@ryuzaki13/react-foundation-lib 2.34.0 → 2.36.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 (27) hide show
  1. package/dist/analytical-table/index.js +3 -3
  2. package/dist/binary/binaryToBlob.d.ts +4 -0
  3. package/dist/binary/binaryToBlob.d.ts.map +1 -1
  4. package/dist/binary/index.d.ts +2 -2
  5. package/dist/binary/index.d.ts.map +1 -1
  6. package/dist/binary/index.js +73 -54
  7. package/dist/binary/index.js.map +1 -1
  8. package/dist/binary/useBinaryFile.d.ts +14 -5
  9. package/dist/binary/useBinaryFile.d.ts.map +1 -1
  10. package/dist/chunks/{formatDate-CNPcfNte.js → formatDate-SviDwHVE.js} +2 -2
  11. package/dist/chunks/{formatDate-CNPcfNte.js.map → formatDate-SviDwHVE.js.map} +1 -1
  12. package/dist/chunks/{formatters-4P9iq3wB.js → formatters-BuMl2-6q.js} +4 -4
  13. package/dist/chunks/{formatters-4P9iq3wB.js.map → formatters-BuMl2-6q.js.map} +1 -1
  14. package/dist/chunks/{scalarTypeClassification-D4YcGxtQ.js → scalarTypeClassification-DT-sUKOU.js} +141 -136
  15. package/dist/chunks/scalarTypeClassification-DT-sUKOU.js.map +1 -0
  16. package/dist/chunks/{validate-Drrm-CCz.js → validate-CNMgSfgA.js} +2 -2
  17. package/dist/chunks/{validate-Drrm-CCz.js.map → validate-CNMgSfgA.js.map} +1 -1
  18. package/dist/error-report/index.js +2 -2
  19. package/dist/excel/index.js +2 -2
  20. package/dist/formatters/date/parseDate.d.ts +1 -1
  21. package/dist/formatters/date/parseDate.d.ts.map +1 -1
  22. package/dist/formatters/index.js +4 -4
  23. package/dist/odata-service/index.js +2 -2
  24. package/package.json +1 -1
  25. package/src/binary/README.mdx +38 -78
  26. package/src/formatters/date/README.mdx +11 -2
  27. package/dist/chunks/scalarTypeClassification-D4YcGxtQ.js.map +0 -1
@@ -4,7 +4,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
4
4
 
5
5
  # Работа с бинарными данными
6
6
 
7
- Модуль `binary` преобразует строковое бинарное содержимое в браузерный `Blob`, определяет предполагаемый MIME-тип документа и предоставляет React hook для типового сценария «base64 → `{ blob, mime }`». Отдельная pure function `getBase64DecodedSize` проверяет стандартный Base64 payload и считает размер без декодирования в browser или server runtime.
7
+ Модуль `binary` преобразует строковое бинарное содержимое в браузерный `Blob`, определяет предполагаемый MIME-тип документа и предоставляет React hook, результат которого показывает, удалось ли определить MIME. Отдельная pure function `getBase64DecodedSize` проверяет стандартный Base64 payload и считает размер без декодирования в browser или server runtime.
8
8
 
9
9
  Основной сценарий:
10
10
 
@@ -278,7 +278,7 @@ const raw = String.fromCharCode(65, 66, 67);
278
278
  | Превратить base64 data URL в `Blob` | `binaryToBlob` |
279
279
  | Превратить raw binary string в `Blob` | `binaryToBlob(..., ..., false)` |
280
280
  | Предположить MIME по имени и данным | `detectMimeType` |
281
- | В React получить `{ blob, mime }` из base64 prop/state | `useBinaryFile` |
281
+ | В React получить `Blob` и результат определения MIME | `useBinaryFile` |
282
282
  | Скачать готовый `Blob` | `downloadFileFromBlob` из `/dom` |
283
283
  | Прочитать пользовательский `File` | `readFile` или `readImageFile` из `/file` |
284
284
  | Использовать известные filename и MIME | Вызвать `detectMimeType`/`binaryToBlob` вручную |
@@ -762,70 +762,41 @@ Fallback PDF является осознанным предметно-незав
762
762
  ### Сигнатура
763
763
 
764
764
  ```ts
765
- function useBinaryFile(bin: string | undefined): {
765
+ type UseBinaryFileResult = {
766
766
  data: {
767
767
  blob: Blob;
768
768
  mime: string;
769
+ isMimeDetected: boolean;
769
770
  } | null;
770
771
  error: string | null;
771
772
  };
772
- ```
773
-
774
- Hook принимает только base64/base64 data URL. Он всегда вызывает:
775
773
 
776
- ```ts
777
- const mime = detectMimeType(undefined, bin);
778
- const blob = binaryToBlob(bin, mime, true);
774
+ function useBinaryFile(bin: string | undefined): UseBinaryFileResult;
779
775
  ```
780
776
 
781
- Filename передать нельзя, raw binary mode использовать нельзя.
777
+ Hook принимает base64 или base64 data URL. Имя файла и MIME можно передать отдельно через `detectMimeType` и `binaryToBlob`.
782
778
 
783
779
  ### Возвращаемое состояние
784
780
 
785
- | Поле | Значение | Смысл |
786
- | ------- | ---------------- | ------------------------------------ |
787
- | `data` | `{ blob, mime }` | Декодирование завершилось успешно |
788
- | `data` | `null` | Нет результата либо произошла ошибка |
789
- | `error` | `string` | Строковое представление ошибки |
790
- | `error` | `null` | Ошибки нет |
791
-
792
- ### Lifecycle
793
-
794
- Преобразование выполняется после commit в React effect:
795
-
796
- 1. первый render возвращает `{ data: null, error: null }`;
797
- 2. после commit effect обрабатывает `bin`;
798
- 3. успех записывает `{ blob, mime }` и очищает ошибку;
799
- 4. ошибка очищает `data` и записывает `String(error)`;
800
- 5. `undefined` или пустая строка очищают оба поля.
801
-
802
- Пример последовательности:
803
-
804
- | `bin` | Состояние после effect |
805
- | --------------------- | ---------------------------------------------------------- |
806
- | `undefined` | `{ data: null, error: null }` |
807
- | `""` | `{ data: null, error: null }` |
808
- | Корректный base64 PDF | `{ data: { blob, mime: "application/pdf" }, error: null }` |
809
- | Некорректный base64 | `{ data: null, error: "Error: ..." }` |
810
- | Строка из пробелов | Ошибка после удаления пробелов |
811
-
812
- У hook нет отдельного `isLoading`/`isProcessing`. На первом render `data: null` и `error: null` может означать как отсутствие входа, так и ещё не выполненный effect.
813
-
814
- ### Смена `bin`
781
+ | Поле | Значение | Смысл |
782
+ | ------- | ------------------------------- | ------------------------------------ |
783
+ | `data` | `{ blob, mime, isMimeDetected }` | Декодирование завершилось успешно |
784
+ | `data` | `null` | Нет результата либо произошла ошибка |
785
+ | `error` | `string` | Строковое представление ошибки |
786
+ | `error` | `null` | Ошибки нет |
815
787
 
816
- При смене одного непустого `bin` на другой предыдущие `data`/`error` могут оставаться видимыми до выполнения следующего effect. Hook не очищает состояние синхронно во время render.
788
+ ### Результат при рендере
817
789
 
818
- Если нельзя кратковременно показать предыдущий документ:
790
+ Хук синхронно декодирует текущий `bin` при рендере. При смене `bin` результат сразу относится к новому входу. Мемоизация позволяет повторно использовать `Blob` при рендере с тем же `bin`.
819
791
 
820
- - разместите hook в компоненте, который remount-ится по стабильному ID документа;
821
- - или выполните преобразование на явной границе загрузки;
822
- - или добавьте внешний state machine с identity результата.
823
-
824
- Не используйте саму большую base64-строку как React `key`. Используйте безопасный стабильный ID документа:
825
-
826
- ```tsx
827
- <BinaryDocument key={document.id} bin={document.content} />
828
- ```
792
+ | `bin` | Результат |
793
+ | ---------------------------------- | ----------------------------------------------------------------------- |
794
+ | `undefined` | `{ data: null, error: null }` |
795
+ | `""` | `{ data: null, error: null }` |
796
+ | Корректный base64 PDF | `data.mime === "application/pdf"`, `data.isMimeDetected === true` |
797
+ | Корректный base64 неизвестного типа | `data.mime === "application/octet-stream"`, `data.isMimeDetected === false` |
798
+ | Некорректный base64 | `{ data: null, error: "Error: ..." }` |
799
+ | Строка из пробелов | Ошибка после удаления пробелов |
829
800
 
830
801
  ### Определение MIME внутри hook
831
802
 
@@ -833,27 +804,22 @@ Hook не знает filename. Приоритет будет таким:
833
804
 
834
805
  1. MIME из data URL;
835
806
  2. сигнатура;
836
- 3. fallback `application/pdf`.
807
+ 3. fallback `application/octet-stream`.
837
808
 
838
- Обычный base64 текста без data URL и известной сигнатуры станет `Blob` с `application/pdf`:
809
+ Проверяйте `data.isMimeDetected` перед выбором просмотрщика. Значение `true` означает, что MIME взят из data URL или определён по сигнатуре. Значение `false` означает, что hook подставил нейтральный MIME и сохранил декодированные байты.
839
810
 
840
811
  ```tsx
841
812
  const { data } = useBinaryFile("SGVsbG8=");
842
813
 
843
- // После effect:
844
- // data?.mime === "application/pdf"
814
+ // data?.mime === "application/octet-stream"
815
+ // data?.isMimeDetected === false
845
816
  ```
846
817
 
847
818
  Если известны имя или MIME, вызывайте `detectMimeType` и `binaryToBlob` вручную.
848
819
 
849
820
  ### Ошибки и logging
850
821
 
851
- При ошибке hook:
852
-
853
- 1. вызывает внутренний `logError(error)`;
854
- 2. `logError` пишет ошибку в `console.error`;
855
- 3. возвращает `error: String(error)`;
856
- 4. очищает `data`.
822
+ При ошибке хук возвращает `{ data: null, error: String(error) }` во время рендера. После commit эффект передаёт исходную ошибку в `logError`, который пишет её в `console.error`.
857
823
 
858
824
  Для обычного `Error` строка включает имя:
859
825
 
@@ -879,12 +845,12 @@ export function BinaryDocument(props: BinaryDocumentProps) {
879
845
  return <p role="alert">Не удалось подготовить документ</p>;
880
846
  }
881
847
 
882
- if (!props.bin) {
848
+ if (!data) {
883
849
  return <p>Документ не передан</p>;
884
850
  }
885
851
 
886
- if (!data) {
887
- return <p>Подготовка документа…</p>;
852
+ if (!data.isMimeDetected) {
853
+ return <p>Формат файла не распознан</p>;
888
854
  }
889
855
 
890
856
  return <DocumentViewer blob={data.blob} mime={data.mime} />;
@@ -936,7 +902,7 @@ Effect синхронизирует React с внешним browser API и си
936
902
  Не используйте `useBinaryFile`, если:
937
903
 
938
904
  - код выполняется вне React;
939
- - MIME уже известен и не равен PDF fallback;
905
+ - MIME передаётся отдельно от base64;
940
906
  - нужно учитывать filename;
941
907
  - данные являются raw binary string;
942
908
  - результат нужен немедленно в event handler;
@@ -1148,19 +1114,13 @@ const mime = detectMimeType(fileName, payload);
1148
1114
  const blob = binaryToBlob(payload, mime);
1149
1115
  ```
1150
1116
 
1151
- ### Hook определил текст как PDF
1152
-
1153
- Причина: `useBinaryFile` не получает filename, сигнатура текста неизвестна, поэтому применяется PDF fallback.
1154
-
1155
- Решения:
1117
+ ### Hook вернул `isMimeDetected: false`
1156
1118
 
1157
- - передать data URL с MIME;
1158
- - вызвать функции вручную с известным MIME;
1159
- - не использовать hook для этого контракта.
1119
+ Байты успешно декодированы. Их можно скачать как `application/octet-stream`. Если тип известен из метаданных, передайте его в data URL или вызовите `binaryToBlob` с этим MIME.
1160
1120
 
1161
1121
  ### MIME не совпал с содержимым
1162
1122
 
1163
- Проверьте приоритет:
1123
+ Проверьте порядок определения MIME в `detectMimeType`:
1164
1124
 
1165
1125
  1. filename;
1166
1126
  2. data URL;
@@ -1185,7 +1145,7 @@ data:<mime>,<percent-encoded-payload>
1185
1145
 
1186
1146
  ### Ошибка появляется в `console.error`
1187
1147
 
1188
- Это текущее поведение `useBinaryFile`: hook логирует пойманную ошибку перед записью `error` state. Для ручного `binaryToBlob` logging не выполняется.
1148
+ `useBinaryFile` логирует пойманную ошибку после commit. При прямом вызове `binaryToBlob` за журналирование отвечает вызывающий код.
1189
1149
 
1190
1150
  ### Object URL перестал работать
1191
1151
 
@@ -1260,7 +1220,7 @@ Base64 обычно примерно на треть больше исходно
1260
1220
 
1261
1221
  ### `detectMimeType` декодирует только начало
1262
1222
 
1263
- Signature detection декодирует ограниченное начало base64, поэтому дешевле полного декодирования. При этом распознавание data URL выполняется регулярным выражением над входной строкой и может просканировать весь payload. Последующий `binaryToBlob` в любом случае обрабатывает полный payload.
1223
+ Для поиска сигнатуры декодируются первые 128 непробельных символов Base64. Распознавание data URL выполняется регулярным выражением над входной строкой и может просканировать весь payload. Последующий `binaryToBlob` обрабатывает полный payload.
1264
1224
 
1265
1225
  ### Рекомендации
1266
1226
 
@@ -1344,8 +1304,8 @@ import { binaryToBlob, detectMimeType, useBinaryFile } from "@ryuzaki13/react-fo
1344
1304
  | `binaryToBlob` MIME | `application/octet-stream` |
1345
1305
  | `binaryToBlob` input mode | base64 |
1346
1306
  | `detectMimeType` fallback | `application/pdf` |
1347
- | `useBinaryFile` initial `data` | `null` |
1348
- | `useBinaryFile` initial `error` | `null` |
1307
+ | `useBinaryFile` fallback | `application/octet-stream` |
1308
+ | `useBinaryFile` без входа | `{ data: null, error: null }` |
1349
1309
  | `useBinaryFile` raw binary support | Нет |
1350
1310
  | Автоматическое создание object URL | Нет |
1351
1311
 
@@ -32,7 +32,7 @@ import {
32
32
 
33
33
  ### Floating: сохранить видимые компоненты
34
34
 
35
- Обычные `parseDateValue` и `parseDate` намеренно не пересчитывают ISO/OData timezone в timezone компьютера пользователя.
35
+ Обычные `parseDateValue` и `parseDate` намеренно не пересчитывают явный timezone в timezone компьютера пользователя. Это относится к ISO/OData и датам с точками и временем.
36
36
 
37
37
  ```ts
38
38
  const date = parseDate("2026-03-03T18:03:50+05:00");
@@ -108,11 +108,20 @@ formatDateAsDate("not-a-date", { fallback: "—" }); // "—"
108
108
  | ABAP date | `20260303` | `abap-compact` |
109
109
  | ABAP timestamp | `20260303180350` | `abap-timestamp` |
110
110
  | Dotted | `03.03.2026` | `abap-dotted` |
111
+ | Дата и время | `09.11.2024T03:00:00+03:00` | `abap-dotted` |
111
112
  | Slash | `03/03/2026` | `slash-date` |
112
113
  | ISO local | `2026-03-03T18:03:50` | `iso-local` |
113
114
  | ISO zoned | `2026-03-03T18:03:50Z` | `iso-zoned` |
114
115
  | ISO duration | `PT02H30M` | `iso-duration` |
115
116
 
117
+ Для `DD.MM.YYYY` время можно отделять буквой `T` или пробелом. Поддерживаются те же временные суффиксы, что и у ISO: необязательные минуты и секунды, дробные секунды, `Z` или смещение `±HH:mm`/`±HHmm`.
118
+
119
+ ```ts
120
+ formatDateAsDateTime("09.11.2024T03:00:00+03:00"); // "09.11.2024 03:00"
121
+ parseDate("09.11.2024T03:00:00+03:00")?.getHours(); // 3
122
+ parseDateTZ("09.11.2024T03:00:00+03:00")?.toISOString(); // "2024-11-09T00:00:00.000Z"
123
+ ```
124
+
116
125
  Slash-формат интерпретируется как `MM/DD/YYYY`, а не `DD/MM/YYYY`:
117
126
 
118
127
  ```ts
@@ -151,7 +160,7 @@ if (parsed?.kind === "duration") {
151
160
 
152
161
  ### `parseDateValueTZ(value)`
153
162
 
154
- Возвращает такую же структуру, но timestamp, ISO zoned и OData ticks интерпретируются как instant. Форматы без timezone всё равно остаются локальными календарными компонентами.
163
+ Возвращает такую же структуру, но timestamp, ISO zoned, даты с точками и явным смещением, а также OData ticks интерпретируются как instant. Форматы без timezone всё равно остаются локальными календарными компонентами.
155
164
 
156
165
  ### `parseDate(value)` и `parseDateTZ(value)`
157
166
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"scalarTypeClassification-D4YcGxtQ.js","names":[],"sources":["../../src/formatters/strings/spaceCharacterConstants.ts","../../src/formatters/number/parseNumber.ts","../../src/formatters/date/calendarDateConstants.ts","../../src/formatters/date/dateFormatConstants.ts","../../src/formatters/date/dateValueConstants.ts","../../src/formatters/date/datePatternConstants.ts","../../src/formatters/date/datePresetNameConstants.ts","../../src/formatters/date/pattern.ts","../../src/formatters/date/presets.ts","../../src/formatters/date/parseDate.ts","../../src/metadata/scalarTypeClassification.ts"],"sourcesContent":["/** Коды пробельных разделителей общие для очистки текста и SAP-подобного числового ввода. */\nexport const SPACE_CODE = 32;\nexport const NO_BREAK_SPACE_CODE = 160;\nexport const NARROW_NO_BREAK_SPACE_CODE = 8239;\n","import { SPACE_CODE, NO_BREAK_SPACE_CODE, NARROW_NO_BREAK_SPACE_CODE } from \"../strings/spaceCharacterConstants\";\n\nconst APOSTROPHE_GROUP_SEPARATOR_CODE = 39;\n\n/**\n * SAP-like парсер: пробелы/NBSP как группировка, ',' как десятичный.\n * Возвращает только finite number или undefined.\n */\nexport function toFiniteNumber(v: unknown): number | undefined {\n\tif (typeof v === \"number\") return Number.isFinite(v) ? v : undefined;\n\tif (typeof v !== \"string\") return undefined;\n\n\tconst trimmed = v.trim();\n\tif (!trimmed) return undefined;\n\n\tconst parsed = Number(trimmed);\n\tif (Number.isFinite(parsed)) return parsed;\n\n\t// SAP-like: убираем пробелы/NBSP/NNBSP, поддерживаем ',' как decimal\n\n\tlet s = \"\";\n\tfor (let i = 0; i < trimmed.length; i++) {\n\t\tconst c = trimmed.charCodeAt(i);\n\t\tif (\n\t\t\tc === SPACE_CODE ||\n\t\t\tc === NO_BREAK_SPACE_CODE ||\n\t\t\tc === NARROW_NO_BREAK_SPACE_CODE ||\n\t\t\tc === APOSTROPHE_GROUP_SEPARATOR_CODE /*'*/\n\t\t)\n\t\t\tcontinue;\n\t\ts += trimmed[i];\n\t}\n\n\tconst hasComma = s.indexOf(\",\") !== -1;\n\tconst hasDot = s.indexOf(\".\") !== -1;\n\n\tif (hasComma && hasDot) {\n\t\ts = s.replace(/,/g, \"\"); // 1,234.56 -> 1234.56\n\t} else if (hasComma) {\n\t\ts = s.replace(/,/g, \".\"); // 1234,56 -> 1234.56\n\t}\n\n\tconst n = Number(s);\n\treturn Number.isFinite(n) ? n : undefined;\n}\n\nexport function parseNumber(v: unknown): number {\n\treturn toFiniteNumber(v) ?? 0;\n}\n\nexport function isPositiveValue(value: unknown): boolean {\n\tconst normalizedValue = toFiniteNumber(value);\n\tif (normalizedValue) {\n\t\treturn normalizedValue > 0;\n\t}\n\n\treturn false;\n}\n\n/**\n * Читает положительное целое число из неизвестного значения.\n */\nexport function toPositiveInteger(value: unknown): number | undefined {\n\tconst normalizedValue = toFiniteNumber(value);\n\tif (normalizedValue === undefined || !Number.isInteger(normalizedValue) || normalizedValue <= 0) {\n\t\treturn undefined;\n\t}\n\n\treturn normalizedValue;\n}\n","/** Календарные границы и единицы времени общие для проверок компонентов и вычисления длительностей. */\nexport const CALENDAR_DAYS_PER_WEEK = 7;\nexport const CALENDAR_MONTHS_PER_YEAR = 12;\nexport const CALENDAR_LAST_HOUR = 23;\nexport const CALENDAR_LAST_MINUTE = 59;\nexport const CALENDAR_LAST_SECOND = 59;\nexport const SECONDS_PER_MINUTE = 60;\nexport const SECONDS_PER_HOUR = 3_600;\nexport const MS_IN_SECOND = 1_000;\nexport const MS_IN_MINUTE = 60_000;\nexport const MS_IN_HOUR = 3_600_000;\nexport const MS_IN_DAY = 86_400_000;\n","/** Точность и детализация форматирования сохраняют единые значения для пресетов, проверок и типов. */\nexport const DATE_FORMAT_PRECISION_DAY = \"day\";\nexport const DATE_FORMAT_PRECISION_MONTH = \"month\";\nexport const DATE_FORMAT_PRECISION_YEAR = \"year\";\nexport const DATE_FORMAT_STYLE_SHORT = \"short\";\nexport const DATE_FORMAT_STYLE_MEDIUM = \"medium\";\nexport const DATE_FORMAT_STYLE_LONG = \"long\";\nexport const INTL_DATE_PART_TWO_DIGIT = \"2-digit\";\nexport const INTL_DATE_PART_NUMERIC = \"numeric\";\nexport const INTL_DATE_HOUR_CYCLE_23 = \"h23\";\nexport const DEFAULT_DATE_LOCALE = \"ru-RU\";\n\n/** Текстовый месяц и части formatToParts имеют собственную семантику относительно style-пресетов. */\nexport const INTL_DATE_MONTH_SHORT = \"short\";\nexport const INTL_DATE_MONTH_LONG = \"long\";\nexport const INTL_DATE_PART_MONTH = \"month\";\nexport const INTL_DATE_PART_YEAR = \"year\";\n","/** Виды результата и распознанные источники связывают парсер даты с литеральными контрактами и форматтерами. */\nexport const PARSED_DATE_KIND_DATE_TIME = \"date-time\";\nexport const PARSED_DATE_KIND_DURATION = \"duration\";\nexport const DATE_INPUT_SOURCE_DATE_OBJECT = \"date-object\";\nexport const DATE_INPUT_SOURCE_TIMESTAMP = \"timestamp\";\nexport const DATE_INPUT_SOURCE_ODATA_TICKS = \"odata-ticks\";\nexport const DATE_INPUT_SOURCE_ODATA_LITERAL = \"odata-literal\";\nexport const DATE_INPUT_SOURCE_ABAP_COMPACT = \"abap-compact\";\nexport const DATE_INPUT_SOURCE_ABAP_TIMESTAMP = \"abap-timestamp\";\nexport const DATE_INPUT_SOURCE_ABAP_DOTTED = \"abap-dotted\";\nexport const DATE_INPUT_SOURCE_SLASH_DATE = \"slash-date\";\nexport const DATE_INPUT_SOURCE_ISO_LOCAL = \"iso-local\";\nexport const DATE_INPUT_SOURCE_ISO_ZONED = \"iso-zoned\";\nexport const DATE_INPUT_SOURCE_ISO_DURATION = \"iso-duration\";\n","/** Токены и повторяемые полные шаблоны связывают распознавание ввода с компиляцией форматтеров. */\nexport const DATE_PATTERN_TOKEN_YEAR = \"yyyy\";\nexport const DATE_PATTERN_TOKEN_SHORT_YEAR = \"yy\";\nexport const DATE_PATTERN_TOKEN_MONTH = \"MM\";\nexport const DATE_PATTERN_TOKEN_DAY = \"dd\";\nexport const DATE_PATTERN_TOKEN_HOURS = \"HH\";\nexport const DATE_PATTERN_TOKEN_MINUTES = \"mm\";\nexport const DATE_PATTERN_TOKEN_SECONDS = \"ss\";\nexport const DATE_PATTERN_DAY_MONTH_YEAR_DOTTED = \"dd.MM.yyyy\";\nexport const DATE_PATTERN_TIME_MINUTES = \"HH:mm\";\nexport const DATE_PATTERN_TIME_SECONDS = \"HH:mm:ss\";\nexport const DATE_PATTERN_ABAP_DATE = \"yyyyMMdd\";\nexport const DATE_PATTERN_ABAP_DATE_TIME = \"yyyyMMddHHmmss\";\nexport const DATE_PATTERN_ISO_DATE = \"yyyy-MM-dd\";\nexport const DATE_PATTERN_ISO_DATE_TIME = \"yyyy-MM-ddTHH:mm:ss\";\n","/** Имена встроенных пресетов разделяют внутренние обращения и сохраняемый публичный объект имён. */\nexport const DATE_PRESET_NAME_DATE = \"date\";\nexport const DATE_PRESET_NAME_DATE_SHORT = \"date-short\";\nexport const DATE_PRESET_NAME_DATE_MEDIUM = \"date-medium\";\nexport const DATE_PRESET_NAME_DATE_LONG = \"date-long\";\nexport const DATE_PRESET_NAME_MONTH_SHORT = \"month-short\";\nexport const DATE_PRESET_NAME_MONTH_MEDIUM = \"month-medium\";\nexport const DATE_PRESET_NAME_MONTH_LONG = \"month-long\";\nexport const DATE_PRESET_NAME_MONTH_YEAR_MEDIUM = \"month-year-medium\";\nexport const DATE_PRESET_NAME_MONTH_YEAR_LONG = \"month-year-long\";\nexport const DATE_PRESET_NAME_DATETIME = \"datetime\";\nexport const DATE_PRESET_NAME_DATETIME_SECONDS = \"datetime-seconds\";\nexport const DATE_PRESET_NAME_DATETIME_SHORT = \"datetime-short\";\nexport const DATE_PRESET_NAME_DATETIME_MEDIUM = \"datetime-medium\";\nexport const DATE_PRESET_NAME_DATETIME_LONG = \"datetime-long\";\nexport const DATE_PRESET_NAME_TIME = \"time\";\nexport const DATE_PRESET_NAME_TIME_SECONDS = \"time-seconds\";\nexport const DATE_PRESET_NAME_TIME_SHORT = \"time-short\";\nexport const DATE_PRESET_NAME_TIME_MEDIUM = \"time-medium\";\nexport const DATE_PRESET_NAME_TIME_LONG = \"time-long\";\nexport const DATE_PRESET_NAME_ODATA_DATE = \"odata-date\";\nexport const DATE_PRESET_NAME_ODATA_DATETIME = \"odata-datetime\";\nexport const DATE_PRESET_NAME_ABAP_DATETIME = \"abap-datetime\";\nexport const DATE_PRESET_NAME_ABAP_DATE = \"abap-date\";\nexport const DATE_PRESET_NAME_ABAP_MONTH = \"abap-month\";\nexport const DATE_PRESET_NAME_ABAP_YEAR = \"abap-year\";\n","import { DATE_FORMAT_PRECISION_DAY } from \"./dateFormatConstants\";\nimport {\n\tDATE_PATTERN_TOKEN_DAY,\n\tDATE_PATTERN_TOKEN_MONTH,\n\tDATE_PATTERN_TOKEN_YEAR,\n\tDATE_PATTERN_TOKEN_SHORT_YEAR,\n\tDATE_PATTERN_TOKEN_HOURS,\n\tDATE_PATTERN_TOKEN_MINUTES,\n\tDATE_PATTERN_TOKEN_SECONDS\n} from \"./datePatternConstants\";\n\nimport type { DateFormatPrecision } from \"./types\";\n\n/**\n * Токены календарной даты, поддерживаемые ручными шаблонами форматирования.\n */\nexport const DATE_PATTERN_DATE_TOKENS = Object.freeze([\n\tDATE_PATTERN_TOKEN_DAY,\n\tDATE_PATTERN_TOKEN_MONTH,\n\tDATE_PATTERN_TOKEN_YEAR,\n\tDATE_PATTERN_TOKEN_SHORT_YEAR\n] as const);\n\n/**\n * Токены времени, поддерживаемые ручными шаблонами форматирования.\n */\nexport const DATE_PATTERN_TIME_TOKENS = Object.freeze([\n\tDATE_PATTERN_TOKEN_HOURS,\n\tDATE_PATTERN_TOKEN_MINUTES,\n\tDATE_PATTERN_TOKEN_SECONDS\n] as const);\n\n/**\n * Все токены ручного шаблона даты/времени.\n */\nexport const DATE_PATTERN_TOKENS = Object.freeze([...DATE_PATTERN_DATE_TOKENS, ...DATE_PATTERN_TIME_TOKENS] as const);\n\n/**\n * Регулярное выражение для поиска токенов ручного шаблона.\n */\nexport const DATE_PATTERN_TOKEN_RE = /(yyyy|yy|MM|dd|HH|mm|ss)/g;\n\nconst DATE_PATTERN_TOKEN_SET = new Set<string>(DATE_PATTERN_TOKENS);\nconst DATE_PATTERN_PRECISION_TOKENS: Readonly<Record<DateFormatPrecision, ReadonlySet<string>>> = Object.freeze({\n\tday: new Set(DATE_PATTERN_TOKENS),\n\tmonth: new Set([DATE_PATTERN_TOKEN_MONTH, DATE_PATTERN_TOKEN_YEAR, DATE_PATTERN_TOKEN_SHORT_YEAR]),\n\tyear: new Set([DATE_PATTERN_TOKEN_YEAR, DATE_PATTERN_TOKEN_SHORT_YEAR])\n});\n\n/**\n * Проверяет, что сегмент шаблона является поддерживаемым токеном даты/времени.\n */\nexport function isDatePatternToken(value: string): boolean {\n\treturn DATE_PATTERN_TOKEN_SET.has(value);\n}\n\n/**\n * Проверяет, что шаблон содержит хотя бы один токен из списка.\n */\nexport function containsDatePatternToken(pattern: string, tokens: readonly string[]): boolean {\n\treturn tokens.some((token) => pattern.includes(token));\n}\n\n/**\n * Проверяет, похожа ли строка на ручной шаблон даты.\n */\nexport function hasDatePatternTokens(pattern: string): boolean {\n\tDATE_PATTERN_TOKEN_RE.lastIndex = 0;\n\treturn DATE_PATTERN_TOKEN_RE.test(pattern);\n}\n\n/**\n * Возвращает токены, допустимые для выбранной точности календарной даты.\n */\nexport function getDatePatternPrecisionTokens(precision: DateFormatPrecision): ReadonlySet<string> {\n\treturn DATE_PATTERN_PRECISION_TOKENS[precision];\n}\n\n/**\n * Удаляет из ручного шаблона части даты, которые ниже выбранной точности.\n */\nexport function resolveDatePatternPrecision(pattern: string, precision: DateFormatPrecision): string {\n\tif (precision === DATE_FORMAT_PRECISION_DAY) return pattern;\n\n\tconst allowedTokens = getDatePatternPrecisionTokens(precision);\n\tconst resultSegments: string[] = [];\n\tlet pendingLiteral = \"\";\n\tlet hasKeptToken = false;\n\tlet keptTokenCount = 0;\n\tlet cursor = 0;\n\tlet match: RegExpExecArray | null;\n\n\tDATE_PATTERN_TOKEN_RE.lastIndex = 0;\n\twhile ((match = DATE_PATTERN_TOKEN_RE.exec(pattern))) {\n\t\tconst literal = pattern.slice(cursor, match.index);\n\t\tconst token = match[0];\n\n\t\tif (hasKeptToken) pendingLiteral += literal;\n\n\t\tif (allowedTokens.has(token)) {\n\t\t\tif (hasKeptToken) resultSegments.push(pendingLiteral);\n\t\t\tresultSegments.push(token);\n\t\t\tpendingLiteral = \"\";\n\t\t\thasKeptToken = true;\n\t\t\tkeptTokenCount += 1;\n\t\t}\n\n\t\tcursor = match.index + token.length;\n\t}\n\n\tif (keptTokenCount === 0) return pattern;\n\treturn resultSegments.join(\"\");\n}\n","import { MS_IN_SECOND, SECONDS_PER_HOUR, SECONDS_PER_MINUTE } from \"./calendarDateConstants\";\nimport {\n\tDEFAULT_DATE_LOCALE,\n\tINTL_DATE_PART_TWO_DIGIT,\n\tINTL_DATE_PART_NUMERIC,\n\tINTL_DATE_HOUR_CYCLE_23,\n\tDATE_FORMAT_STYLE_SHORT,\n\tDATE_FORMAT_STYLE_MEDIUM,\n\tDATE_FORMAT_STYLE_LONG,\n\tDATE_FORMAT_PRECISION_DAY,\n\tDATE_FORMAT_PRECISION_MONTH,\n\tDATE_FORMAT_PRECISION_YEAR,\n\tINTL_DATE_MONTH_SHORT,\n\tINTL_DATE_MONTH_LONG,\n\tINTL_DATE_PART_YEAR,\n\tINTL_DATE_PART_MONTH\n} from \"./dateFormatConstants\";\nimport {\n\tDATE_PATTERN_TIME_MINUTES,\n\tDATE_PATTERN_TIME_SECONDS,\n\tDATE_PATTERN_ISO_DATE,\n\tDATE_PATTERN_ISO_DATE_TIME,\n\tDATE_PATTERN_ABAP_DATE_TIME,\n\tDATE_PATTERN_ABAP_DATE,\n\tDATE_PATTERN_TOKEN_YEAR,\n\tDATE_PATTERN_TOKEN_SHORT_YEAR,\n\tDATE_PATTERN_TOKEN_MONTH,\n\tDATE_PATTERN_TOKEN_DAY,\n\tDATE_PATTERN_TOKEN_HOURS,\n\tDATE_PATTERN_TOKEN_MINUTES,\n\tDATE_PATTERN_TOKEN_SECONDS\n} from \"./datePatternConstants\";\nimport {\n\tDATE_PRESET_NAME_DATE,\n\tDATE_PRESET_NAME_DATE_SHORT,\n\tDATE_PRESET_NAME_DATE_MEDIUM,\n\tDATE_PRESET_NAME_DATE_LONG,\n\tDATE_PRESET_NAME_MONTH_YEAR_MEDIUM,\n\tDATE_PRESET_NAME_MONTH_YEAR_LONG,\n\tDATE_PRESET_NAME_DATETIME,\n\tDATE_PRESET_NAME_DATETIME_SECONDS,\n\tDATE_PRESET_NAME_TIME,\n\tDATE_PRESET_NAME_TIME_SECONDS,\n\tDATE_PRESET_NAME_ODATA_DATE,\n\tDATE_PRESET_NAME_ODATA_DATETIME,\n\tDATE_PRESET_NAME_ABAP_DATETIME,\n\tDATE_PRESET_NAME_ABAP_DATE,\n\tDATE_PRESET_NAME_ABAP_MONTH,\n\tDATE_PRESET_NAME_ABAP_YEAR,\n\tDATE_PRESET_NAME_MONTH_SHORT,\n\tDATE_PRESET_NAME_MONTH_MEDIUM,\n\tDATE_PRESET_NAME_MONTH_LONG,\n\tDATE_PRESET_NAME_DATETIME_SHORT,\n\tDATE_PRESET_NAME_DATETIME_MEDIUM,\n\tDATE_PRESET_NAME_DATETIME_LONG,\n\tDATE_PRESET_NAME_TIME_SHORT,\n\tDATE_PRESET_NAME_TIME_MEDIUM,\n\tDATE_PRESET_NAME_TIME_LONG\n} from \"./datePresetNameConstants\";\nimport {\n\tcontainsDatePatternToken,\n\tDATE_PATTERN_DATE_TOKENS,\n\tDATE_PATTERN_TIME_TOKENS,\n\tDATE_PATTERN_TOKEN_RE,\n\tisDatePatternToken,\n\tresolveDatePatternPrecision\n} from \"./pattern\";\n\nimport type { DateFormatPrecision, DateFormatPreset, DateFormatPresetConfig, DateFormatStyle } from \"./types\";\n\n/**\n * Функция, которая форматирует уже подготовленную календарную дату.\n */\nexport type CompiledDateFormatter = (date: Date, precision?: DateFormatPrecision) => string;\n\n/**\n * Внутреннее представление предустановки с заранее созданными форматтерами.\n */\nexport interface CompiledDateFormatPreset extends DateFormatPreset {\n\tformatDateTime: CompiledDateFormatter;\n\tformatDuration?: (durationMs: number, fallback: string) => string;\n}\n\n/**\n * Уровни детализации, для которых создаются встроенные style-пресеты.\n */\nconst FORMAT_STYLES = Object.freeze([DATE_FORMAT_STYLE_SHORT, DATE_FORMAT_STYLE_MEDIUM, DATE_FORMAT_STYLE_LONG] as const);\nconst FORMAT_PRECISIONS = Object.freeze([DATE_FORMAT_PRECISION_DAY, DATE_FORMAT_PRECISION_MONTH, DATE_FORMAT_PRECISION_YEAR] as const);\n\n/**\n * Значения по умолчанию для предустановок форматирования дат.\n */\nexport const DATE_FORMAT_DEFAULTS: Omit<DateFormatPreset, \"name\" | \"intlOptions\"> & { intlOptions: Intl.DateTimeFormatOptions } = {\n\tlocale: DEFAULT_DATE_LOCALE,\n\tintlOptions: { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC },\n\tinvalidFallback: \"\"\n};\n\n/**\n * Имена встроенных предустановок.\n */\nexport const DEFAULT_DATE_PRESET_NAMES = Object.freeze({\n\tdate: DATE_PRESET_NAME_DATE,\n\tdateShort: DATE_PRESET_NAME_DATE_SHORT,\n\tdateMedium: DATE_PRESET_NAME_DATE_MEDIUM,\n\tdateLong: DATE_PRESET_NAME_DATE_LONG,\n\tmonthShort: DATE_PRESET_NAME_MONTH_SHORT,\n\tmonthMedium: DATE_PRESET_NAME_MONTH_MEDIUM,\n\tmonthLong: DATE_PRESET_NAME_MONTH_LONG,\n\tmonthYearMedium: DATE_PRESET_NAME_MONTH_YEAR_MEDIUM,\n\tmonthYearLong: DATE_PRESET_NAME_MONTH_YEAR_LONG,\n\tdatetime: DATE_PRESET_NAME_DATETIME,\n\tdatetimeSeconds: DATE_PRESET_NAME_DATETIME_SECONDS,\n\tdatetimeShort: DATE_PRESET_NAME_DATETIME_SHORT,\n\tdatetimeMedium: DATE_PRESET_NAME_DATETIME_MEDIUM,\n\tdatetimeLong: DATE_PRESET_NAME_DATETIME_LONG,\n\ttime: DATE_PRESET_NAME_TIME,\n\ttimeSeconds: DATE_PRESET_NAME_TIME_SECONDS,\n\ttimeShort: DATE_PRESET_NAME_TIME_SHORT,\n\ttimeMedium: DATE_PRESET_NAME_TIME_MEDIUM,\n\ttimeLong: DATE_PRESET_NAME_TIME_LONG,\n\todataDate: DATE_PRESET_NAME_ODATA_DATE,\n\todataDatetime: DATE_PRESET_NAME_ODATA_DATETIME,\n\tabapDatetime: DATE_PRESET_NAME_ABAP_DATETIME,\n\tabapDate: DATE_PRESET_NAME_ABAP_DATE,\n\tabapMonth: DATE_PRESET_NAME_ABAP_MONTH,\n\tabapYear: DATE_PRESET_NAME_ABAP_YEAR\n});\n\n/**\n * Алиасы style-форматов даты к именам встроенных date-пресетов.\n */\nexport const DATE_FORMAT_STYLE_PRESET_NAMES: Readonly<Record<DateFormatStyle, string>> = Object.freeze({\n\tshort: DATE_PRESET_NAME_DATE_SHORT,\n\tmedium: DATE_PRESET_NAME_DATE_MEDIUM,\n\tlong: DATE_PRESET_NAME_DATE_LONG\n});\n\nconst patternPresetCache = new Map<string, DateFormatPreset>();\n\n/**\n * Встроенные предустановки форматирования дат.\n */\nconst BUILTIN_PRESETS: DateFormatPresetConfig[] = [\n\t{\n\t\tname: DATE_PRESET_NAME_DATE,\n\t\tintlOptions: { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC }\n\t},\n\t{\n\t\tname: DATE_PRESET_NAME_DATETIME,\n\t\tintlDateOptions: { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC },\n\t\tintlTimeOptions: { hour: INTL_DATE_PART_TWO_DIGIT, minute: INTL_DATE_PART_TWO_DIGIT, hourCycle: INTL_DATE_HOUR_CYCLE_23 },\n\t\tintlJoiner: \" \"\n\t},\n\t{\n\t\tname: DATE_PRESET_NAME_DATETIME_SECONDS,\n\t\tintlDateOptions: { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC },\n\t\tintlTimeOptions: {\n\t\t\thour: INTL_DATE_PART_TWO_DIGIT,\n\t\t\tminute: INTL_DATE_PART_TWO_DIGIT,\n\t\t\tsecond: INTL_DATE_PART_TWO_DIGIT,\n\t\t\thourCycle: INTL_DATE_HOUR_CYCLE_23\n\t\t},\n\t\tintlJoiner: \" \"\n\t},\n\t{\n\t\tname: DATE_PRESET_NAME_TIME,\n\t\tintlOptions: { hour: INTL_DATE_PART_TWO_DIGIT, minute: INTL_DATE_PART_TWO_DIGIT, hourCycle: INTL_DATE_HOUR_CYCLE_23 },\n\t\tdurationPattern: DATE_PATTERN_TIME_MINUTES\n\t},\n\t{\n\t\tname: DATE_PRESET_NAME_TIME_SECONDS,\n\t\tintlOptions: {\n\t\t\thour: INTL_DATE_PART_TWO_DIGIT,\n\t\t\tminute: INTL_DATE_PART_TWO_DIGIT,\n\t\t\tsecond: INTL_DATE_PART_TWO_DIGIT,\n\t\t\thourCycle: INTL_DATE_HOUR_CYCLE_23\n\t\t},\n\t\tdurationPattern: DATE_PATTERN_TIME_SECONDS\n\t},\n\t...FORMAT_STYLES.map((style) => ({\n\t\tname: `date-${style}`,\n\t\tintlOptions: getDateStyleIntlOptions(style)\n\t})),\n\t...FORMAT_STYLES.map((style) => ({\n\t\tname: `month-${style}`,\n\t\tintlOptions: getMonthStyleIntlOptions(style)\n\t})),\n\t{\n\t\tname: DATE_PRESET_NAME_MONTH_YEAR_MEDIUM,\n\t\tintlOptions: { month: INTL_DATE_MONTH_SHORT, year: INTL_DATE_PART_NUMERIC }\n\t},\n\t{\n\t\tname: DATE_PRESET_NAME_MONTH_YEAR_LONG,\n\t\tintlOptions: { month: INTL_DATE_MONTH_LONG, year: INTL_DATE_PART_NUMERIC }\n\t},\n\t...FORMAT_STYLES.map((style) => ({\n\t\tname: `time-${style}`,\n\t\tintlOptions: getTimeStyleIntlOptions(style),\n\t\tdurationPattern: style === DATE_FORMAT_STYLE_SHORT ? DATE_PATTERN_TIME_MINUTES : DATE_PATTERN_TIME_SECONDS\n\t})),\n\t...FORMAT_STYLES.map((style) => ({\n\t\tname: `datetime-${style}`,\n\t\tintlDateOptions: getDateStyleIntlOptions(style),\n\t\tintlTimeOptions: getTimeStyleIntlOptions(style),\n\t\tintlJoiner: \", \"\n\t})),\n\t{ name: DATE_PRESET_NAME_ODATA_DATE, pattern: DATE_PATTERN_ISO_DATE },\n\t{ name: DATE_PRESET_NAME_ODATA_DATETIME, pattern: DATE_PATTERN_ISO_DATE_TIME },\n\t{ name: DATE_PRESET_NAME_ABAP_DATETIME, pattern: DATE_PATTERN_ABAP_DATE_TIME },\n\t{ name: DATE_PRESET_NAME_ABAP_DATE, pattern: DATE_PATTERN_ABAP_DATE },\n\t{ name: DATE_PRESET_NAME_ABAP_MONTH, pattern: \"yyyyMM\" },\n\t{ name: DATE_PRESET_NAME_ABAP_YEAR, pattern: DATE_PATTERN_TOKEN_YEAR }\n];\n\n/**\n * Текстовая детализация месяца для встроенных пресетов `месяц + год`.\n */\nconst MONTH_YEAR_PRESET_STYLES: ReadonlyMap<string, typeof INTL_DATE_MONTH_SHORT | typeof INTL_DATE_MONTH_LONG> = new Map([\n\t[DATE_PRESET_NAME_MONTH_YEAR_MEDIUM, INTL_DATE_MONTH_SHORT],\n\t[DATE_PRESET_NAME_MONTH_YEAR_LONG, INTL_DATE_MONTH_LONG]\n]);\n\n/**\n * Реестр предустановок форматирования.\n */\nconst registry = new Map<string, CompiledDateFormatPreset>();\n\n/**\n * Дополняет числовую часть даты ведущим нулём.\n */\nfunction padDatePart(value: number, size = 2): string {\n\treturn String(value).padStart(size, \"0\");\n}\n\n/**\n * Возвращает настройки Intl для dateStyle-подобного формата без timezone-семантики.\n */\nfunction getDateStyleIntlOptions(\n\tstyle: DateFormatStyle,\n\tprecision: DateFormatPrecision = DATE_FORMAT_PRECISION_DAY\n): Intl.DateTimeFormatOptions {\n\tif (precision === DATE_FORMAT_PRECISION_YEAR) return { year: INTL_DATE_PART_NUMERIC };\n\n\tif (precision === DATE_FORMAT_PRECISION_MONTH) {\n\t\tif (style === DATE_FORMAT_STYLE_SHORT) return { month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC };\n\t\tif (style === DATE_FORMAT_STYLE_MEDIUM) return { month: INTL_DATE_MONTH_SHORT, year: INTL_DATE_PART_NUMERIC };\n\t\treturn { month: INTL_DATE_MONTH_LONG, year: INTL_DATE_PART_NUMERIC };\n\t}\n\n\tif (style === DATE_FORMAT_STYLE_SHORT)\n\t\treturn { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT, year: INTL_DATE_PART_NUMERIC };\n\tif (style === DATE_FORMAT_STYLE_MEDIUM)\n\t\treturn { day: INTL_DATE_PART_NUMERIC, month: INTL_DATE_MONTH_SHORT, year: INTL_DATE_PART_NUMERIC };\n\treturn { day: INTL_DATE_PART_NUMERIC, month: INTL_DATE_MONTH_LONG, year: INTL_DATE_PART_NUMERIC };\n}\n\n/**\n * Возвращает настройки Intl для dateStyle-подобного формата без года.\n *\n * Семейство сохраняет различия стандартных уровней детализации:\n * числовой short, сокращённый текстовый medium и полный текстовый long.\n */\nfunction getMonthStyleIntlOptions(style: DateFormatStyle): Intl.DateTimeFormatOptions {\n\tif (style === DATE_FORMAT_STYLE_SHORT) return { day: INTL_DATE_PART_TWO_DIGIT, month: INTL_DATE_PART_TWO_DIGIT };\n\tif (style === DATE_FORMAT_STYLE_MEDIUM) return { day: INTL_DATE_PART_NUMERIC, month: INTL_DATE_MONTH_SHORT };\n\treturn { day: INTL_DATE_PART_NUMERIC, month: INTL_DATE_MONTH_LONG };\n}\n\n/**\n * Возвращает настройки Intl для timeStyle-подобного формата без timezoneName.\n *\n * Intl timeStyle=\"long\" добавляет часовой пояс в результат. В этом модуле\n * timezone намеренно не существует, поэтому long повторяет секундную точность\n * без вывода GMT/UTC-метки.\n */\nfunction getTimeStyleIntlOptions(style: DateFormatStyle): Intl.DateTimeFormatOptions {\n\tif (style === DATE_FORMAT_STYLE_SHORT)\n\t\treturn { hour: INTL_DATE_PART_TWO_DIGIT, minute: INTL_DATE_PART_TWO_DIGIT, hourCycle: INTL_DATE_HOUR_CYCLE_23 };\n\treturn {\n\t\thour: INTL_DATE_PART_TWO_DIGIT,\n\t\tminute: INTL_DATE_PART_TWO_DIGIT,\n\t\tsecond: INTL_DATE_PART_TWO_DIGIT,\n\t\thourCycle: INTL_DATE_HOUR_CYCLE_23\n\t};\n}\n\n/**\n * Удаляет timezone из настроек Intl, чтобы форматирование не могло сдвинуть\n * календарные компоненты или вывести timezoneName в строку.\n */\nfunction sanitizeIntlOptions(options: Intl.DateTimeFormatOptions): Intl.DateTimeFormatOptions {\n\tconst { timeZone, timeZoneName, ...safeOptions } = options;\n\tvoid timeZone;\n\tvoid timeZoneName;\n\treturn safeOptions;\n}\n\n/**\n * Проверяет, содержит ли Intl-конфигурация календарные поля.\n */\nfunction hasIntlDateFields(options: Intl.DateTimeFormatOptions): boolean {\n\treturn Boolean(options.dateStyle || options.year || options.month || options.day);\n}\n\n/**\n * Приводит Intl-конфигурацию к выбранной точности календарной даты.\n */\nfunction resolveIntlDatePrecisionOptions(options: Intl.DateTimeFormatOptions, precision: DateFormatPrecision): Intl.DateTimeFormatOptions {\n\tconst safeOptions = sanitizeIntlOptions(options);\n\tif (precision === DATE_FORMAT_PRECISION_DAY || !hasIntlDateFields(safeOptions)) return safeOptions;\n\n\tif (safeOptions.dateStyle) {\n\t\tconst style =\n\t\t\tsafeOptions.dateStyle === DATE_FORMAT_STYLE_SHORT || safeOptions.dateStyle === DATE_FORMAT_STYLE_MEDIUM\n\t\t\t\t? safeOptions.dateStyle\n\t\t\t\t: DATE_FORMAT_STYLE_LONG;\n\t\treturn getDateStyleIntlOptions(style, precision);\n\t}\n\n\tif (precision === DATE_FORMAT_PRECISION_YEAR) {\n\t\treturn { year: safeOptions.year ?? INTL_DATE_PART_NUMERIC };\n\t}\n\n\treturn {\n\t\tmonth: safeOptions.month ?? INTL_DATE_PART_TWO_DIGIT,\n\t\tyear: safeOptions.year ?? INTL_DATE_PART_NUMERIC\n\t};\n}\n\n/**\n * Создаёт функцию Intl-форматирования без timezone-настроек.\n *\n * Стандартный Intl timeStyle=\"long\" и timeStyle=\"full\" выводят timezoneName.\n * Поэтому любые timeStyle-настройки нормализуются в явные поля времени.\n */\nfunction createIntlFormatter(locale: string, options: Intl.DateTimeFormatOptions): CompiledDateFormatter {\n\tconst safeOptions = sanitizeIntlOptions(options);\n\tconst precisionFormatters = new Map<DateFormatPrecision, Intl.DateTimeFormat>();\n\n\tif (safeOptions.timeStyle) {\n\t\tconst timeOptions = getTimeStyleIntlOptions(\n\t\t\tsafeOptions.timeStyle === DATE_FORMAT_STYLE_SHORT ? DATE_FORMAT_STYLE_SHORT : DATE_FORMAT_STYLE_MEDIUM\n\t\t);\n\n\t\tif (safeOptions.dateStyle) {\n\t\t\tconst dateFormatter = new Intl.DateTimeFormat(locale, { dateStyle: safeOptions.dateStyle });\n\t\t\tconst timeFormatter = new Intl.DateTimeFormat(locale, timeOptions);\n\t\t\treturn (date, precision = DATE_FORMAT_PRECISION_DAY) => {\n\t\t\t\tif (precision === DATE_FORMAT_PRECISION_DAY) return `${dateFormatter.format(date)}, ${timeFormatter.format(date)}`;\n\n\t\t\t\tconst precisionOptions = resolveIntlDatePrecisionOptions({ dateStyle: safeOptions.dateStyle }, precision);\n\t\t\t\tlet precisionFormatter = precisionFormatters.get(precision);\n\t\t\t\tif (!precisionFormatter) {\n\t\t\t\t\tprecisionFormatter = new Intl.DateTimeFormat(locale, precisionOptions);\n\t\t\t\t\tprecisionFormatters.set(precision, precisionFormatter);\n\t\t\t\t}\n\n\t\t\t\treturn precisionFormatter.format(date);\n\t\t\t};\n\t\t}\n\n\t\treturn new Intl.DateTimeFormat(locale, timeOptions).format;\n\t}\n\n\tconst defaultFormatter = new Intl.DateTimeFormat(locale, safeOptions);\n\treturn (date, precision = DATE_FORMAT_PRECISION_DAY) => {\n\t\tif (precision === DATE_FORMAT_PRECISION_DAY) return defaultFormatter.format(date);\n\n\t\tlet precisionFormatter = precisionFormatters.get(precision);\n\t\tif (!precisionFormatter) {\n\t\t\tprecisionFormatter = new Intl.DateTimeFormat(locale, resolveIntlDatePrecisionOptions(safeOptions, precision));\n\t\t\tprecisionFormatters.set(precision, precisionFormatter);\n\t\t}\n\n\t\treturn precisionFormatter.format(date);\n\t};\n}\n\n/**\n * Возвращает значение токена шаблона для календарной даты.\n */\nfunction getPatternTokenValue(token: string, date: Date): string {\n\tconst fullYear = String(date.getFullYear());\n\n\tswitch (token) {\n\t\tcase DATE_PATTERN_TOKEN_YEAR:\n\t\t\treturn fullYear;\n\t\tcase DATE_PATTERN_TOKEN_SHORT_YEAR:\n\t\t\treturn fullYear.slice(-2);\n\t\tcase DATE_PATTERN_TOKEN_MONTH:\n\t\t\treturn padDatePart(date.getMonth() + 1);\n\t\tcase DATE_PATTERN_TOKEN_DAY:\n\t\t\treturn padDatePart(date.getDate());\n\t\tcase DATE_PATTERN_TOKEN_HOURS:\n\t\t\treturn padDatePart(date.getHours());\n\t\tcase DATE_PATTERN_TOKEN_MINUTES:\n\t\t\treturn padDatePart(date.getMinutes());\n\t\tcase DATE_PATTERN_TOKEN_SECONDS:\n\t\t\treturn padDatePart(date.getSeconds());\n\t\tdefault:\n\t\t\treturn token;\n\t}\n}\n\n/**\n * Компилирует машинный шаблон в функцию без разбора шаблона на каждый вызов.\n */\nfunction compileFixedPatternFormatter(pattern: string): CompiledDateFormatter {\n\tswitch (pattern) {\n\t\tcase DATE_PATTERN_ABAP_DATE:\n\t\t\treturn (date) => `${date.getFullYear()}${padDatePart(date.getMonth() + 1)}${padDatePart(date.getDate())}`;\n\t\tcase DATE_PATTERN_ABAP_DATE_TIME:\n\t\t\treturn (date) =>\n\t\t\t\t`${date.getFullYear()}${padDatePart(date.getMonth() + 1)}${padDatePart(date.getDate())}${padDatePart(date.getHours())}${padDatePart(\n\t\t\t\t\tdate.getMinutes()\n\t\t\t\t)}${padDatePart(date.getSeconds())}`;\n\t\tcase DATE_PATTERN_ISO_DATE:\n\t\t\treturn (date) => `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(date.getDate())}`;\n\t\tcase DATE_PATTERN_ISO_DATE_TIME:\n\t\t\treturn (date) =>\n\t\t\t\t`${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(date.getDate())}T${padDatePart(date.getHours())}:${padDatePart(\n\t\t\t\t\tdate.getMinutes()\n\t\t\t\t)}:${padDatePart(date.getSeconds())}`;\n\t\tdefault:\n\t\t\treturn compileGenericPatternFormatter(pattern);\n\t}\n}\n\n/**\n * Компилирует машинный шаблон с учётом точности календарной даты.\n */\nfunction compilePatternFormatter(pattern: string): CompiledDateFormatter {\n\tconst precisionFormatters = new Map<DateFormatPrecision, CompiledDateFormatter>();\n\n\treturn (date, precision = DATE_FORMAT_PRECISION_DAY) => {\n\t\tlet formatter = precisionFormatters.get(precision);\n\t\tif (!formatter) {\n\t\t\tformatter = compileFixedPatternFormatter(resolveDatePatternPrecision(pattern, precision));\n\t\t\tprecisionFormatters.set(precision, formatter);\n\t\t}\n\n\t\treturn formatter(date, DATE_FORMAT_PRECISION_DAY);\n\t};\n}\n\n/**\n * Компилирует произвольный шаблон один раз при регистрации предустановки.\n */\nfunction compileGenericPatternFormatter(pattern: string): CompiledDateFormatter {\n\tconst segments: string[] = [];\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\tDATE_PATTERN_TOKEN_RE.lastIndex = 0;\n\twhile ((match = DATE_PATTERN_TOKEN_RE.exec(pattern))) {\n\t\tif (match.index > lastIndex) segments.push(pattern.slice(lastIndex, match.index));\n\t\tsegments.push(match[0]);\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\tif (lastIndex < pattern.length) segments.push(pattern.slice(lastIndex));\n\n\treturn (date) => {\n\t\tlet result = \"\";\n\t\tfor (const segment of segments) {\n\t\t\tresult += isDatePatternToken(segment) ? getPatternTokenValue(segment, date) : segment;\n\t\t}\n\t\treturn result;\n\t};\n}\n\n/**\n * Форматирует длительность в предскомпилированный time-шаблон.\n */\nfunction formatDurationByPattern(durationMs: number, pattern: string, fallback: string): string {\n\tif (containsDatePatternToken(pattern, DATE_PATTERN_DATE_TOKENS)) return fallback;\n\tif (!containsDatePatternToken(pattern, DATE_PATTERN_TIME_TOKENS)) return fallback;\n\n\tconst sign = durationMs < 0 ? \"-\" : \"\";\n\tconst absoluteSeconds = Math.trunc(Math.abs(durationMs) / MS_IN_SECOND);\n\tconst hours = Math.trunc(absoluteSeconds / SECONDS_PER_HOUR);\n\tconst minutes = Math.trunc((absoluteSeconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);\n\tconst seconds = absoluteSeconds % SECONDS_PER_MINUTE;\n\n\tif (pattern === DATE_PATTERN_TIME_MINUTES) return `${sign}${padDatePart(hours)}:${padDatePart(minutes)}`;\n\tif (pattern === DATE_PATTERN_TIME_SECONDS) return `${sign}${padDatePart(hours)}:${padDatePart(minutes)}:${padDatePart(seconds)}`;\n\n\treturn (\n\t\tsign +\n\t\tpattern\n\t\t\t.replaceAll(DATE_PATTERN_TOKEN_HOURS, padDatePart(hours))\n\t\t\t.replaceAll(DATE_PATTERN_TOKEN_MINUTES, padDatePart(minutes))\n\t\t\t.replaceAll(DATE_PATTERN_TOKEN_SECONDS, padDatePart(seconds))\n\t);\n}\n\n/**\n * Компилирует Intl-форматтер или машинный шаблон для предустановки.\n */\nexport function compileDatePreset(config: DateFormatPresetConfig | DateFormatPreset): CompiledDateFormatPreset {\n\tconst preset: DateFormatPreset = { ...DATE_FORMAT_DEFAULTS, ...config };\n\tconst formatDateTime = createPresetFormatter(preset);\n\tconst durationPattern = preset.durationPattern ?? preset.pattern;\n\tconst compiledPreset: CompiledDateFormatPreset = { ...preset, formatDateTime };\n\n\tif (durationPattern) {\n\t\tcompiledPreset.formatDuration = (durationMs, fallback) => formatDurationByPattern(durationMs, durationPattern, fallback);\n\t}\n\n\treturn compiledPreset;\n}\n\n/**\n * Создаёт функцию форматирования даты для предустановки.\n */\nfunction createPresetFormatter(preset: DateFormatPreset): CompiledDateFormatter {\n\tif (preset.pattern) return compilePatternFormatter(preset.pattern);\n\n\tif (preset.intlDateOptions && preset.intlTimeOptions) {\n\t\tconst dateFormatter = createIntlFormatter(preset.locale, preset.intlDateOptions);\n\t\tconst timeFormatter = createIntlFormatter(preset.locale, preset.intlTimeOptions);\n\t\tconst joiner = preset.intlJoiner ?? \" \";\n\n\t\treturn (date, precision = DATE_FORMAT_PRECISION_DAY) => {\n\t\t\tif (precision !== DATE_FORMAT_PRECISION_DAY) return dateFormatter(date, precision);\n\t\t\treturn `${dateFormatter(date)}${joiner}${timeFormatter(date)}`;\n\t\t};\n\t}\n\n\treturn createIntlFormatter(preset.locale, preset.intlOptions ?? DATE_FORMAT_DEFAULTS.intlOptions);\n}\n\n/**\n * Создаёт форматтер месяца и года без локализованного маркера года `г.`.\n *\n * `Intl.DateTimeFormat` для `ru-RU` добавляет этот маркер автоматически.\n * Пресет предназначен для компактного отображения месячной точности в DateInput,\n * поэтому собирает только содержательные части `month` и `year`.\n */\nfunction createMonthYearFormatter(\n\tlocale: string,\n\tmonthStyle: typeof INTL_DATE_MONTH_SHORT | typeof INTL_DATE_MONTH_LONG\n): CompiledDateFormatter {\n\t// Русская локаль сокращает название месяца только в контексте даты с днём.\n\t// День нужен Intl для правильной формы, но в итоговую строку не включается.\n\tconst monthYearFormatter = new Intl.DateTimeFormat(\n\t\tlocale,\n\t\tmonthStyle === INTL_DATE_MONTH_SHORT\n\t\t\t? { day: INTL_DATE_PART_NUMERIC, month: monthStyle, year: INTL_DATE_PART_NUMERIC }\n\t\t\t: { month: monthStyle, year: INTL_DATE_PART_NUMERIC }\n\t);\n\tconst standaloneMonthFormatter = new Intl.DateTimeFormat(locale, { month: INTL_DATE_MONTH_LONG });\n\tconst yearFormatter = new Intl.DateTimeFormat(locale, { year: INTL_DATE_PART_NUMERIC });\n\n\treturn (date, precision = DATE_FORMAT_PRECISION_DAY) => {\n\t\tconst formatter = precision === DATE_FORMAT_PRECISION_YEAR ? yearFormatter : monthYearFormatter;\n\t\tconst parts = formatter.formatToParts(date);\n\t\tconst year = parts.find((part) => part.type === INTL_DATE_PART_YEAR)?.value ?? \"\";\n\t\tif (precision === DATE_FORMAT_PRECISION_YEAR) return year;\n\n\t\tconst contextualMonth = parts.find((part) => part.type === INTL_DATE_PART_MONTH)?.value ?? \"\";\n\t\t// Для мая Intl возвращает нескорочённую родительную форму `мая`.\n\t\t// Если сокращение с точкой отсутствует, берём самостоятельную форму `май`.\n\t\tconst month =\n\t\t\tmonthStyle === INTL_DATE_MONTH_SHORT && !contextualMonth.endsWith(\".\")\n\t\t\t\t? (standaloneMonthFormatter.formatToParts(date).find((part) => part.type === INTL_DATE_PART_MONTH)?.value ??\n\t\t\t\t\tcontextualMonth)\n\t\t\t\t: contextualMonth;\n\n\t\treturn `${month} ${year}`;\n\t};\n}\n\n/**\n * Компилирует встроенный пресет с учётом его фиксированной семантики.\n */\nfunction compileBuiltinDatePreset(config: DateFormatPresetConfig): CompiledDateFormatPreset {\n\tconst preset = compileDatePreset(config);\n\tconst monthYearStyle = MONTH_YEAR_PRESET_STYLES.get(config.name);\n\tif (!monthYearStyle) return preset;\n\n\treturn {\n\t\t...preset,\n\t\tformatDateTime: createMonthYearFormatter(preset.locale, monthYearStyle)\n\t};\n}\n\n/**\n * Инициализирует реестр встроенными предустановками.\n */\nfunction initPresets(): void {\n\tfor (const config of BUILTIN_PRESETS) {\n\t\tregistry.set(config.name, compileBuiltinDatePreset(config));\n\t}\n}\n\ninitPresets();\n\n/**\n * Возвращает предустановку по имени.\n */\nexport function getDatePreset(name: string): DateFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\n/**\n * Возвращает скомпилированную предустановку по имени.\n */\nexport function getCompiledDatePreset(name: string): CompiledDateFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\n/**\n * Возвращает список имён доступных предустановок.\n */\nexport function getDatePresetNames(): string[] {\n\treturn Array.from(registry.keys());\n}\n\n/**\n * Проверяет, что строка является алиасом style-пресета даты.\n */\nexport function isDateFormatStyle(value: string): value is DateFormatStyle {\n\treturn FORMAT_STYLES.includes(value as DateFormatStyle);\n}\n\n/**\n * Проверяет, что строка является поддерживаемой точностью даты.\n */\nexport function isDateFormatPrecision(value: string): value is DateFormatPrecision {\n\treturn FORMAT_PRECISIONS.includes(value as DateFormatPrecision);\n}\n\n/**\n * Нормализует имя пресета, алиас style-формата или ручной шаблон.\n */\nexport function resolveDateFormatName(dateFormat?: string, defaultFormat: string = DATE_PRESET_NAME_DATE): string {\n\tconst normalizedFormat = dateFormat?.trim();\n\tif (!normalizedFormat) return defaultFormat;\n\n\treturn isDateFormatStyle(normalizedFormat) ? DATE_FORMAT_STYLE_PRESET_NAMES[normalizedFormat] : normalizedFormat;\n}\n\n/**\n * Создаёт кешируемый объектный пресет для ручного шаблона.\n */\nfunction createPatternDatePreset(pattern: string, presetName: string, locale: string, invalidFallback: string): DateFormatPreset {\n\tconst cacheKey = `${presetName}\\u0000${locale}\\u0000${invalidFallback}\\u0000${pattern}`;\n\tconst cachedPreset = patternPresetCache.get(cacheKey);\n\tif (cachedPreset) return cachedPreset;\n\n\tconst preset = {\n\t\tname: `${presetName}:${pattern}`,\n\t\tpattern,\n\t\tlocale,\n\t\tinvalidFallback\n\t};\n\n\tpatternPresetCache.set(cacheKey, preset);\n\treturn preset;\n}\n\nexport interface ResolveDateFormatPresetOptions {\n\t/**\n\t * Формат по умолчанию, если входная строка пустая.\n\t */\n\tdefaultFormat?: string;\n\t/**\n\t * Префикс имени для объектных пресетов ручных шаблонов.\n\t */\n\tpatternPresetName?: string;\n\t/**\n\t * Локаль объектного пресета ручного шаблона.\n\t */\n\tlocale?: string;\n\t/**\n\t * Fallback объектного пресета ручного шаблона.\n\t */\n\tinvalidFallback?: string;\n}\n\n/**\n * Возвращает зарегистрированный пресет или кешируемый объектный пресет для ручного шаблона.\n */\nexport function resolveDateFormatPreset(\n\tdateFormat?: string,\n\t{\n\t\tdefaultFormat = DATE_PRESET_NAME_DATE,\n\t\tpatternPresetName = \"__date_pattern__\",\n\t\tlocale = DEFAULT_DATE_LOCALE,\n\t\tinvalidFallback = \"\"\n\t}: ResolveDateFormatPresetOptions = {}\n): string | DateFormatPreset {\n\tconst resolvedFormat = resolveDateFormatName(dateFormat, defaultFormat);\n\tif (getDatePreset(resolvedFormat)) return resolvedFormat;\n\n\treturn createPatternDatePreset(resolvedFormat, patternPresetName, locale, invalidFallback);\n}\n\n/**\n * Регистрирует или перезаписывает предустановку.\n */\nexport function registerDatePreset(config: DateFormatPresetConfig): DateFormatPreset {\n\tconst preset = compileDatePreset(config);\n\tregistry.set(preset.name, preset);\n\treturn preset;\n}\n\n/**\n * Сбрасывает реестр к встроенному состоянию.\n */\nexport function resetDatePresets(): void {\n\tregistry.clear();\n\tinitPresets();\n}\n","import {\n\tMS_IN_SECOND,\n\tMS_IN_MINUTE,\n\tMS_IN_HOUR,\n\tMS_IN_DAY,\n\tCALENDAR_MONTHS_PER_YEAR,\n\tCALENDAR_LAST_HOUR,\n\tCALENDAR_LAST_MINUTE\n} from \"./calendarDateConstants\";\nimport {\n\tINTL_DATE_PART_MONTH,\n\tINTL_DATE_MONTH_SHORT,\n\tINTL_DATE_MONTH_LONG,\n\tINTL_DATE_PART_NUMERIC,\n\tDATE_FORMAT_PRECISION_YEAR,\n\tDATE_FORMAT_PRECISION_MONTH,\n\tDATE_FORMAT_PRECISION_DAY\n} from \"./dateFormatConstants\";\nimport {\n\tDATE_PATTERN_DAY_MONTH_YEAR_DOTTED,\n\tDATE_PATTERN_TOKEN_YEAR,\n\tDATE_PATTERN_TOKEN_SHORT_YEAR,\n\tDATE_PATTERN_TOKEN_MONTH,\n\tDATE_PATTERN_TOKEN_DAY,\n\tDATE_PATTERN_TOKEN_HOURS,\n\tDATE_PATTERN_TOKEN_MINUTES,\n\tDATE_PATTERN_TOKEN_SECONDS\n} from \"./datePatternConstants\";\nimport {\n\tDATE_PRESET_NAME_DATE,\n\tDATE_PRESET_NAME_DATE_SHORT,\n\tDATE_PRESET_NAME_MONTH_SHORT,\n\tDATE_PRESET_NAME_MONTH_MEDIUM,\n\tDATE_PRESET_NAME_MONTH_LONG,\n\tDATE_PRESET_NAME_MONTH_YEAR_MEDIUM,\n\tDATE_PRESET_NAME_MONTH_YEAR_LONG,\n\tDATE_PRESET_NAME_DATETIME,\n\tDATE_PRESET_NAME_DATETIME_SECONDS,\n\tDATE_PRESET_NAME_DATETIME_SHORT\n} from \"./datePresetNameConstants\";\nimport {\n\tDATE_INPUT_SOURCE_ISO_LOCAL,\n\tPARSED_DATE_KIND_DATE_TIME,\n\tDATE_INPUT_SOURCE_TIMESTAMP,\n\tDATE_INPUT_SOURCE_ODATA_TICKS,\n\tDATE_INPUT_SOURCE_ISO_ZONED,\n\tDATE_INPUT_SOURCE_ABAP_COMPACT,\n\tDATE_INPUT_SOURCE_ABAP_TIMESTAMP,\n\tDATE_INPUT_SOURCE_ABAP_DOTTED,\n\tDATE_INPUT_SOURCE_SLASH_DATE,\n\tDATE_INPUT_SOURCE_ODATA_LITERAL,\n\tPARSED_DATE_KIND_DURATION,\n\tDATE_INPUT_SOURCE_ISO_DURATION,\n\tDATE_INPUT_SOURCE_DATE_OBJECT\n} from \"./dateValueConstants\";\nimport { DATE_PATTERN_TOKEN_RE, hasDatePatternTokens, resolveDatePatternPrecision } from \"./pattern\";\nimport { DATE_FORMAT_DEFAULTS, getDatePreset, resolveDateFormatName } from \"./presets\";\n\nimport type { DateFormatPattern, DateFormatPrecision, ParsedDateTimeValue, ParsedDateValue } from \"./types\";\n\nconst DATE_PARSING_MODE_FLOATING = \"floating\";\nconst DATE_PARSING_MODE_INSTANT = \"instant\";\nconst TIMESTAMP_MILLISECONDS_THRESHOLD = 1e12;\nconst MONTH_NAME_REFERENCE_YEAR = 2026;\nconst MILLISECOND_DIGITS = 3;\nconst PREVIOUS_CENTURY = 1900;\nconst CURRENT_CENTURY = 2000;\nconst ABAP_YEAR_END_OFFSET = 4;\nconst ABAP_MONTH_END_OFFSET = 6;\nconst ABAP_DAY_END_OFFSET = 8;\nconst ABAP_HOUR_END_OFFSET = 10;\nconst ABAP_MINUTE_END_OFFSET = 12;\nconst ABAP_SECOND_END_OFFSET = 14;\n\n/**\n * Регулярное выражение для OData даты вида `/Date(1720137600000+0300)/`.\n */\nconst ODATA_TICKS_RE = /^\\/Date\\((-?\\d+)([+-]\\d{4})?\\)\\/$/;\n\n/**\n * Регулярное выражение для OData литералов вида `datetime'2026-03-03T18:03:50'`.\n */\nconst ODATA_LITERAL_RE = /^(datetimeoffset|datetime)'(.+)'$/i;\n\n/**\n * Регулярное выражение для ISO-даты без timezone.\n */\nconst ISO_LOCAL_RE = /^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2})(?::(\\d{2})(?::(\\d{2})(?:\\.(\\d{1,9}))?)?)?)?$/;\n\n/**\n * Регулярное выражение для даты с явным timezone.\n */\nconst ISO_ZONED_RE = /(Z|([+-])(\\d{2}):?(\\d{2}))$/i;\n\n/**\n * Регулярное выражение для ABAP даты `YYYYMMDD`.\n */\nconst ABAP_COMPACT_RE = /^\\d{8}$/;\n\n/**\n * Регулярное выражение для ABAP timestamp `YYYYMMDDHHmmss...`.\n * Хвост после секунд содержит доли/служебные разряды и не влияет на календарное время.\n */\nconst ABAP_TIMESTAMP_RE = /^\\d{14,}$/;\n\n/**\n * Регулярное выражение для даты вида `DD.MM.YYYY`.\n */\nconst ABAP_DOTTED_RE = /^(\\d{2})\\.(\\d{2})\\.(\\d{4})$/;\n\n/**\n * Регулярное выражение для даты вида `MM/DD/YYYY`.\n */\nconst SLASH_DATE_RE = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/;\n\n/**\n * Регулярное выражение для ISO-8601 длительности.\n */\nconst ISO_DURATION_RE = /^([+-])?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)(?:\\.(\\d+))?S)?)?$/;\n\n/**\n * Набор строковых значений, трактуемых как пустые.\n */\nconst EMPTY_STRING_VALUES = new Set([\"\", \"null\", \"undefined\"]);\n\n/**\n * Константы для расчёта длительностей.\n */\nconst APPROX_DAYS_IN_MONTH = 30;\nconst APPROX_DAYS_IN_YEAR = 365;\nconst TWO_DIGIT_YEAR_PIVOT = 70;\n\n/**\n * Режим интерпретации источников, которые несут абсолютный момент времени.\n *\n * `floating` сохраняет историческую семантику видимых календарных компонентов,\n * `instant` применяет timezone и сохраняет Unix instant.\n */\ntype DateParsingMode = typeof DATE_PARSING_MODE_FLOATING | typeof DATE_PARSING_MODE_INSTANT;\n\n/**\n * Внутренние настройки общего механизма парсинга.\n *\n * Опция намеренно не экспортируется: публичные функции жёстко выбирают режим,\n * чтобы существующий вызов нельзя было неявно переключить на другую семантику.\n */\ntype ParseDateValueInternalOptions = {\n\tmode?: DateParsingMode;\n};\n\nconst DEFAULT_DATE_PARSING_MODE: DateParsingMode = DATE_PARSING_MODE_FLOATING;\n\n/**\n * Шаблоны ручного ввода для встроенных Intl-пресетов.\n */\nconst DATE_FORMAT_PARSE_PATTERNS: Readonly<Record<string, readonly DateFormatPattern[]>> = Object.freeze({\n\t[DATE_PRESET_NAME_DATE]: Object.freeze([DATE_PATTERN_DAY_MONTH_YEAR_DOTTED] as const),\n\t[DATE_PRESET_NAME_DATE_SHORT]: Object.freeze([DATE_PATTERN_DAY_MONTH_YEAR_DOTTED] as const),\n\t[DATE_PRESET_NAME_DATETIME]: Object.freeze([\"dd.MM.yyyy HH:mm\"] as const),\n\t[DATE_PRESET_NAME_DATETIME_SECONDS]: Object.freeze([\"dd.MM.yyyy HH:mm:ss\"] as const),\n\t[DATE_PRESET_NAME_DATETIME_SHORT]: Object.freeze([\"dd.MM.yyyy, HH:mm\"] as const)\n});\n\n/**\n * Регулярное выражение для человекочитаемых дат вида `3 марта 2026 г.`.\n */\nconst LOCALIZED_DATE_RE = /^(\\d{1,2})\\s+([\\p{L}.]+)\\s+(\\d{4})(?:\\s*[\\p{L}.]+)?(?:,?\\s+(\\d{1,2}):(\\d{2})(?::(\\d{2}))?)?$/iu;\n/**\n * Регулярное выражение для короткой числовой даты без года вида `03.03`.\n */\nconst NUMERIC_DAY_MONTH_RE = /^(\\d{1,2})\\.(\\d{1,2})$/u;\n/**\n * Регулярное выражение для текстовой даты без года вида `3 марта`.\n */\nconst LOCALIZED_DAY_MONTH_RE = /^(\\d{1,2})\\s+([\\p{L}.]+)$/iu;\nconst LOCALIZED_MONTH_RE = /^([\\p{L}.]+)\\s+(\\d{4})(?:\\s*[\\p{L}.]+)?$/iu;\nconst LOCALIZED_YEAR_RE = /^(\\d{4})(?:\\s*[\\p{L}.]+)?$/iu;\n\nconst localizedMonthIndexCache = new Map<string, ReadonlyMap<string, number>>();\nconst DAY_MONTH_PRESET_NAMES = new Set<string>([DATE_PRESET_NAME_MONTH_SHORT, DATE_PRESET_NAME_MONTH_MEDIUM, DATE_PRESET_NAME_MONTH_LONG]);\nconst MONTH_YEAR_PRESET_NAMES = new Set<string>([DATE_PRESET_NAME_MONTH_YEAR_MEDIUM, DATE_PRESET_NAME_MONTH_YEAR_LONG]);\n\n/**\n * Создаёт календарную дату без timezone-семантики и валидирует компоненты.\n */\nfunction createCalendarDate(year: number, month: number, day: number, hour = 0, minute = 0, second = 0, millisecond = 0): Date | null {\n\tconst result = new Date(year, month - 1, day, hour, minute, second, millisecond);\n\tconst isValid =\n\t\tresult.getFullYear() === year &&\n\t\tresult.getMonth() === month - 1 &&\n\t\tresult.getDate() === day &&\n\t\tresult.getHours() === hour &&\n\t\tresult.getMinutes() === minute &&\n\t\tresult.getSeconds() === second;\n\n\treturn isValid ? result : null;\n}\n\n/**\n * Нормализует имя месяца из Intl-форматтера для обратного парсинга.\n */\nfunction normalizeLocalizedMonthName(monthName: string, locale: string): string {\n\treturn monthName.toLocaleLowerCase(locale).replace(/\\.$/, \"\");\n}\n\n/**\n * Добавляет имя месяца в runtime-словарь локали.\n */\nfunction addLocalizedMonthName(monthIndex: Map<string, number>, monthName: string, index: number, locale: string): void {\n\tmonthIndex.set(normalizeLocalizedMonthName(monthName, locale), index);\n}\n\n/**\n * Добавляет имя месяца из formatToParts, чтобы учитывать падеж в составе полной даты.\n */\nfunction addLocalizedMonthPart(\n\tmonthIndex: Map<string, number>,\n\tformatter: Intl.DateTimeFormat,\n\tdate: Date,\n\tindex: number,\n\tlocale: string\n): void {\n\tconst monthPart = formatter.formatToParts(date).find((part) => part.type === INTL_DATE_PART_MONTH);\n\tif (monthPart) addLocalizedMonthName(monthIndex, monthPart.value, index, locale);\n}\n\n/**\n * Собирает словарь названий месяцев через Intl.DateTimeFormat для заданной локали.\n */\nfunction getLocalizedMonthIndex(locale: string): ReadonlyMap<string, number> {\n\tconst cachedIndex = localizedMonthIndexCache.get(locale);\n\tif (cachedIndex) return cachedIndex;\n\n\tconst monthIndex = new Map<string, number>();\n\tconst shortFormatter = new Intl.DateTimeFormat(locale, { month: INTL_DATE_MONTH_SHORT });\n\tconst longFormatter = new Intl.DateTimeFormat(locale, { month: INTL_DATE_MONTH_LONG });\n\tconst shortDateFormatter = new Intl.DateTimeFormat(locale, {\n\t\tday: INTL_DATE_PART_NUMERIC,\n\t\tmonth: INTL_DATE_MONTH_SHORT,\n\t\tyear: INTL_DATE_PART_NUMERIC\n\t});\n\tconst longDateFormatter = new Intl.DateTimeFormat(locale, {\n\t\tday: INTL_DATE_PART_NUMERIC,\n\t\tmonth: INTL_DATE_MONTH_LONG,\n\t\tyear: INTL_DATE_PART_NUMERIC\n\t});\n\n\tfor (let month = 0; month < CALENDAR_MONTHS_PER_YEAR; month += 1) {\n\t\tconst date = new Date(MONTH_NAME_REFERENCE_YEAR, month, 1);\n\t\taddLocalizedMonthName(monthIndex, shortFormatter.format(date), month, locale);\n\t\taddLocalizedMonthName(monthIndex, longFormatter.format(date), month, locale);\n\t\taddLocalizedMonthPart(monthIndex, shortDateFormatter, date, month, locale);\n\t\taddLocalizedMonthPart(monthIndex, longDateFormatter, date, month, locale);\n\t}\n\n\tlocalizedMonthIndexCache.set(locale, monthIndex);\n\treturn monthIndex;\n}\n\n/**\n * Парсит человекочитаемую дату, сформированную Intl-пресетами текущей локали.\n */\nfunction parseLocalizedDayString(value: string, locale: string): ParsedDateTimeValue | null {\n\tconst match = LOCALIZED_DATE_RE.exec(value.trim());\n\tif (!match) return null;\n\n\tconst day = Number(match[1]);\n\tconst monthIndex = getLocalizedMonthIndex(locale).get(normalizeLocalizedMonthName(match[2], locale));\n\tconst year = Number(match[3]);\n\tconst hour = Number(match[4] ?? 0);\n\tconst minute = Number(match[5] ?? 0);\n\tconst second = Number(match[6] ?? 0);\n\n\tif (monthIndex === undefined) return null;\n\tif (!Number.isFinite(day) || !Number.isFinite(year) || !Number.isFinite(hour) || !Number.isFinite(minute) || !Number.isFinite(second)) {\n\t\treturn null;\n\t}\n\n\tconst parsed = createCalendarDate(year, monthIndex + 1, day, hour, minute, second);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\n/**\n * Парсит человекочитаемую дату без года, сформированную day+month-пресетами.\n */\nfunction parseLocalizedDayMonthString(value: string, locale: string, year: number): ParsedDateTimeValue | null {\n\tconst numericMatch = NUMERIC_DAY_MONTH_RE.exec(value.trim());\n\tif (numericMatch) {\n\t\tconst day = Number(numericMatch[1]);\n\t\tconst month = Number(numericMatch[2]);\n\t\tconst parsed = createCalendarDate(year, month, day);\n\n\t\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n\t}\n\n\tconst match = LOCALIZED_DAY_MONTH_RE.exec(value.trim());\n\tif (!match) return null;\n\n\tconst day = Number(match[1]);\n\tconst monthIndex = getLocalizedMonthIndex(locale).get(normalizeLocalizedMonthName(match[2], locale));\n\n\tif (monthIndex === undefined || !Number.isFinite(day)) {\n\t\treturn null;\n\t}\n\n\tconst parsed = createCalendarDate(year, monthIndex + 1, day);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\n/**\n * Парсит человекочитаемый месяц, сформированный Intl-пресетами текущей локали.\n */\nfunction parseLocalizedMonthString(value: string, locale: string): ParsedDateTimeValue | null {\n\tconst match = LOCALIZED_MONTH_RE.exec(value.trim());\n\tif (!match) return null;\n\n\tconst monthIndex = getLocalizedMonthIndex(locale).get(normalizeLocalizedMonthName(match[1], locale));\n\tconst year = Number(match[2]);\n\n\tif (monthIndex === undefined || !Number.isFinite(year)) return null;\n\n\tconst parsed = createCalendarDate(year, monthIndex + 1, 1);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\n/**\n * Парсит человекочитаемый год, сформированный Intl-пресетами текущей локали.\n */\nfunction parseLocalizedYearString(value: string): ParsedDateTimeValue | null {\n\tconst match = LOCALIZED_YEAR_RE.exec(value.trim());\n\tif (!match) return null;\n\n\tconst year = Number(match[1]);\n\tif (!Number.isFinite(year)) return null;\n\n\tconst parsed = createCalendarDate(year, 1, 1);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\n/**\n * Парсит человекочитаемую дату с учётом точности календарного значения.\n */\nfunction parseLocalizedDateString(value: string, locale: string, precision: DateFormatPrecision): ParsedDateTimeValue | null {\n\tif (precision === DATE_FORMAT_PRECISION_YEAR) return parseLocalizedYearString(value);\n\tif (precision === DATE_FORMAT_PRECISION_MONTH) return parseLocalizedMonthString(value, locale);\n\n\treturn parseLocalizedDayString(value, locale);\n}\n\n/**\n * Проверяет, что формат может быть распарсен как `день месяц` без года.\n */\nfunction isDayMonthPresetName(dateFormat: string): boolean {\n\treturn DAY_MONTH_PRESET_NAMES.has(dateFormat);\n}\n\n/**\n * Проверяет, что пресет содержит месяц и год без дня.\n */\nfunction isMonthYearPresetName(dateFormat: string): boolean {\n\treturn MONTH_YEAR_PRESET_NAMES.has(dateFormat);\n}\n\n/**\n * Возвращает опорный год для пресетов без года.\n */\nfunction resolveReferenceYear(referenceDate: Date | undefined): number {\n\tif (referenceDate instanceof Date && !Number.isNaN(referenceDate.getTime())) {\n\t\treturn referenceDate.getFullYear();\n\t}\n\n\treturn new Date().getFullYear();\n}\n\n/**\n * Пересобирает `Date` в календарную дату через локальные компоненты.\n */\nfunction cloneCalendarDate(date: Date): Date {\n\treturn new Date(\n\t\tdate.getFullYear(),\n\t\tdate.getMonth(),\n\t\tdate.getDate(),\n\t\tdate.getHours(),\n\t\tdate.getMinutes(),\n\t\tdate.getSeconds(),\n\t\tdate.getMilliseconds()\n\t);\n}\n\n/**\n * Пересобирает `Date` в календарную дату через UTC-компоненты.\n *\n * Используется для источников, где дата уже пришла как instant,\n * но визуальные компоненты нужно сохранить без timezone-сдвига.\n */\nfunction cloneUtcCalendarDate(date: Date): Date {\n\treturn new Date(\n\t\tdate.getUTCFullYear(),\n\t\tdate.getUTCMonth(),\n\t\tdate.getUTCDate(),\n\t\tdate.getUTCHours(),\n\t\tdate.getUTCMinutes(),\n\t\tdate.getUTCSeconds(),\n\t\tdate.getUTCMilliseconds()\n\t);\n}\n\n/**\n * Формирует результат парсинга календарной даты/времени.\n */\nfunction asDateTimeValue(date: Date, source: ParsedDateTimeValue[\"source\"]): ParsedDateTimeValue {\n\treturn { kind: PARSED_DATE_KIND_DATE_TIME, source, date };\n}\n\n/**\n * Парсит timestamp (секунды или миллисекунды Unix epoch).\n */\nfunction parseTimestamp(value: number, mode: DateParsingMode = DEFAULT_DATE_PARSING_MODE): ParsedDateTimeValue | null {\n\tif (!Number.isFinite(value)) return null;\n\n\tconst timestamp = Math.abs(value) < TIMESTAMP_MILLISECONDS_THRESHOLD ? value * MS_IN_SECOND : value;\n\tconst parsed = new Date(timestamp);\n\tif (Number.isNaN(parsed.getTime())) return null;\n\n\treturn asDateTimeValue(mode === DATE_PARSING_MODE_INSTANT ? parsed : cloneUtcCalendarDate(parsed), DATE_INPUT_SOURCE_TIMESTAMP);\n}\n\n/**\n * Парсит OData ticks: floating-режим восстанавливает сервисные компоненты\n * через offset, instant-режим сохраняет абсолютный timestamp.\n */\nfunction parseODataTicks(value: string, mode: DateParsingMode = DEFAULT_DATE_PARSING_MODE): ParsedDateTimeValue | null {\n\tconst match = ODATA_TICKS_RE.exec(value);\n\tif (!match) return null;\n\n\tconst timestamp = Number(match[1]);\n\tif (!Number.isFinite(timestamp)) return null;\n\n\tif (mode === DATE_PARSING_MODE_INSTANT) {\n\t\t// В OData v2 ticks уже содержат миллисекунды от Unix epoch.\n\t\t// Offset описывает сервисное представление и не должен повторно сдвигать instant.\n\t\tconst instantDate = new Date(timestamp);\n\t\treturn Number.isNaN(instantDate.getTime()) ? null : asDateTimeValue(instantDate, DATE_INPUT_SOURCE_ODATA_TICKS);\n\t}\n\n\tconst offset = match[2];\n\tif (!offset) return asDateTimeValue(cloneUtcCalendarDate(new Date(timestamp)), DATE_INPUT_SOURCE_ODATA_TICKS);\n\n\tconst sign = offset.startsWith(\"-\") ? -1 : 1;\n\tconst hours = Number(offset.slice(1, 3));\n\tconst minutes = Number(offset.slice(3, 5));\n\tif (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null;\n\n\tconst offsetMs = sign * (hours * MS_IN_HOUR + minutes * MS_IN_MINUTE);\n\treturn asDateTimeValue(cloneUtcCalendarDate(new Date(timestamp + offsetMs)), DATE_INPUT_SOURCE_ODATA_TICKS);\n}\n\n/**\n * Парсит даты без timezone в ISO-подобных форматах.\n */\nfunction parseIsoLocal(value: string): ParsedDateTimeValue | null {\n\tconst match = ISO_LOCAL_RE.exec(value);\n\tif (!match) return null;\n\n\tconst year = Number(match[1]);\n\tconst month = Number(match[2]);\n\tconst day = Number(match[3]);\n\tconst hour = Number(match[4] ?? 0);\n\tconst minute = Number(match[5] ?? 0);\n\tconst second = Number(match[6] ?? 0);\n\tconst millisecondsRaw = (match[7] ?? \"\").slice(0, MILLISECOND_DIGITS).padEnd(MILLISECOND_DIGITS, \"0\");\n\tconst millisecond = Number(millisecondsRaw || 0);\n\n\tconst parsed = createCalendarDate(year, month, day, hour, minute, second, millisecond);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\n/**\n * Возвращает смещение ISO timezone в миллисекундах.\n *\n * Положительный offset означает, что локальные компоненты опережают UTC,\n * поэтому при построении instant это значение вычитается.\n */\nfunction resolveIsoTimezoneOffsetMs(timezoneMatch: RegExpExecArray): number | null {\n\tif (timezoneMatch[1].toUpperCase() === \"Z\") return 0;\n\n\tconst sign = timezoneMatch[2] === \"-\" ? -1 : 1;\n\tconst hours = Number(timezoneMatch[3]);\n\tconst minutes = Number(timezoneMatch[4]);\n\tif (!Number.isFinite(hours) || !Number.isFinite(minutes) || hours > CALENDAR_LAST_HOUR || minutes > CALENDAR_LAST_MINUTE) return null;\n\n\treturn sign * (hours * MS_IN_HOUR + minutes * MS_IN_MINUTE);\n}\n\n/**\n * Парсит даты с явным timezone.\n */\nfunction parseIsoZoned(value: string, mode: DateParsingMode = DEFAULT_DATE_PARSING_MODE): ParsedDateTimeValue | null {\n\tconst timezoneMatch = ISO_ZONED_RE.exec(value);\n\tif (!timezoneMatch) return null;\n\n\tconst normalizedValue = value.slice(0, timezoneMatch.index);\n\tconst parsed = parseIsoLocal(normalizedValue);\n\tif (!parsed) return null;\n\tif (mode === DATE_PARSING_MODE_FLOATING) return asDateTimeValue(parsed.date, DATE_INPUT_SOURCE_ISO_ZONED);\n\n\tconst timezoneOffsetMs = resolveIsoTimezoneOffsetMs(timezoneMatch);\n\tif (timezoneOffsetMs === null) return null;\n\n\tconst calendarDate = parsed.date;\n\tconst instantTimestamp =\n\t\tDate.UTC(\n\t\t\tcalendarDate.getFullYear(),\n\t\t\tcalendarDate.getMonth(),\n\t\t\tcalendarDate.getDate(),\n\t\t\tcalendarDate.getHours(),\n\t\t\tcalendarDate.getMinutes(),\n\t\t\tcalendarDate.getSeconds(),\n\t\t\tcalendarDate.getMilliseconds()\n\t\t) - timezoneOffsetMs;\n\n\tconst instantDate = new Date(instantTimestamp);\n\treturn Number.isNaN(instantDate.getTime()) ? null : asDateTimeValue(instantDate, DATE_INPUT_SOURCE_ISO_ZONED);\n}\n\n/**\n * Парсит ABAP дату формата `YYYYMMDD`.\n */\nfunction parseAbapCompact(value: string): ParsedDateTimeValue | null {\n\tif (!ABAP_COMPACT_RE.test(value)) return null;\n\n\tconst year = Number(value.slice(0, ABAP_YEAR_END_OFFSET));\n\tconst month = Number(value.slice(ABAP_YEAR_END_OFFSET, ABAP_MONTH_END_OFFSET));\n\tconst day = Number(value.slice(ABAP_MONTH_END_OFFSET, ABAP_DAY_END_OFFSET));\n\n\tconst parsed = createCalendarDate(year, month, day);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ABAP_COMPACT) : null;\n}\n\n/**\n * Парсит ABAP timestamp формата `YYYYMMDDHHmmss...`.\n */\nfunction parseAbapTimestamp(value: string): ParsedDateTimeValue | null {\n\tif (!ABAP_TIMESTAMP_RE.test(value)) return null;\n\n\tconst year = Number(value.slice(0, ABAP_YEAR_END_OFFSET));\n\tconst month = Number(value.slice(ABAP_YEAR_END_OFFSET, ABAP_MONTH_END_OFFSET));\n\tconst day = Number(value.slice(ABAP_MONTH_END_OFFSET, ABAP_DAY_END_OFFSET));\n\tconst hour = Number(value.slice(ABAP_DAY_END_OFFSET, ABAP_HOUR_END_OFFSET));\n\tconst minute = Number(value.slice(ABAP_HOUR_END_OFFSET, ABAP_MINUTE_END_OFFSET));\n\tconst second = Number(value.slice(ABAP_MINUTE_END_OFFSET, ABAP_SECOND_END_OFFSET));\n\n\tconst parsed = createCalendarDate(year, month, day, hour, minute, second);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ABAP_TIMESTAMP) : null;\n}\n\n/**\n * Парсит дату формата `DD.MM.YYYY`.\n */\nfunction parseAbapDotted(value: string): ParsedDateTimeValue | null {\n\tconst match = ABAP_DOTTED_RE.exec(value);\n\tif (!match) return null;\n\n\tconst day = Number(match[1]);\n\tconst month = Number(match[2]);\n\tconst year = Number(match[3]);\n\n\tconst parsed = createCalendarDate(year, month, day);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ABAP_DOTTED) : null;\n}\n\n/**\n * Парсит дату формата `MM/DD/YYYY`.\n */\nfunction parseSlashDate(value: string): ParsedDateTimeValue | null {\n\tconst match = SLASH_DATE_RE.exec(value);\n\tif (!match) return null;\n\n\tconst month = Number(match[1]);\n\tconst day = Number(match[2]);\n\tconst year = Number(match[3]);\n\n\tconst parsed = createCalendarDate(year, month, day);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_SLASH_DATE) : null;\n}\n\n/**\n * Парсит OData литералы `datetime'...'` и `datetimeoffset'...'`.\n */\nfunction parseODataLiteral(value: string, mode: DateParsingMode = DEFAULT_DATE_PARSING_MODE): ParsedDateTimeValue | null {\n\tconst match = ODATA_LITERAL_RE.exec(value);\n\tif (!match) return null;\n\n\tconst innerValue = match[2].trim();\n\treturn parseDateString(innerValue, DATE_INPUT_SOURCE_ODATA_LITERAL, mode);\n}\n\n/**\n * Парсит ISO-8601 длительность.\n *\n * Для год/месяц используется приближение: 365 и 30 суток соответственно.\n */\nfunction parseIsoDuration(value: string): ParsedDateValue | null {\n\tconst match = ISO_DURATION_RE.exec(value);\n\tif (!match) return null;\n\n\tconst sign = match[1] === \"-\" ? -1 : 1;\n\tconst years = Number(match[2] ?? 0);\n\tconst months = Number(match[3] ?? 0);\n\tconst days = Number(match[4] ?? 0);\n\tconst hours = Number(match[5] ?? 0);\n\tconst minutes = Number(match[6] ?? 0);\n\tconst seconds = Number(match[7] ?? 0);\n\tconst fractionRaw = (match[8] ?? \"\").slice(0, MILLISECOND_DIGITS).padEnd(MILLISECOND_DIGITS, \"0\");\n\tconst milliseconds = Number(fractionRaw || 0);\n\n\tconst hasAnyComponent = Boolean(years || months || days || hours || minutes || seconds || milliseconds);\n\tif (!hasAnyComponent) return null;\n\n\tconst durationMs =\n\t\tsign *\n\t\t(years * APPROX_DAYS_IN_YEAR * MS_IN_DAY +\n\t\t\tmonths * APPROX_DAYS_IN_MONTH * MS_IN_DAY +\n\t\t\tdays * MS_IN_DAY +\n\t\t\thours * MS_IN_HOUR +\n\t\t\tminutes * MS_IN_MINUTE +\n\t\t\tseconds * MS_IN_SECOND +\n\t\t\tmilliseconds);\n\n\treturn { kind: PARSED_DATE_KIND_DURATION, source: DATE_INPUT_SOURCE_ISO_DURATION, durationMs };\n}\n\n/**\n * Перезаписывает источник, если требуется проставить контекст вызова.\n */\nfunction withSourceOverride(value: ParsedDateTimeValue, sourceOverride?: ParsedDateTimeValue[\"source\"]): ParsedDateTimeValue {\n\treturn sourceOverride ? { ...value, source: sourceOverride } : value;\n}\n\n/**\n * Парсит строку в дату.\n */\nfunction parseDateString(\n\tvalue: string,\n\tsourceOverride?: ParsedDateTimeValue[\"source\"],\n\tmode: DateParsingMode = DEFAULT_DATE_PARSING_MODE\n): ParsedDateTimeValue | null {\n\tconst zoned = parseIsoZoned(value, mode);\n\tif (zoned) return withSourceOverride(zoned, sourceOverride);\n\n\tconst localIso = parseIsoLocal(value);\n\tif (localIso) return withSourceOverride(localIso, sourceOverride);\n\n\tconst dotted = parseAbapDotted(value);\n\tif (dotted) return withSourceOverride(dotted, sourceOverride);\n\n\tconst slashed = parseSlashDate(value);\n\tif (slashed) return withSourceOverride(slashed, sourceOverride);\n\n\tconst timestamp = parseAbapTimestamp(value);\n\tif (timestamp) return withSourceOverride(timestamp, sourceOverride);\n\n\tconst compact = parseAbapCompact(value);\n\tif (compact) return withSourceOverride(compact, sourceOverride);\n\n\tconst timestampAsNumber = Number(value);\n\tif (/^-?\\d+$/.test(value) && Number.isFinite(timestampAsNumber)) {\n\t\tconst timestamp = parseTimestamp(timestampAsNumber, mode);\n\t\tif (timestamp) return withSourceOverride(timestamp, sourceOverride);\n\t}\n\n\treturn null;\n}\n\n/**\n * Экранирует литерал для безопасной подстановки в регулярное выражение.\n */\nfunction escapeRegExp(value: string): string {\n\treturn value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Преобразует двузначный год в четырёхзначный.\n *\n * Значения `00-69` трактуются как `2000-2069`,\n * значения `70-99` трактуются как `1970-1999`.\n */\nfunction resolveTwoDigitYear(year: number): number {\n\treturn year < TWO_DIGIT_YEAR_PIVOT ? CURRENT_CENTURY + year : PREVIOUS_CENTURY + year;\n}\n\n/**\n * Парсит строку по пользовательскому шаблону даты.\n *\n * Поддерживаются токены `dd`, `MM`, `yyyy`, `yy`, `HH`, `mm` и `ss`.\n */\nexport interface ParseDateByPatternOptions {\n\t/**\n\t * Точность календарной даты.\n\t */\n\tprecision?: DateFormatPrecision;\n}\n\nexport function parseDateByPattern(\n\tvalue: unknown,\n\tpattern = DATE_PATTERN_DAY_MONTH_YEAR_DOTTED,\n\toptions: ParseDateByPatternOptions = {}\n): ParsedDateValue | null {\n\tif (typeof value !== \"string\") {\n\t\treturn parseDateValue(value);\n\t}\n\n\tconst trimmed = value.trim();\n\tif (EMPTY_STRING_VALUES.has(trimmed.toLowerCase())) return null;\n\n\tconst precision = options.precision ?? DATE_FORMAT_PRECISION_DAY;\n\tconst precisionPattern = resolveDatePatternPrecision(pattern, precision);\n\tconst captureNames: string[] = [];\n\tlet cursor = 0;\n\tlet regexPattern = \"^\";\n\tlet matchPart: RegExpExecArray | null = null;\n\n\tDATE_PATTERN_TOKEN_RE.lastIndex = 0;\n\n\twhile ((matchPart = DATE_PATTERN_TOKEN_RE.exec(precisionPattern)) !== null) {\n\t\tregexPattern += escapeRegExp(precisionPattern.slice(cursor, matchPart.index));\n\t\tcaptureNames.push(matchPart[0]);\n\n\t\tif (matchPart[0] === DATE_PATTERN_TOKEN_YEAR) regexPattern += \"(\\\\d{4})\";\n\t\telse regexPattern += \"(\\\\d{2})\";\n\n\t\tcursor = matchPart.index + matchPart[0].length;\n\t}\n\n\tif (captureNames.length === 0) return null;\n\n\tregexPattern += `${escapeRegExp(precisionPattern.slice(cursor))}$`;\n\tconst regex = new RegExp(regexPattern);\n\tconst match = regex.exec(trimmed);\n\tif (!match) return null;\n\n\tlet year: number | null = null;\n\tlet month: number | null = null;\n\tlet day: number | null = null;\n\tlet hour = 0;\n\tlet minute = 0;\n\tlet second = 0;\n\n\tfor (let index = 0; index < captureNames.length; index += 1) {\n\t\tconst token = captureNames[index];\n\t\tconst rawValue = match[index + 1];\n\t\tconst numericValue = Number(rawValue);\n\t\tif (!Number.isFinite(numericValue)) return null;\n\n\t\tif (token === DATE_PATTERN_TOKEN_YEAR) year = numericValue;\n\t\tif (token === DATE_PATTERN_TOKEN_SHORT_YEAR) year = resolveTwoDigitYear(numericValue);\n\t\tif (token === DATE_PATTERN_TOKEN_MONTH) month = numericValue;\n\t\tif (token === DATE_PATTERN_TOKEN_DAY) day = numericValue;\n\t\tif (token === DATE_PATTERN_TOKEN_HOURS) hour = numericValue;\n\t\tif (token === DATE_PATTERN_TOKEN_MINUTES) minute = numericValue;\n\t\tif (token === DATE_PATTERN_TOKEN_SECONDS) second = numericValue;\n\t}\n\n\tif (!year) return null;\n\tif (precision !== DATE_FORMAT_PRECISION_YEAR && !month) return null;\n\tif (precision === DATE_FORMAT_PRECISION_DAY && !day) return null;\n\n\tconst parsed = createCalendarDate(year, month ?? 1, day ?? 1, hour, minute, second);\n\treturn parsed ? asDateTimeValue(parsed, DATE_INPUT_SOURCE_ISO_LOCAL) : null;\n}\n\nexport interface ParseDateByFormatOptions {\n\t/**\n\t * Формат по умолчанию, если входной формат не задан.\n\t */\n\tdefaultFormat?: DateFormatPattern;\n\t/**\n\t * Локаль для обратного парсинга человекочитаемых Intl-строк.\n\t */\n\tlocale?: string;\n\t/**\n\t * Точность календарной даты.\n\t */\n\tprecision?: DateFormatPrecision;\n\t/**\n\t * Опорная дата для пресетов без года, например `month-long`.\n\t */\n\treferenceDate?: Date;\n}\n\n/**\n * Возвращает набор строгих шаблонов для парсинга по имени пресета или ручному формату.\n */\nfunction getDateFormatParsePatterns(dateFormat: string, precision: DateFormatPrecision): readonly DateFormatPattern[] {\n\tconst preset = getDatePreset(dateFormat);\n\tconst presetPatterns = DATE_FORMAT_PARSE_PATTERNS[dateFormat];\n\n\tif (preset?.pattern) return [resolveDatePatternPrecision(preset.pattern, precision)];\n\tif (presetPatterns) return presetPatterns.map((pattern) => resolveDatePatternPrecision(pattern, precision));\n\tif (!preset && hasDatePatternTokens(dateFormat)) return [resolveDatePatternPrecision(dateFormat, precision)];\n\n\treturn [];\n}\n\n/**\n * Парсит календарную дату по имени пресета, style-алиасу или ручному шаблону.\n */\nexport function parseDateByFormat(value: unknown, dateFormat?: string, options: ParseDateByFormatOptions = {}): ParsedDateTimeValue | null {\n\tif (typeof value !== \"string\") {\n\t\tconst parsed = parseDateValue(value);\n\t\treturn parsed?.kind === PARSED_DATE_KIND_DATE_TIME ? parsed : null;\n\t}\n\n\tconst trimmed = value.trim();\n\tif (EMPTY_STRING_VALUES.has(trimmed.toLowerCase())) return null;\n\n\tconst precision = options.precision ?? DATE_FORMAT_PRECISION_DAY;\n\tconst resolvedFormat = resolveDateFormatName(dateFormat, options.defaultFormat ?? DATE_PRESET_NAME_DATE);\n\tfor (const pattern of getDateFormatParsePatterns(resolvedFormat, precision)) {\n\t\tconst parsedByPattern = parseDateByPattern(trimmed, pattern, { precision });\n\t\tif (parsedByPattern?.kind === PARSED_DATE_KIND_DATE_TIME) return parsedByPattern;\n\t}\n\n\tif (precision === DATE_FORMAT_PRECISION_DAY) {\n\t\tconst parsedByValue = parseDateValue(trimmed);\n\t\tif (parsedByValue?.kind === PARSED_DATE_KIND_DATE_TIME) return parsedByValue;\n\t}\n\n\tconst preset = getDatePreset(resolvedFormat);\n\tconst locale = preset?.locale ?? options.locale ?? DATE_FORMAT_DEFAULTS.locale;\n\n\tif (precision === DATE_FORMAT_PRECISION_DAY && isDayMonthPresetName(resolvedFormat)) {\n\t\tconst parsedDayMonth = parseLocalizedDayMonthString(trimmed, locale, resolveReferenceYear(options.referenceDate));\n\t\tif (parsedDayMonth) return parsedDayMonth;\n\t}\n\n\tif (precision !== DATE_FORMAT_PRECISION_YEAR && isMonthYearPresetName(resolvedFormat)) {\n\t\treturn parseLocalizedMonthString(trimmed, locale);\n\t}\n\n\treturn parseLocalizedDateString(trimmed, locale, precision);\n}\n\n/**\n * Общий механизм парсинга с явно выбранной timezone-семантикой.\n */\nfunction parseDateValueInternal(\n\tvalue: unknown,\n\t{ mode = DEFAULT_DATE_PARSING_MODE }: ParseDateValueInternalOptions = {}\n): ParsedDateValue | null {\n\tif (value == null) return null;\n\n\tif (value instanceof Date) {\n\t\tif (Number.isNaN(value.getTime())) return null;\n\t\tconst date = mode === DATE_PARSING_MODE_INSTANT ? new Date(value.getTime()) : cloneCalendarDate(value);\n\t\treturn asDateTimeValue(date, DATE_INPUT_SOURCE_DATE_OBJECT);\n\t}\n\n\tif (typeof value === \"number\") {\n\t\treturn parseTimestamp(value, mode);\n\t}\n\n\tif (typeof value !== \"string\") return null;\n\n\tconst trimmed = value.trim();\n\tif (EMPTY_STRING_VALUES.has(trimmed.toLowerCase())) return null;\n\n\tconst odataTicks = parseODataTicks(trimmed, mode);\n\tif (odataTicks) return odataTicks;\n\n\tconst odataLiteral = parseODataLiteral(trimmed, mode);\n\tif (odataLiteral) return odataLiteral;\n\n\tconst duration = parseIsoDuration(trimmed);\n\tif (duration) return duration;\n\n\treturn parseDateString(trimmed, undefined, mode);\n}\n\n/**\n * Универсально парсит вход даты/времени из `unknown`, сохраняя исторические\n * видимые календарные компоненты без применения timezone.\n */\nexport function parseDateValue(value: unknown): ParsedDateValue | null {\n\treturn parseDateValueInternal(value);\n}\n\n/**\n * Универсально парсит вход даты/времени из `unknown` как абсолютный instant.\n *\n * Явные timezone в ISO/OData и Unix timestamp преобразуются в `Date`\n * с сохранением момента времени; форматы без timezone остаются календарными.\n */\nexport function parseDateValueTZ(value: unknown): ParsedDateValue | null {\n\treturn parseDateValueInternal(value, { mode: DATE_PARSING_MODE_INSTANT });\n}\n\n/**\n * Преобразует результат парсинга к `Date`, в том числе для duration-значений.\n *\n * Для duration используется та же \"плавающая\" календарная семантика, что и для timestamp:\n * UTC-компоненты пересобираются в локальный `Date`, чтобы не появлялся timezone-сдвиг.\n */\nfunction coerceParsedDateToDate(value: ParsedDateValue | null): Date | null {\n\tif (!value) return null;\n\tif (value.kind === PARSED_DATE_KIND_DATE_TIME) return value.date;\n\n\tconst durationDate = new Date(value.durationMs);\n\tif (Number.isNaN(durationDate.getTime())) return null;\n\n\treturn cloneUtcCalendarDate(durationDate);\n}\n\n/**\n * Универсально парсит вход и всегда возвращает `Date | null`.\n */\nexport function parseDate(value: unknown): Date | null {\n\treturn coerceParsedDateToDate(parseDateValue(value));\n}\n\n/**\n * Универсально парсит вход с учётом timezone и возвращает `Date | null`.\n */\nexport function parseDateTZ(value: unknown): Date | null {\n\treturn coerceParsedDateToDate(parseDateValueTZ(value));\n}\n","import {\n\ttype BaseMetaType,\n\ttype BooleanMetaType,\n\ttype DateMetaType,\n\ttype IntegerMetaType,\n\ttype NumericMetaType,\n\ttype ScalarMetaType\n} from \"./metadataTypes\";\nimport {\n\tBASE_META_TYPE_DATE,\n\tBASE_META_TYPE_NUMBER,\n\tSCALAR_TYPE_BOOLEAN,\n\tSCALAR_TYPE_BYTE,\n\tSCALAR_TYPE_DATETIME,\n\tSCALAR_TYPE_DATETIME_OFFSET,\n\tSCALAR_TYPE_DECIMAL,\n\tSCALAR_TYPE_DOUBLE,\n\tSCALAR_TYPE_FLOAT,\n\tSCALAR_TYPE_INT,\n\tSCALAR_TYPE_LONG,\n\tSCALAR_TYPE_STRING,\n\tSCALAR_TYPE_TIME\n} from \"./scalarTypeConstants\";\n\n/** Определяет базовый тип поля для UI и Excel без инициализации протокольных модулей. */\nexport function getBaseTypeFromScalarType<T extends ScalarMetaType>(type: T): BaseMetaType {\n\tif (isScalarBooleanType(type)) return SCALAR_TYPE_BOOLEAN;\n\tif (isScalarNumericType(type)) return BASE_META_TYPE_NUMBER;\n\tif (isScalarDateType(type)) return BASE_META_TYPE_DATE;\n\treturn SCALAR_TYPE_STRING;\n}\n\nexport function isScalarBooleanType(type: ScalarMetaType | undefined): type is BooleanMetaType {\n\treturn type === SCALAR_TYPE_BOOLEAN;\n}\n\nexport function isScalarNumericType(type: ScalarMetaType | undefined): type is NumericMetaType {\n\treturn (\n\t\ttype === SCALAR_TYPE_BYTE ||\n\t\ttype === SCALAR_TYPE_INT ||\n\t\ttype === SCALAR_TYPE_LONG ||\n\t\ttype === SCALAR_TYPE_FLOAT ||\n\t\ttype === SCALAR_TYPE_DECIMAL ||\n\t\ttype === SCALAR_TYPE_DOUBLE\n\t);\n}\n\nexport function isScalarIntegerType(type: ScalarMetaType | undefined): type is IntegerMetaType {\n\treturn type === SCALAR_TYPE_BYTE || type === SCALAR_TYPE_INT || type === SCALAR_TYPE_LONG;\n}\n\nexport function isScalarDateType(type: ScalarMetaType | undefined): type is DateMetaType {\n\treturn type === SCALAR_TYPE_DATETIME || type === SCALAR_TYPE_DATETIME_OFFSET || type === SCALAR_TYPE_TIME;\n}\n"],"mappings":";;AAGA,IAAa,IAA6B,MCDpC,IAAkC;AAMxC,SAAgB,EAAe,GAAgC;CAC9D,IAAI,OAAO,KAAM,UAAU,OAAO,OAAO,SAAS,CAAC,IAAI,IAAI,KAAA;CAC3D,IAAI,OAAO,KAAM,UAAU;CAE3B,IAAM,IAAU,EAAE,KAAK;CACvB,IAAI,CAAC,GAAS;CAEd,IAAM,IAAS,OAAO,CAAO;CAC7B,IAAI,OAAO,SAAS,CAAM,GAAG,OAAO;CAIpC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;EACxC,IAAM,IAAI,EAAQ,WAAW,CAAC;EAE7B,MAAA,MACA,MAAA,OACA,MAAA,QACA,MAAM,MAGP,KAAK,EAAQ;CACd;CAEA,IAAM,IAAW,EAAE,QAAQ,GAAG,MAAM,IAC9B,IAAS,EAAE,QAAQ,GAAG,MAAM;CAElC,AAAI,KAAY,IACf,IAAI,EAAE,QAAQ,MAAM,EAAE,IACZ,MACV,IAAI,EAAE,QAAQ,MAAM,GAAG;CAGxB,IAAM,IAAI,OAAO,CAAC;CAClB,OAAO,OAAO,SAAS,CAAC,IAAI,IAAI,KAAA;AACjC;AAEA,SAAgB,EAAY,GAAoB;CAC/C,OAAO,EAAe,CAAC,KAAK;AAC7B;AAEA,SAAgB,EAAgB,GAAyB;CACxD,IAAM,IAAkB,EAAe,CAAK;CAK5C,OAJI,IACI,IAAkB,IAGnB;AACR;AAKA,SAAgB,EAAkB,GAAoC;CACrE,IAAM,IAAkB,EAAe,CAAK;CACxC,YAAoB,KAAA,KAAa,CAAC,OAAO,UAAU,CAAe,KAAK,KAAmB,IAI9F,OAAO;AACR;;;AC9DA,IAAa,IAAmB,MACnB,IAAe,KACf,IAAe,KACf,IAAa,MACb,IAAY,OCTZ,KAA8B,SAC9B,KAA6B,QAC7B,IAA0B,SAC1B,KAA2B,UAC3B,KAAyB,QACzB,IAA2B,WAC3B,IAAyB,WAEzB,KAAsB,SAGtB,IAAwB,SACxB,IAAuB,QACvB,KAAuB,SCdvB,KAA6B,aAC7B,KAA4B,YAC5B,KAAgC,eAChC,KAA8B,aAC9B,KAAgC,eAChC,KAAkC,iBAClC,KAAiC,gBACjC,KAAmC,kBACnC,KAAgC,eAChC,KAA+B,cAC/B,IAA8B,aAC9B,KAA8B,aAC9B,KAAiC,gBCZjC,IAA0B,QAO1B,KAAqC,cACrC,KAA4B,SAC5B,KAA4B,YAC5B,KAAyB,YACzB,KAA8B,kBAC9B,KAAwB,cACxB,KAA6B,uBCb7B,IAAwB,QACxB,IAA8B,cAC9B,IAA+B,eAC/B,IAA6B,aAC7B,IAA+B,eAC/B,IAAgC,gBAChC,KAA8B,cAC9B,IAAqC,qBACrC,IAAmC,mBACnC,IAA4B,YAC5B,KAAoC,oBACpC,KAAkC,kBAClC,KAAmC,mBACnC,KAAiC,iBACjC,KAAwB,QACxB,KAAgC,gBAChC,KAA8B,cAC9B,KAA+B,eAC/B,KAA6B,aAC7B,KAA8B,cAC9B,KAAkC,kBAClC,KAAiC,iBACjC,KAA6B,aAC7B,KAA8B,cAC9B,IAA6B,aCT7B,IAA2B,OAAO,OAAO;;;CAGrD;;AAED,CAAU,GAKG,IAA2B,OAAO,OAAO;;;;AAItD,CAAU,GAKG,IAAsB,OAAO,OAAO,CAAC,GAAG,GAA0B,GAAG,CAAwB,CAAU,GAKvG,IAAwB,6BAE/B,KAAyB,IAAI,IAAY,CAAmB,GAC5D,KAA4F,OAAO,OAAO;CAC/G,KAAK,IAAI,IAAI,CAAmB;CAChC,uBAAO,IAAI,IAAI;;EAA2B;;CAAsD,CAAC;CACjG,sBAAM,IAAI,IAAI,CAAC,GAAA,IAAsD,CAAC;AACvE,CAAC;AAKD,SAAgB,GAAmB,GAAwB;CAC1D,OAAO,GAAuB,IAAI,CAAK;AACxC;AAKA,SAAgB,GAAyB,GAAiB,GAAoC;CAC7F,OAAO,EAAO,MAAM,MAAU,EAAQ,SAAS,CAAK,CAAC;AACtD;AAKA,SAAgB,GAAqB,GAA0B;CAE9D,OADA,EAAsB,YAAY,GAC3B,EAAsB,KAAK,CAAO;AAC1C;AAKA,SAAgB,GAA8B,GAAqD;CAClG,OAAO,GAA8B;AACtC;AAKA,SAAgB,EAA4B,GAAiB,GAAwC;CACpG,IAAI,MAAA,OAAyC,OAAO;CAEpD,IAAM,IAAgB,GAA8B,CAAS,GACvD,IAA2B,CAAC,GAC9B,IAAiB,IACjB,IAAe,IACf,IAAiB,GACjB,IAAS,GACT;CAGJ,KADA,EAAsB,YAAY,GAC1B,IAAQ,EAAsB,KAAK,CAAO,IAAI;EACrD,IAAM,IAAU,EAAQ,MAAM,GAAQ,EAAM,KAAK,GAC3C,IAAQ,EAAM;EAYpB,AAVI,MAAc,KAAkB,IAEhC,EAAc,IAAI,CAAK,MACtB,KAAc,EAAe,KAAK,CAAc,GACpD,EAAe,KAAK,CAAK,GACzB,IAAiB,IACjB,IAAe,IACf,KAAkB,IAGnB,IAAS,EAAM,QAAQ,EAAM;CAC9B;CAGA,OADI,MAAmB,IAAU,IAC1B,EAAe,KAAK,EAAE;AAC9B;;;AC1BA,IAAM,IAAgB,OAAO,OAAO;CAAC;CAAyB;CAA0B;AAAsB,CAAU,GAClH,KAAoB,OAAO,OAAO;;CAA4B;CAA6B;AAA0B,CAAU,GAKxH,IAAqH;CACjI,QAAQ;CACR,aAAa;EAAE,KAAK;EAA0B,OAAO;EAA0B,MAAM;CAAuB;CAC5G,iBAAiB;AAClB,GAKa,KAA4B,OAAO,OAAO;CACtD,MAAM;CACN,WAAW;CACX,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,aAAa;CACb,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,UAAU;CACV,iBAAiB;CACjB,eAAe;CACf,gBAAgB;CAChB,cAAc;CACd,MAAM;CACN,aAAa;CACb,WAAW;CACX,YAAY;CACZ,UAAU;CACV,WAAW;CACX,eAAe;CACf,cAAc;CACd,UAAU;CACV,WAAW;CACX,UAAU;AACX,CAAC,GAKY,KAA4E,OAAO,OAAO;CACtG,OAAO;CACP,QAAQ;CACR,MAAM;AACP,CAAC,GAEK,qBAAqB,IAAI,IAA8B,GAKvD,KAA4C;CACjD;EACC,MAAM;EACN,aAAa;GAAE,KAAK;GAA0B,OAAO;GAA0B,MAAM;EAAuB;CAC7G;CACA;EACC,MAAM;EACN,iBAAiB;GAAE,KAAK;GAA0B,OAAO;GAA0B,MAAM;EAAuB;EAChH,iBAAiB;GAAE,MAAM;GAA0B,QAAQ;GAA0B,WAAA;EAAmC;EACxH,YAAY;CACb;CACA;EACC,MAAM;EACN,iBAAiB;GAAE,KAAK;GAA0B,OAAO;GAA0B,MAAM;EAAuB;EAChH,iBAAiB;GAChB,MAAM;GACN,QAAQ;GACR,QAAQ;GACR,WAAA;EACD;EACA,YAAY;CACb;CACA;EACC,MAAM;EACN,aAAa;GAAE,MAAM;GAA0B,QAAQ;GAA0B,WAAA;EAAmC;EACpH,iBAAiB;CAClB;CACA;EACC,MAAM;EACN,aAAa;GACZ,MAAM;GACN,QAAQ;GACR,QAAQ;GACR,WAAA;EACD;EACA,iBAAiB;CAClB;CACA,GAAG,EAAc,KAAK,OAAW;EAChC,MAAM,QAAQ;EACd,aAAa,GAAwB,CAAK;CAC3C,EAAE;CACF,GAAG,EAAc,KAAK,OAAW;EAChC,MAAM,SAAS;EACf,aAAa,GAAyB,CAAK;CAC5C,EAAE;CACF;EACC,MAAM;EACN,aAAa;GAAE,OAAO;GAAuB,MAAM;EAAuB;CAC3E;CACA;EACC,MAAM;EACN,aAAa;GAAE,OAAO;GAAsB,MAAM;EAAuB;CAC1E;CACA,GAAG,EAAc,KAAK,OAAW;EAChC,MAAM,QAAQ;EACd,aAAa,GAAwB,CAAK;EAC1C,iBAAiB,MAAA,UAAoC,KAA4B;CAClF,EAAE;CACF,GAAG,EAAc,KAAK,OAAW;EAChC,MAAM,YAAY;EAClB,iBAAiB,GAAwB,CAAK;EAC9C,iBAAiB,GAAwB,CAAK;EAC9C,YAAY;CACb,EAAE;CACF;EAAE,MAAM;EAA6B,SAAS;CAAsB;CACpE;EAAE,MAAM;EAAiC,SAAS;CAA2B;CAC7E;EAAE,MAAM;EAAgC,SAAS;CAA4B;CAC7E;EAAE,MAAM;EAA4B,SAAS;CAAuB;CACpE;EAAE,MAAM;EAA6B,SAAS;CAAS;CACvD;EAAE,MAAM;EAA4B,SAAS;CAAwB;AACtE,GAKM,qBAA4G,IAAI,IAAI,CACzH,CAAC,GAAoC,CAAqB,GAC1D,CAAC,GAAkC,CAAoB,CACxD,CAAC,GAKK,oBAAW,IAAI,IAAsC;AAK3D,SAAS,EAAY,GAAe,IAAO,GAAW;CACrD,OAAO,OAAO,CAAK,CAAC,CAAC,SAAS,GAAM,GAAG;AACxC;AAKA,SAAS,GACR,GACA,IAAA,OAC6B;CAa7B,OAZI,MAAA,SAAiD,EAAE,MAAM,EAAuB,IAEhF,MAAA,UACC,MAAA,UAA0C;EAAE,OAAO;EAA0B,MAAM;CAAuB,IAC1G,MAAA,WAA2C;EAAE,OAAO;EAAuB,MAAM;CAAuB,IACrG;EAAE,OAAO;EAAsB,MAAM;CAAuB,IAGhE,MAAA,UACI;EAAE,KAAK;EAA0B,OAAO;EAA0B,MAAM;CAAuB,IACnG,MAAA,WACI;EAAE,KAAK;EAAwB,OAAO;EAAuB,MAAM;CAAuB,IAC3F;EAAE,KAAK;EAAwB,OAAO;EAAsB,MAAM;CAAuB;AACjG;AAQA,SAAS,GAAyB,GAAoD;CAGrF,OAFI,MAAA,UAA0C;EAAE,KAAK;EAA0B,OAAO;CAAyB,IAC3G,MAAA,WAA2C;EAAE,KAAK;EAAwB,OAAO;CAAsB,IACpG;EAAE,KAAK;EAAwB,OAAO;CAAqB;AACnE;AASA,SAAS,GAAwB,GAAoD;CAGpF,OAFI,MAAA,UACI;EAAE,MAAM;EAA0B,QAAQ;EAA0B,WAAA;CAAmC,IACxG;EACN,MAAM;EACN,QAAQ;EACR,QAAQ;EACR,WAAA;CACD;AACD;AAMA,SAAS,GAAoB,GAAiE;CAC7F,IAAM,EAAE,aAAU,iBAAc,GAAG,MAAgB;CAGnD,OAAO;AACR;AAKA,SAAS,GAAkB,GAA8C;CACxE,OAAO,GAAQ,EAAQ,aAAa,EAAQ,QAAQ,EAAQ,SAAS,EAAQ;AAC9E;AAKA,SAAS,GAAgC,GAAqC,GAA4D;CACzI,IAAM,IAAc,GAAoB,CAAO;CAe/C,OAdI,MAAA,SAA2C,CAAC,GAAkB,CAAW,IAAU,IAEnF,EAAY,YAKR,GAHN,EAAY,cAAA,WAAyC,EAAY,cAAA,WAC9D,EAAY,YACZ,IACkC,CAAS,IAG5C,MAAA,SACI,EAAE,MAAM,EAAY,QAAA,UAA+B,IAGpD;EACN,OAAO,EAAY,SAAA;EACnB,MAAM,EAAY,QAAA;CACnB;AACD;AAQA,SAAS,GAAoB,GAAgB,GAA4D;CACxG,IAAM,IAAc,GAAoB,CAAO,GACzC,oBAAsB,IAAI,IAA8C;CAE9E,IAAI,EAAY,WAAW;EAC1B,IAAM,IAAc,GACnB,EAAY,cAAA,UAAwC,IAA0B,EAC/E;EAEA,IAAI,EAAY,WAAW;GAC1B,IAAM,IAAgB,IAAI,KAAK,eAAe,GAAQ,EAAE,WAAW,EAAY,UAAU,CAAC,GACpF,IAAgB,IAAI,KAAK,eAAe,GAAQ,CAAW;GACjE,QAAQ,GAAM,IAAA,UAA0C;IACvD,IAAI,MAAA,OAAyC,OAAO,GAAG,EAAc,OAAO,CAAI,EAAE,IAAI,EAAc,OAAO,CAAI;IAE/G,IAAM,IAAmB,GAAgC,EAAE,WAAW,EAAY,UAAU,GAAG,CAAS,GACpG,IAAqB,EAAoB,IAAI,CAAS;IAM1D,OALK,MACJ,IAAqB,IAAI,KAAK,eAAe,GAAQ,CAAgB,GACrE,EAAoB,IAAI,GAAW,CAAkB,IAG/C,EAAmB,OAAO,CAAI;GACtC;EACD;EAEA,OAAO,IAAI,KAAK,eAAe,GAAQ,CAAW,CAAC,CAAC;CACrD;CAEA,IAAM,IAAmB,IAAI,KAAK,eAAe,GAAQ,CAAW;CACpE,QAAQ,GAAM,IAAA,UAA0C;EACvD,IAAI,MAAA,OAAyC,OAAO,EAAiB,OAAO,CAAI;EAEhF,IAAI,IAAqB,EAAoB,IAAI,CAAS;EAM1D,OALK,MACJ,IAAqB,IAAI,KAAK,eAAe,GAAQ,GAAgC,GAAa,CAAS,CAAC,GAC5G,EAAoB,IAAI,GAAW,CAAkB,IAG/C,EAAmB,OAAO,CAAI;CACtC;AACD;AAKA,SAAS,GAAqB,GAAe,GAAoB;CAChE,IAAM,IAAW,OAAO,EAAK,YAAY,CAAC;CAE1C,QAAQ,GAAR;EACC,KAAK,GACJ,OAAO;EACR,KAAA,MACC,OAAO,EAAS,MAAM,EAAE;EACzB,KAAA,MACC,OAAO,EAAY,EAAK,SAAS,IAAI,CAAC;EACvC,KAAA,MACC,OAAO,EAAY,EAAK,QAAQ,CAAC;EAClC,KAAA,MACC,OAAO,EAAY,EAAK,SAAS,CAAC;EACnC,KAAA,MACC,OAAO,EAAY,EAAK,WAAW,CAAC;EACrC,KAAA,MACC,OAAO,EAAY,EAAK,WAAW,CAAC;EACrC,SACC,OAAO;CACT;AACD;AAKA,SAAS,GAA6B,GAAwC;CAC7E,QAAQ,GAAR;EACC,KAAK,IACJ,QAAQ,MAAS,GAAG,EAAK,YAAY,IAAI,EAAY,EAAK,SAAS,IAAI,CAAC,IAAI,EAAY,EAAK,QAAQ,CAAC;EACvG,KAAK,IACJ,QAAQ,MACP,GAAG,EAAK,YAAY,IAAI,EAAY,EAAK,SAAS,IAAI,CAAC,IAAI,EAAY,EAAK,QAAQ,CAAC,IAAI,EAAY,EAAK,SAAS,CAAC,IAAI,EACvH,EAAK,WAAW,CACjB,IAAI,EAAY,EAAK,WAAW,CAAC;EACnC,KAAK,IACJ,QAAQ,MAAS,GAAG,EAAK,YAAY,EAAE,GAAG,EAAY,EAAK,SAAS,IAAI,CAAC,EAAE,GAAG,EAAY,EAAK,QAAQ,CAAC;EACzG,KAAK,IACJ,QAAQ,MACP,GAAG,EAAK,YAAY,EAAE,GAAG,EAAY,EAAK,SAAS,IAAI,CAAC,EAAE,GAAG,EAAY,EAAK,QAAQ,CAAC,EAAE,GAAG,EAAY,EAAK,SAAS,CAAC,EAAE,GAAG,EAC3H,EAAK,WAAW,CACjB,EAAE,GAAG,EAAY,EAAK,WAAW,CAAC;EACpC,SACC,OAAO,GAA+B,CAAO;CAC/C;AACD;AAKA,SAAS,GAAwB,GAAwC;CACxE,IAAM,oBAAsB,IAAI,IAAgD;CAEhF,QAAQ,GAAM,IAAA,UAA0C;EACvD,IAAI,IAAY,EAAoB,IAAI,CAAS;EAMjD,OALK,MACJ,IAAY,GAA6B,EAA4B,GAAS,CAAS,CAAC,GACxF,EAAoB,IAAI,GAAW,CAAS,IAGtC,EAAU,GAAA,KAA+B;CACjD;AACD;AAKA,SAAS,GAA+B,GAAwC;CAC/E,IAAM,IAAqB,CAAC,GACxB,IAAY,GACZ;CAGJ,KADA,EAAsB,YAAY,GAC1B,IAAQ,EAAsB,KAAK,CAAO,IAGjD,AAFI,EAAM,QAAQ,KAAW,EAAS,KAAK,EAAQ,MAAM,GAAW,EAAM,KAAK,CAAC,GAChF,EAAS,KAAK,EAAM,EAAE,GACtB,IAAY,EAAM,QAAQ,EAAM,EAAE,CAAC;CAIpC,OAFI,IAAY,EAAQ,UAAQ,EAAS,KAAK,EAAQ,MAAM,CAAS,CAAC,IAE9D,MAAS;EAChB,IAAI,IAAS;EACb,KAAK,IAAM,KAAW,GACrB,KAAU,GAAmB,CAAO,IAAI,GAAqB,GAAS,CAAI,IAAI;EAE/E,OAAO;CACR;AACD;AAKA,SAAS,GAAwB,GAAoB,GAAiB,GAA0B;CAE/F,IADI,GAAyB,GAAS,CAAwB,KAC1D,CAAC,GAAyB,GAAS,CAAwB,GAAG,OAAO;CAEzE,IAAM,IAAO,IAAa,IAAI,MAAM,IAC9B,IAAkB,KAAK,MAAM,KAAK,IAAI,CAAU,IAAI,CAAY,GAChE,IAAQ,KAAK,MAAM,IAAkB,CAAgB,GACrD,IAAU,KAAK,MAAO,IAAkB,IAAA,EAAsC,GAC9E,IAAU,IAAA;CAKhB,OAHI,MAAA,UAA8C,GAAG,IAAO,EAAY,CAAK,EAAE,GAAG,EAAY,CAAO,MACjG,MAAA,aAA8C,GAAG,IAAO,EAAY,CAAK,EAAE,GAAG,EAAY,CAAO,EAAE,GAAG,EAAY,CAAO,MAG5H,IACA,EACE,WAAA,MAAqC,EAAY,CAAK,CAAC,CAAC,CACxD,WAAA,MAAuC,EAAY,CAAO,CAAC,CAAC,CAC5D,WAAA,MAAuC,EAAY,CAAO,CAAC;AAE/D;AAKA,SAAgB,GAAkB,GAA6E;CAC9G,IAAM,IAA2B;EAAE,GAAG;EAAsB,GAAG;CAAO,GAChE,IAAiB,GAAsB,CAAM,GAC7C,IAAkB,EAAO,mBAAmB,EAAO,SACnD,IAA2C;EAAE,GAAG;EAAQ;CAAe;CAM7E,OAJI,MACH,EAAe,kBAAkB,GAAY,MAAa,GAAwB,GAAY,GAAiB,CAAQ,IAGjH;AACR;AAKA,SAAS,GAAsB,GAAiD;CAC/E,IAAI,EAAO,SAAS,OAAO,GAAwB,EAAO,OAAO;CAEjE,IAAI,EAAO,mBAAmB,EAAO,iBAAiB;EACrD,IAAM,IAAgB,GAAoB,EAAO,QAAQ,EAAO,eAAe,GACzE,IAAgB,GAAoB,EAAO,QAAQ,EAAO,eAAe,GACzE,IAAS,EAAO,cAAc;EAEpC,QAAQ,GAAM,IAAA,UACT,MAAA,QACG,GAAG,EAAc,CAAI,IAAI,IAAS,EAAc,CAAI,MADP,EAAc,GAAM,CAAS;CAGnF;CAEA,OAAO,GAAoB,EAAO,QAAQ,EAAO,eAAe,EAAqB,WAAW;AACjG;AASA,SAAS,GACR,GACA,GACwB;CAGxB,IAAM,IAAqB,IAAI,KAAK,eACnC,GACA,MAAA,UACG;EAAE,KAAK;EAAwB,OAAO;EAAY,MAAM;CAAuB,IAC/E;EAAE,OAAO;EAAY,MAAM;CAAuB,CACtD,GACM,IAA2B,IAAI,KAAK,eAAe,GAAQ,EAAE,OAAO,EAAqB,CAAC,GAC1F,IAAgB,IAAI,KAAK,eAAe,GAAQ,EAAE,MAAM,EAAuB,CAAC;CAEtF,QAAQ,GAAM,IAAA,UAA0C;EAEvD,IAAM,KADY,MAAA,SAA2C,IAAgB,EAAA,CACrD,cAAc,CAAI,GACpC,IAAO,EAAM,MAAM,MAAS,EAAK,SAAA,MAA4B,CAAC,EAAE,SAAS;EAC/E,IAAI,MAAA,QAA0C,OAAO;EAErD,IAAM,IAAkB,EAAM,MAAM,MAAS,EAAK,SAAA,OAA6B,CAAC,EAAE,SAAS;EAS3F,OAAO,GALN,MAAA,WAAwC,CAAC,EAAgB,SAAS,GAAG,IACjE,EAAyB,cAAc,CAAI,CAAC,CAAC,MAAM,MAAS,EAAK,SAAA,OAA6B,CAAC,EAAE,SACnG,IACC,EAEY,GAAG;CACpB;AACD;AAKA,SAAS,GAAyB,GAA0D;CAC3F,IAAM,IAAS,GAAkB,CAAM,GACjC,IAAiB,GAAyB,IAAI,EAAO,IAAI;CAG/D,OAFK,IAEE;EACN,GAAG;EACH,gBAAgB,GAAyB,EAAO,QAAQ,CAAc;CACvE,IAL4B;AAM7B;AAKA,SAAS,KAAoB;CAC5B,KAAK,IAAM,KAAU,IACpB,EAAS,IAAI,EAAO,MAAM,GAAyB,CAAM,CAAC;AAE5D;AAEA,GAAY;AAKZ,SAAgB,EAAc,GAA4C;CACzE,OAAO,EAAS,IAAI,CAAI;AACzB;AAKA,SAAgB,GAAsB,GAAoD;CACzF,OAAO,EAAS,IAAI,CAAI;AACzB;AAKA,SAAgB,KAA+B;CAC9C,OAAO,MAAM,KAAK,EAAS,KAAK,CAAC;AAClC;AAKA,SAAgB,GAAkB,GAAyC;CAC1E,OAAO,EAAc,SAAS,CAAwB;AACvD;AAKA,SAAgB,GAAsB,GAA6C;CAClF,OAAO,GAAkB,SAAS,CAA4B;AAC/D;AAKA,SAAgB,GAAsB,GAAqB,IAAwB,GAA+B;CACjH,IAAM,IAAmB,GAAY,KAAK;CAG1C,OAFK,IAEE,GAAkB,CAAgB,IAAI,GAA+B,KAAoB,IAFlE;AAG/B;AAKA,SAAS,GAAwB,GAAiB,GAAoB,GAAgB,GAA2C;CAChI,IAAM,IAAW,GAAG,EAAW,QAAQ,EAAO,QAAQ,EAAgB,QAAQ,KACxE,IAAe,GAAmB,IAAI,CAAQ;CACpD,IAAI,GAAc,OAAO;CAEzB,IAAM,IAAS;EACd,MAAM,GAAG,EAAW,GAAG;EACvB;EACA;EACA;CACD;CAGA,OADA,GAAmB,IAAI,GAAU,CAAM,GAChC;AACR;AAwBA,SAAgB,GACf,GACA,EACC,mBAAgB,GAChB,uBAAoB,oBACpB,YAAS,IACT,qBAAkB,OACiB,CAAC,GACT;CAC5B,IAAM,IAAiB,GAAsB,GAAY,CAAa;CAGtE,OAFI,EAAc,CAAc,IAAU,IAEnC,GAAwB,GAAgB,GAAmB,GAAQ,CAAe;AAC1F;AAKA,SAAgB,GAAmB,GAAkD;CACpF,IAAM,IAAS,GAAkB,CAAM;CAEvC,OADA,EAAS,IAAI,EAAO,MAAM,CAAM,GACzB;AACR;AAKA,SAAgB,KAAyB;CAExC,AADA,EAAS,MAAM,GACf,GAAY;AACb;;;AC9oBA,IAAM,KAA6B,YAC7B,IAA4B,WAC5B,KAAmC,cACnC,KAA4B,MAC5B,IAAqB,GACrB,KAAmB,MACnB,KAAkB,KAClB,IAAuB,GACvB,IAAwB,GACxB,KAAsB,GACtB,KAAuB,IACvB,KAAyB,IACzB,KAAyB,IAKzB,KAAiB,qCAKjB,KAAmB,sCAKnB,KAAe,uFAKf,KAAe,gCAKf,KAAkB,WAMlB,KAAoB,aAKpB,KAAiB,+BAKjB,KAAgB,+BAKhB,KAAkB,kGAKlB,oBAAsB,IAAI,IAAI;CAAC;CAAI;CAAQ;AAAW,CAAC,GAKvD,KAAuB,IACvB,KAAsB,KACtB,KAAuB,IAoBvB,IAA6C,IAK7C,KAAqF,OAAO,OAAO;EACvG,IAAwB,OAAO,OAAO,CAAC,EAAkC,CAAU;EACnF,IAA8B,OAAO,OAAO,CAAC,EAAkC,CAAU;EACzF,IAA4B,OAAO,OAAO,CAAC,kBAAkB,CAAU;EACvE,KAAoC,OAAO,OAAO,CAAC,qBAAqB,CAAU;EAClF,KAAkC,OAAO,OAAO,CAAC,mBAAmB,CAAU;AAChF,CAAC,GAKK,KAAoB,kGAIpB,KAAuB,2BAIvB,KAAyB,+BACzB,KAAqB,8CACrB,KAAoB,gCAEpB,qBAA2B,IAAI,IAAyC,GACxE,qBAAyB,IAAI,IAAY;CAAC;CAA8B;CAA+B;AAA2B,CAAC,GACnI,qBAA0B,IAAI,IAAY,CAAC,GAAoC,CAAgC,CAAC;AAKtH,SAAS,EAAmB,GAAc,GAAe,GAAa,IAAO,GAAG,IAAS,GAAG,IAAS,GAAG,IAAc,GAAgB;CACrI,IAAM,IAAS,IAAI,KAAK,GAAM,IAAQ,GAAG,GAAK,GAAM,GAAQ,GAAQ,CAAW;CAS/E,OAPC,EAAO,YAAY,MAAM,KACzB,EAAO,SAAS,MAAM,IAAQ,KAC9B,EAAO,QAAQ,MAAM,KACrB,EAAO,SAAS,MAAM,KACtB,EAAO,WAAW,MAAM,KACxB,EAAO,WAAW,MAAM,IAER,IAAS;AAC3B;AAKA,SAAS,EAA4B,GAAmB,GAAwB;CAC/E,OAAO,EAAU,kBAAkB,CAAM,CAAC,CAAC,QAAQ,OAAO,EAAE;AAC7D;AAKA,SAAS,GAAsB,GAAiC,GAAmB,GAAe,GAAsB;CACvH,EAAW,IAAI,EAA4B,GAAW,CAAM,GAAG,CAAK;AACrE;AAKA,SAAS,GACR,GACA,GACA,GACA,GACA,GACO;CACP,IAAM,IAAY,EAAU,cAAc,CAAI,CAAC,CAAC,MAAM,MAAS,EAAK,SAAS,EAAoB;CACjG,AAAI,KAAW,GAAsB,GAAY,EAAU,OAAO,GAAO,CAAM;AAChF;AAKA,SAAS,GAAuB,GAA6C;CAC5E,IAAM,IAAc,GAAyB,IAAI,CAAM;CACvD,IAAI,GAAa,OAAO;CAExB,IAAM,oBAAa,IAAI,IAAoB,GACrC,IAAiB,IAAI,KAAK,eAAe,GAAQ,EAAE,OAAO,EAAsB,CAAC,GACjF,IAAgB,IAAI,KAAK,eAAe,GAAQ,EAAE,OAAO,EAAqB,CAAC,GAC/E,IAAqB,IAAI,KAAK,eAAe,GAAQ;EAC1D,KAAK;EACL,OAAO;EACP,MAAM;CACP,CAAC,GACK,IAAoB,IAAI,KAAK,eAAe,GAAQ;EACzD,KAAK;EACL,OAAO;EACP,MAAM;CACP,CAAC;CAED,KAAK,IAAI,IAAQ,GAAG,IAAA,IAAkC,KAAS,GAAG;EACjE,IAAM,IAAO,IAAI,KAAK,IAA2B,GAAO,CAAC;EAIzD,AAHA,GAAsB,GAAY,EAAe,OAAO,CAAI,GAAG,GAAO,CAAM,GAC5E,GAAsB,GAAY,EAAc,OAAO,CAAI,GAAG,GAAO,CAAM,GAC3E,GAAsB,GAAY,GAAoB,GAAM,GAAO,CAAM,GACzE,GAAsB,GAAY,GAAmB,GAAM,GAAO,CAAM;CACzE;CAGA,OADA,GAAyB,IAAI,GAAQ,CAAU,GACxC;AACR;AAKA,SAAS,GAAwB,GAAe,GAA4C;CAC3F,IAAM,IAAQ,GAAkB,KAAK,EAAM,KAAK,CAAC;CACjD,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAM,OAAO,EAAM,EAAE,GACrB,IAAa,GAAuB,CAAM,CAAC,CAAC,IAAI,EAA4B,EAAM,IAAI,CAAM,CAAC,GAC7F,IAAO,OAAO,EAAM,EAAE,GACtB,IAAO,OAAO,EAAM,MAAM,CAAC,GAC3B,IAAS,OAAO,EAAM,MAAM,CAAC,GAC7B,IAAS,OAAO,EAAM,MAAM,CAAC;CAGnC,IADI,MAAe,KAAA,KACf,CAAC,OAAO,SAAS,CAAG,KAAK,CAAC,OAAO,SAAS,CAAI,KAAK,CAAC,OAAO,SAAS,CAAI,KAAK,CAAC,OAAO,SAAS,CAAM,KAAK,CAAC,OAAO,SAAS,CAAM,GACnI,OAAO;CAGR,IAAM,IAAS,EAAmB,GAAM,IAAa,GAAG,GAAK,GAAM,GAAQ,CAAM;CACjF,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAKA,SAAS,GAA6B,GAAe,GAAgB,GAA0C;CAC9G,IAAM,IAAe,GAAqB,KAAK,EAAM,KAAK,CAAC;CAC3D,IAAI,GAAc;EACjB,IAAM,IAAM,OAAO,EAAa,EAAE,GAE5B,IAAS,EAAmB,GADpB,OAAO,EAAa,EACM,GAAO,CAAG;EAElD,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;CACxE;CAEA,IAAM,IAAQ,GAAuB,KAAK,EAAM,KAAK,CAAC;CACtD,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAM,OAAO,EAAM,EAAE,GACrB,IAAa,GAAuB,CAAM,CAAC,CAAC,IAAI,EAA4B,EAAM,IAAI,CAAM,CAAC;CAEnG,IAAI,MAAe,KAAA,KAAa,CAAC,OAAO,SAAS,CAAG,GACnD,OAAO;CAGR,IAAM,IAAS,EAAmB,GAAM,IAAa,GAAG,CAAG;CAC3D,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAKA,SAAS,GAA0B,GAAe,GAA4C;CAC7F,IAAM,IAAQ,GAAmB,KAAK,EAAM,KAAK,CAAC;CAClD,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAa,GAAuB,CAAM,CAAC,CAAC,IAAI,EAA4B,EAAM,IAAI,CAAM,CAAC,GAC7F,IAAO,OAAO,EAAM,EAAE;CAE5B,IAAI,MAAe,KAAA,KAAa,CAAC,OAAO,SAAS,CAAI,GAAG,OAAO;CAE/D,IAAM,IAAS,EAAmB,GAAM,IAAa,GAAG,CAAC;CACzD,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAKA,SAAS,GAAyB,GAA2C;CAC5E,IAAM,IAAQ,GAAkB,KAAK,EAAM,KAAK,CAAC;CACjD,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAO,OAAO,EAAM,EAAE;CAC5B,IAAI,CAAC,OAAO,SAAS,CAAI,GAAG,OAAO;CAEnC,IAAM,IAAS,EAAmB,GAAM,GAAG,CAAC;CAC5C,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAKA,SAAS,GAAyB,GAAe,GAAgB,GAA4D;CAI5H,OAHI,MAAA,SAAiD,GAAyB,CAAK,IAC/E,MAAA,UAAkD,GAA0B,GAAO,CAAM,IAEtF,GAAwB,GAAO,CAAM;AAC7C;AAKA,SAAS,GAAqB,GAA6B;CAC1D,OAAO,GAAuB,IAAI,CAAU;AAC7C;AAKA,SAAS,GAAsB,GAA6B;CAC3D,OAAO,GAAwB,IAAI,CAAU;AAC9C;AAKA,SAAS,GAAqB,GAAyC;CAKtE,OAJI,aAAyB,QAAQ,CAAC,OAAO,MAAM,EAAc,QAAQ,CAAC,IAClE,EAAc,YAAY,qBAG3B,IAAI,KAAK,EAAA,CAAE,YAAY;AAC/B;AAKA,SAAS,GAAkB,GAAkB;CAC5C,OAAO,IAAI,KACV,EAAK,YAAY,GACjB,EAAK,SAAS,GACd,EAAK,QAAQ,GACb,EAAK,SAAS,GACd,EAAK,WAAW,GAChB,EAAK,WAAW,GAChB,EAAK,gBAAgB,CACtB;AACD;AAQA,SAAS,EAAqB,GAAkB;CAC/C,OAAO,IAAI,KACV,EAAK,eAAe,GACpB,EAAK,YAAY,GACjB,EAAK,WAAW,GAChB,EAAK,YAAY,GACjB,EAAK,cAAc,GACnB,EAAK,cAAc,GACnB,EAAK,mBAAmB,CACzB;AACD;AAKA,SAAS,EAAgB,GAAY,GAA4D;CAChG,OAAO;EAAE,MAAM;EAA4B;EAAQ;CAAK;AACzD;AAKA,SAAS,GAAe,GAAe,IAAwB,GAAuD;CACrH,IAAI,CAAC,OAAO,SAAS,CAAK,GAAG,OAAO;CAEpC,IAAM,IAAY,KAAK,IAAI,CAAK,IAAI,KAAmC,IAAQ,IAAe,GACxF,IAAS,IAAI,KAAK,CAAS;CAGjC,OAFI,OAAO,MAAM,EAAO,QAAQ,CAAC,IAAU,OAEpC,EAAgB,MAAS,IAA4B,IAAS,EAAqB,CAAM,GAAG,EAA2B;AAC/H;AAMA,SAAS,GAAgB,GAAe,IAAwB,GAAuD;CACtH,IAAM,IAAQ,GAAe,KAAK,CAAK;CACvC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAY,OAAO,EAAM,EAAE;CACjC,IAAI,CAAC,OAAO,SAAS,CAAS,GAAG,OAAO;CAExC,IAAI,MAAS,GAA2B;EAGvC,IAAM,IAAc,IAAI,KAAK,CAAS;EACtC,OAAO,OAAO,MAAM,EAAY,QAAQ,CAAC,IAAI,OAAO,EAAgB,GAAa,EAA6B;CAC/G;CAEA,IAAM,IAAS,EAAM;CACrB,IAAI,CAAC,GAAQ,OAAO,EAAgB,EAAqB,IAAI,KAAK,CAAS,CAAC,GAAG,EAA6B;CAE5G,IAAM,IAAO,EAAO,WAAW,GAAG,IAAI,KAAK,GACrC,IAAQ,OAAO,EAAO,MAAM,GAAG,CAAC,CAAC,GACjC,IAAU,OAAO,EAAO,MAAM,GAAG,CAAC,CAAC;CACzC,IAAI,CAAC,OAAO,SAAS,CAAK,KAAK,CAAC,OAAO,SAAS,CAAO,GAAG,OAAO;CAEjE,IAAM,IAAW,KAAQ,IAAQ,IAAa,IAAU;CACxD,OAAO,EAAgB,EAAqB,IAAI,KAAK,IAAY,CAAQ,CAAC,GAAG,EAA6B;AAC3G;AAKA,SAAS,GAAc,GAA2C;CACjE,IAAM,IAAQ,GAAa,KAAK,CAAK;CACrC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAO,OAAO,EAAM,EAAE,GACtB,IAAQ,OAAO,EAAM,EAAE,GACvB,IAAM,OAAO,EAAM,EAAE,GACrB,IAAO,OAAO,EAAM,MAAM,CAAC,GAC3B,IAAS,OAAO,EAAM,MAAM,CAAC,GAC7B,IAAS,OAAO,EAAM,MAAM,CAAC,GAC7B,KAAmB,EAAM,MAAM,GAAA,CAAI,MAAM,GAAG,CAAkB,CAAC,CAAC,OAAO,GAAoB,GAAG,GAG9F,IAAS,EAAmB,GAAM,GAAO,GAAK,GAAM,GAAQ,GAF9C,OAAO,KAAmB,CAE4B,CAAW;CACrF,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAQA,SAAS,GAA2B,GAA+C;CAClF,IAAI,EAAc,EAAE,CAAC,YAAY,MAAM,KAAK,OAAO;CAEnD,IAAM,IAAO,EAAc,OAAO,MAAM,KAAK,GACvC,IAAQ,OAAO,EAAc,EAAE,GAC/B,IAAU,OAAO,EAAc,EAAE;CAGvC,OAFI,CAAC,OAAO,SAAS,CAAK,KAAK,CAAC,OAAO,SAAS,CAAO,KAAK,IAAA,MAA8B,IAAA,KAAuC,OAE1H,KAAQ,IAAQ,IAAa,IAAU;AAC/C;AAKA,SAAS,GAAc,GAAe,IAAwB,GAAuD;CACpH,IAAM,IAAgB,GAAa,KAAK,CAAK;CAC7C,IAAI,CAAC,GAAe,OAAO;CAG3B,IAAM,IAAS,GADS,EAAM,MAAM,GAAG,EAAc,KACxB,CAAe;CAC5C,IAAI,CAAC,GAAQ,OAAO;CACpB,IAAI,MAAS,IAA4B,OAAO,EAAgB,EAAO,MAAM,EAA2B;CAExG,IAAM,IAAmB,GAA2B,CAAa;CACjE,IAAI,MAAqB,MAAM,OAAO;CAEtC,IAAM,IAAe,EAAO,MACtB,IACL,KAAK,IACJ,EAAa,YAAY,GACzB,EAAa,SAAS,GACtB,EAAa,QAAQ,GACrB,EAAa,SAAS,GACtB,EAAa,WAAW,GACxB,EAAa,WAAW,GACxB,EAAa,gBAAgB,CAC9B,IAAI,GAEC,IAAc,IAAI,KAAK,CAAgB;CAC7C,OAAO,OAAO,MAAM,EAAY,QAAQ,CAAC,IAAI,OAAO,EAAgB,GAAa,EAA2B;AAC7G;AAKA,SAAS,GAAiB,GAA2C;CACpE,IAAI,CAAC,GAAgB,KAAK,CAAK,GAAG,OAAO;CAMzC,IAAM,IAAS,EAJF,OAAO,EAAM,MAAM,GAAG,CAAoB,CAIrB,GAHpB,OAAO,EAAM,MAAM,GAAsB,CAAqB,CAGpC,GAF5B,OAAO,EAAM,MAAM,GAAuB,EAAmB,CAE1B,CAAG;CAClD,OAAO,IAAS,EAAgB,GAAQ,EAA8B,IAAI;AAC3E;AAKA,SAAS,GAAmB,GAA2C;CACtE,IAAI,CAAC,GAAkB,KAAK,CAAK,GAAG,OAAO;CAS3C,IAAM,IAAS,EAPF,OAAO,EAAM,MAAM,GAAG,CAAoB,CAOrB,GANpB,OAAO,EAAM,MAAM,GAAsB,CAAqB,CAMpC,GAL5B,OAAO,EAAM,MAAM,GAAuB,EAAmB,CAK1B,GAJlC,OAAO,EAAM,MAAM,IAAqB,EAAoB,CAIrB,GAHrC,OAAO,EAAM,MAAM,IAAsB,EAAsB,CAGpB,GAF3C,OAAO,EAAM,MAAM,IAAwB,EAAsB,CAEd,CAAM;CACxE,OAAO,IAAS,EAAgB,GAAQ,EAAgC,IAAI;AAC7E;AAKA,SAAS,GAAgB,GAA2C;CACnE,IAAM,IAAQ,GAAe,KAAK,CAAK;CACvC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAM,OAAO,EAAM,EAAE,GACrB,IAAQ,OAAO,EAAM,EAAE,GAGvB,IAAS,EAFF,OAAO,EAAM,EAEQ,GAAM,GAAO,CAAG;CAClD,OAAO,IAAS,EAAgB,GAAQ,EAA6B,IAAI;AAC1E;AAKA,SAAS,GAAe,GAA2C;CAClE,IAAM,IAAQ,GAAc,KAAK,CAAK;CACtC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAQ,OAAO,EAAM,EAAE,GACvB,IAAM,OAAO,EAAM,EAAE,GAGrB,IAAS,EAFF,OAAO,EAAM,EAEQ,GAAM,GAAO,CAAG;CAClD,OAAO,IAAS,EAAgB,GAAQ,EAA4B,IAAI;AACzE;AAKA,SAAS,GAAkB,GAAe,IAAwB,GAAuD;CACxH,IAAM,IAAQ,GAAiB,KAAK,CAAK;CAIzC,OAHK,IAGE,GADY,EAAM,EAAE,CAAC,KACL,GAAY,IAAiC,CAAI,IAHrD;AAIpB;AAOA,SAAS,GAAiB,GAAuC;CAChE,IAAM,IAAQ,GAAgB,KAAK,CAAK;CACxC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAM,IAAO,EAAM,OAAO,MAAM,KAAK,GAC/B,IAAQ,OAAO,EAAM,MAAM,CAAC,GAC5B,IAAS,OAAO,EAAM,MAAM,CAAC,GAC7B,IAAO,OAAO,EAAM,MAAM,CAAC,GAC3B,IAAQ,OAAO,EAAM,MAAM,CAAC,GAC5B,IAAU,OAAO,EAAM,MAAM,CAAC,GAC9B,IAAU,OAAO,EAAM,MAAM,CAAC,GAC9B,KAAe,EAAM,MAAM,GAAA,CAAI,MAAM,GAAG,CAAkB,CAAC,CAAC,OAAO,GAAoB,GAAG,GAC1F,IAAe,OAAO,KAAe,CAAC;CAe5C,OAbgC,KAAS,KAAU,KAAQ,KAAS,KAAW,KAAW,IAanF;EAAE,MAAM;EAA2B,QAAQ;EAAgC,YATjF,KACC,IAAQ,KAAsB,IAC9B,IAAS,KAAuB,IAChC,IAAO,IACP,IAAQ,IACR,IAAU,IACV,IAAU,IACV;CAE2F,IAZhE;AAa9B;AAKA,SAAS,EAAmB,GAA4B,GAAqE;CAC5H,OAAO,IAAiB;EAAE,GAAG;EAAO,QAAQ;CAAe,IAAI;AAChE;AAKA,SAAS,GACR,GACA,GACA,IAAwB,GACK;CAC7B,IAAM,IAAQ,GAAc,GAAO,CAAI;CACvC,IAAI,GAAO,OAAO,EAAmB,GAAO,CAAc;CAE1D,IAAM,IAAW,GAAc,CAAK;CACpC,IAAI,GAAU,OAAO,EAAmB,GAAU,CAAc;CAEhE,IAAM,IAAS,GAAgB,CAAK;CACpC,IAAI,GAAQ,OAAO,EAAmB,GAAQ,CAAc;CAE5D,IAAM,IAAU,GAAe,CAAK;CACpC,IAAI,GAAS,OAAO,EAAmB,GAAS,CAAc;CAE9D,IAAM,IAAY,GAAmB,CAAK;CAC1C,IAAI,GAAW,OAAO,EAAmB,GAAW,CAAc;CAElE,IAAM,IAAU,GAAiB,CAAK;CACtC,IAAI,GAAS,OAAO,EAAmB,GAAS,CAAc;CAE9D,IAAM,IAAoB,OAAO,CAAK;CACtC,IAAI,UAAU,KAAK,CAAK,KAAK,OAAO,SAAS,CAAiB,GAAG;EAChE,IAAM,IAAY,GAAe,GAAmB,CAAI;EACxD,IAAI,GAAW,OAAO,EAAmB,GAAW,CAAc;CACnE;CAEA,OAAO;AACR;AAKA,SAAS,GAAa,GAAuB;CAC5C,OAAO,EAAM,QAAQ,uBAAuB,MAAM;AACnD;AAQA,SAAS,GAAoB,GAAsB;CAClD,OAAO,IAAO,KAAuB,KAAkB,IAAO,KAAmB;AAClF;AAcA,SAAgB,GACf,GACA,IAAU,IACV,IAAqC,CAAC,GACb;CACzB,IAAI,OAAO,KAAU,UACpB,OAAO,EAAe,CAAK;CAG5B,IAAM,IAAU,EAAM,KAAK;CAC3B,IAAI,EAAoB,IAAI,EAAQ,YAAY,CAAC,GAAG,OAAO;CAE3D,IAAM,IAAY,EAAQ,aAAA,OACpB,IAAmB,EAA4B,GAAS,CAAS,GACjE,IAAyB,CAAC,GAC5B,IAAS,GACT,IAAe,KACf,IAAoC;CAIxC,KAFA,EAAsB,YAAY,IAE1B,IAAY,EAAsB,KAAK,CAAgB,OAAO,OAOrE,AANA,KAAgB,GAAa,EAAiB,MAAM,GAAQ,EAAU,KAAK,CAAC,GAC5E,EAAa,KAAK,EAAU,EAAE,GAE1B,EAAU,OAAA,SAAgC,KAAgB,aACzD,KAAgB,YAErB,IAAS,EAAU,QAAQ,EAAU,EAAE,CAAC;CAGzC,IAAI,EAAa,WAAW,GAAG,OAAO;CAEtC,KAAgB,GAAG,GAAa,EAAiB,MAAM,CAAM,CAAC,EAAE;CAEhE,IAAM,IAAQ,IADI,OAAO,CACX,CAAA,CAAM,KAAK,CAAO;CAChC,IAAI,CAAC,GAAO,OAAO;CAEnB,IAAI,IAAsB,MACtB,IAAuB,MACvB,IAAqB,MACrB,IAAO,GACP,KAAS,GACT,KAAS;CAEb,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAa,QAAQ,KAAS,GAAG;EAC5D,IAAM,IAAQ,EAAa,IACrB,IAAW,EAAM,IAAQ,IACzB,IAAe,OAAO,CAAQ;EACpC,IAAI,CAAC,OAAO,SAAS,CAAY,GAAG,OAAO;EAQ3C,AANI,MAAA,WAAmC,IAAO,IAC1C,MAAA,SAAyC,IAAO,GAAoB,CAAY,IAChF,MAAA,SAAoC,IAAQ,IAC5C,MAAA,SAAkC,IAAM,IACxC,MAAA,SAAoC,IAAO,IAC3C,MAAA,SAAsC,KAAS,IAC/C,MAAA,SAAsC,KAAS;CACpD;CAIA,IAFI,CAAC,KACD,MAAA,UAA4C,CAAC,KAC7C,MAAA,SAA2C,CAAC,GAAK,OAAO;CAE5D,IAAM,IAAS,EAAmB,GAAM,KAAS,GAAG,KAAO,GAAG,GAAM,IAAQ,EAAM;CAClF,OAAO,IAAS,EAAgB,GAAQ,CAA2B,IAAI;AACxE;AAwBA,SAAS,GAA2B,GAAoB,GAA8D;CACrH,IAAM,IAAS,EAAc,CAAU,GACjC,IAAiB,GAA2B;CAMlD,OAJI,GAAQ,UAAgB,CAAC,EAA4B,EAAO,SAAS,CAAS,CAAC,IAC/E,IAAuB,EAAe,KAAK,MAAY,EAA4B,GAAS,CAAS,CAAC,IACtG,CAAC,KAAU,GAAqB,CAAU,IAAU,CAAC,EAA4B,GAAY,CAAS,CAAC,IAEpG,CAAC;AACT;AAKA,SAAgB,GAAkB,GAAgB,GAAqB,IAAoC,CAAC,GAA+B;CAC1I,IAAI,OAAO,KAAU,UAAU;EAC9B,IAAM,IAAS,EAAe,CAAK;EACnC,OAAO,GAAQ,SAAA,cAAsC,IAAS;CAC/D;CAEA,IAAM,IAAU,EAAM,KAAK;CAC3B,IAAI,EAAoB,IAAI,EAAQ,YAAY,CAAC,GAAG,OAAO;CAE3D,IAAM,IAAY,EAAQ,aAAA,OACpB,IAAiB,GAAsB,GAAY,EAAQ,iBAAA,MAAsC;CACvG,KAAK,IAAM,KAAW,GAA2B,GAAgB,CAAS,GAAG;EAC5E,IAAM,IAAkB,GAAmB,GAAS,GAAS,EAAE,aAAU,CAAC;EAC1E,IAAI,GAAiB,SAAA,aAAqC,OAAO;CAClE;CAEA,IAAI,MAAA,OAAyC;EAC5C,IAAM,IAAgB,EAAe,CAAO;EAC5C,IAAI,GAAe,SAAA,aAAqC,OAAO;CAChE;CAGA,IAAM,IADS,EAAc,CACd,CAAA,EAAQ,UAAU,EAAQ,UAAU,EAAqB;CAExE,IAAI,MAAA,SAA2C,GAAqB,CAAc,GAAG;EACpF,IAAM,IAAiB,GAA6B,GAAS,GAAQ,GAAqB,EAAQ,aAAa,CAAC;EAChH,IAAI,GAAgB,OAAO;CAC5B;CAMA,OAJI,MAAA,UAA4C,GAAsB,CAAc,IAC5E,GAA0B,GAAS,CAAM,IAG1C,GAAyB,GAAS,GAAQ,CAAS;AAC3D;AAKA,SAAS,GACR,GACA,EAAE,UAAO,MAA6D,CAAC,GAC9C;CACzB,IAAI,KAAS,MAAM,OAAO;CAE1B,IAAI,aAAiB,MAGpB,OAFI,OAAO,MAAM,EAAM,QAAQ,CAAC,IAAU,OAEnC,EADM,MAAS,IAA4B,IAAI,KAAK,EAAM,QAAQ,CAAC,IAAI,GAAkB,CAAK,GACxE,EAA6B;CAG3D,IAAI,OAAO,KAAU,UACpB,OAAO,GAAe,GAAO,CAAI;CAGlC,IAAI,OAAO,KAAU,UAAU,OAAO;CAEtC,IAAM,IAAU,EAAM,KAAK;CAY3B,OAXI,EAAoB,IAAI,EAAQ,YAAY,CAAC,IAAU,OAExC,GAAgB,GAAS,CACxC,KAEiB,GAAkB,GAAS,CAC5C,KAEa,GAAiB,CAC9B,KAEG,GAAgB,GAAS,KAAA,GAAW,CAAI;AAChD;AAMA,SAAgB,EAAe,GAAwC;CACtE,OAAO,GAAuB,CAAK;AACpC;AAQA,SAAgB,GAAiB,GAAwC;CACxE,OAAO,GAAuB,GAAO,EAAE,MAAM,EAA0B,CAAC;AACzE;AAQA,SAAS,GAAuB,GAA4C;CAC3E,IAAI,CAAC,GAAO,OAAO;CACnB,IAAI,EAAM,SAAA,aAAqC,OAAO,EAAM;CAE5D,IAAM,IAAe,IAAI,KAAK,EAAM,UAAU;CAG9C,OAFI,OAAO,MAAM,EAAa,QAAQ,CAAC,IAAU,OAE1C,EAAqB,CAAY;AACzC;AAKA,SAAgB,GAAU,GAA6B;CACtD,OAAO,GAAuB,EAAe,CAAK,CAAC;AACpD;AAKA,SAAgB,GAAY,GAA6B;CACxD,OAAO,GAAuB,GAAiB,CAAK,CAAC;AACtD;;;ACp4BA,SAAgB,GAAoD,GAAuB;CAI1F,OAHI,GAAoB,CAAI,IAAU,IAClC,GAAoB,CAAI,IAAU,IAClC,GAAiB,CAAI,IAAU,IAC5B;AACR;AAEA,SAAgB,GAAoB,GAA2D;CAC9F,OAAO,MAAS;AACjB;AAEA,SAAgB,GAAoB,GAA2D;CAC9F,OACC,MAAA,UACA,MAAA,SACA,MAAA,UACA,MAAA,WACA,MAAA,aACA,MAAA;AAEF;AAEA,SAAgB,GAAoB,GAA2D;CAC9F,OAAO,MAAA,UAA6B,MAAA,SAA4B,MAAA;AACjE;AAEA,SAAgB,GAAiB,GAAwD;CACxF,OAAO,MAAA,cAAiC,MAAA,oBAAwC,MAAA;AACjF"}