From dae4b28381c99da60db327a28ce07b152356dd72 Mon Sep 17 00:00:00 2001 From: Pavel Vostrikov Date: Tue, 24 Mar 2026 21:45:09 +0300 Subject: [PATCH 01/42] feat: add @kaspersky/ui-normalization tooling --- .../kaspersky-dev-tools/npm-shrinkwrap.json | 17 +- .../kaspersky-ui-normalization-tool/AGENTS.md | 302 + .../kaspersky-ui-normalization-tool/DEPLOY.md | 173 + .../kaspersky-ui-normalization-tool/README.md | 61 + .../TESTING-GAPS.md | 177 + .../e2e/PALETTE-E2E-REPORT.md | 39 + .../e2e/demo-form.spec.ts | 29 + .../e2e/keyboard-undo.spec.ts | 117 + .../e2e/palette-add-all.spec.ts | 56 + .../e2e/preview-export.spec.ts | 79 + .../e2e/properties-templates.spec.ts | 98 + .../e2e/ui-exploration.spec.ts | 205 + .../index.html | 13 + .../jsons/form-1774124967510.js | 32 + .../jsons/handlers/click.js | 3 + .../package-lock.json | 9140 +++++++++++++++++ .../package.json | 44 + .../playwright.config.ts | 25 + .../public/favicon.svg | 4 + .../scripts/generate-random-forms.js | 165 + .../src/App.tsx | 631 ++ .../components/CanvasPreviewErrorBoundary.tsx | 39 + .../src/components/CodeExportDialog.tsx | 111 + .../src/components/ControlsPalette.tsx | 96 + .../src/components/FormCanvas.tsx | 1130 ++ .../src/components/FormPreview.tsx | 227 + .../src/components/HandlerFilePicker.tsx | 120 + .../src/components/HandlersEditor.tsx | 89 + .../src/components/PropertiesPanel.tsx | 626 ++ .../src/components/SelectWithOptionWidth.tsx | 51 + .../src/constants.ts | 2 + .../src/controls/descriptors/button.tsx | 54 + .../src/controls/descriptors/checkbox.tsx | 44 + .../src/controls/descriptors/hexa.tsx | 701 ++ .../src/controls/descriptors/icon.tsx | 150 + .../src/controls/descriptors/input.tsx | 36 + .../src/controls/descriptors/markdown.tsx | 33 + .../src/controls/descriptors/radio.tsx | 37 + .../src/controls/descriptors/row.tsx | 53 + .../src/controls/descriptors/select.tsx | 48 + .../src/controls/descriptors/tabs.tsx | 130 + .../src/controls/descriptors/text.tsx | 30 + .../src/controls/descriptors/toggle.tsx | 48 + .../src/controls/descriptors/toolbar.tsx | 226 + .../src/controls/registry.test.ts | 131 + .../src/controls/registry.ts | 150 + .../src/controls/types.ts | 47 + .../src/hooks/useDirectoryPicker.ts | 49 + .../src/hooks/useFormFile.ts | 239 + .../src/hooks/useFormFilesList.ts | 114 + .../src/hooks/useHistory.ts | 71 + .../src/main.css | 202 + .../src/main.tsx | 12 + .../src/templates.ts | 226 + .../src/test/setup.ts | 1 + .../src/types/file-system-access.d.ts | 84 + .../src/types/form-dsl.test.ts | 415 + .../src/types/form-dsl.ts | 1185 +++ .../src/utils/getErrorMessage.ts | 13 + .../src/vite-env.d.ts | 1 + .../tsconfig.json | 25 + .../tsconfig.node.json | 10 + .../verification/01-editor-demo-mode.png | Bin 0 -> 67604 bytes .../verification/02-text-added.png | Bin 0 -> 65355 bytes .../verification/03-text-properties.png | Bin 0 -> 59933 bytes .../vite.config.ts | 30 + .../.gitignore | 24 + .../DEPLOY.md | 153 + .../README.md | 36 + .../index.html | 13 + .../package-lock.json | 4608 +++++++++ .../package.json | 25 + .../src/App.tsx | 226 + .../src/components/FormRenderer.tsx | 408 + .../src/hooks/useDirectoryPicker.ts | 47 + .../src/hooks/useFormFilesList.ts | 141 + .../src/hooks/useFormLoader.ts | 45 + .../src/main.css | 17 + .../src/main.tsx | 16 + .../src/types/file-system-access.d.ts | 30 + .../src/types/form-dsl.ts | 323 + .../src/vite-env.d.ts | 1 + .../tsconfig.json | 23 + .../tsconfig.node.json | 11 + .../vite.config.ts | 22 + 85 files changed, 24656 insertions(+), 9 deletions(-) create mode 100644 packages/kaspersky-ui-normalization-tool/AGENTS.md create mode 100644 packages/kaspersky-ui-normalization-tool/DEPLOY.md create mode 100644 packages/kaspersky-ui-normalization-tool/README.md create mode 100644 packages/kaspersky-ui-normalization-tool/TESTING-GAPS.md create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/PALETTE-E2E-REPORT.md create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/demo-form.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/keyboard-undo.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/palette-add-all.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/preview-export.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/properties-templates.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/e2e/ui-exploration.spec.ts create mode 100644 packages/kaspersky-ui-normalization-tool/index.html create mode 100644 packages/kaspersky-ui-normalization-tool/jsons/form-1774124967510.js create mode 100644 packages/kaspersky-ui-normalization-tool/jsons/handlers/click.js create mode 100644 packages/kaspersky-ui-normalization-tool/package-lock.json create mode 100644 packages/kaspersky-ui-normalization-tool/package.json create mode 100644 packages/kaspersky-ui-normalization-tool/playwright.config.ts create mode 100644 packages/kaspersky-ui-normalization-tool/public/favicon.svg create mode 100644 packages/kaspersky-ui-normalization-tool/scripts/generate-random-forms.js create mode 100644 packages/kaspersky-ui-normalization-tool/src/App.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/CanvasPreviewErrorBoundary.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/CodeExportDialog.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/ControlsPalette.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/FormCanvas.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/FormPreview.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/HandlerFilePicker.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/HandlersEditor.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/PropertiesPanel.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/components/SelectWithOptionWidth.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/constants.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/button.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/checkbox.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/hexa.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/icon.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/input.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/markdown.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/radio.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/row.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/select.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/tabs.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/text.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/toggle.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/descriptors/toolbar.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/registry.test.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/registry.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/controls/types.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/hooks/useDirectoryPicker.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/hooks/useFormFile.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/hooks/useFormFilesList.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/hooks/useHistory.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/main.css create mode 100644 packages/kaspersky-ui-normalization-tool/src/main.tsx create mode 100644 packages/kaspersky-ui-normalization-tool/src/templates.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/test/setup.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/types/file-system-access.d.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/types/form-dsl.test.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/types/form-dsl.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/utils/getErrorMessage.ts create mode 100644 packages/kaspersky-ui-normalization-tool/src/vite-env.d.ts create mode 100644 packages/kaspersky-ui-normalization-tool/tsconfig.json create mode 100644 packages/kaspersky-ui-normalization-tool/tsconfig.node.json create mode 100644 packages/kaspersky-ui-normalization-tool/verification/01-editor-demo-mode.png create mode 100644 packages/kaspersky-ui-normalization-tool/verification/02-text-added.png create mode 100644 packages/kaspersky-ui-normalization-tool/verification/03-text-properties.png create mode 100644 packages/kaspersky-ui-normalization-tool/vite.config.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/.gitignore create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/DEPLOY.md create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/README.md create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/index.html create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/package-lock.json create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/package.json create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/App.tsx create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/components/FormRenderer.tsx create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/hooks/useDirectoryPicker.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/hooks/useFormFilesList.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/hooks/useFormLoader.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/main.css create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/main.tsx create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/types/file-system-access.d.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/types/form-dsl.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/src/vite-env.d.ts create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/tsconfig.json create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/tsconfig.node.json create mode 100644 packages/kaspersky-ui-normalization-transpile-viewer/vite.config.ts diff --git a/packages/kaspersky-dev-tools/npm-shrinkwrap.json b/packages/kaspersky-dev-tools/npm-shrinkwrap.json index 276e2e28..72badbe4 100644 --- a/packages/kaspersky-dev-tools/npm-shrinkwrap.json +++ b/packages/kaspersky-dev-tools/npm-shrinkwrap.json @@ -1,13 +1,12 @@ { "name": "@kaspersky/dev-tools", - "version": "3.4.3", + "version": "3.4.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@kaspersky/dev-tools", - "version": "3.4.3", - "hasInstallScript": true, + "version": "3.4.4", "license": "Apache-2.0", "dependencies": { "@babel/core": "7.26.10", @@ -5501,9 +5500,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "license": "ISC" }, "node_modules/for-each": { @@ -14282,9 +14281,9 @@ } }, "flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==" }, "for-each": { "version": "0.3.5", diff --git a/packages/kaspersky-ui-normalization-tool/AGENTS.md b/packages/kaspersky-ui-normalization-tool/AGENTS.md new file mode 100644 index 00000000..0a74304c --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/AGENTS.md @@ -0,0 +1,302 @@ +# AGENTS.md — контекст проекта UISB + +Документ для AI-агентов (Cursor и др.): назначение проекта, структура, соглашения и важные пути. + +--- + +## Назначение проекта + +**UISB** — визуальный редактор UI-форм на базе дизайн-системы **Hexa UI** (Kaspersky). Пользователь выбирает каталог на диске (File System Access API), создаёт и редактирует формы в виде `.js`-модулей, перетаскивает контролы с палитры на холст (в т.ч. в ячейки grid/table и вкладки tabs). Формы хранятся только в формате **.js** (не JSON). + +Редактор поддерживает: +- **Привязку данных** (fieldName, dataType, defaultValue, schema формы) +- **Валидацию** (required, minLength, maxLength, min, max, pattern, custom) +- **Условную логику** (visibleWhen, disabledWhen — показ/блокировка контролов по значению других полей) +- **Обработчики событий** уровня формы и отдельных контролов (файлы `.js`/`.ts` из каталога формы, по принципу Unity) +- **Undo/redo**, копирование, дублирование, горячие клавиши +- **Предпросмотр формы** с валидацией и условной логикой +- **Экспорт DSL** (JS-модуль, JSON) +- **Шаблоны** типовых форм + +В будущем DSL будет трансформироваться в формы на произвольных библиотеках и дизайн-системах; сейчас рендеринг реализован только через Hexa UI. Генерация React-компонентов и TypeScript-типов из DSL **не входит** в scope — разработчику не важно, что под капотом. + +--- + +## Стек и скрипты + +- **React 17**, **TypeScript**, **Vite** +- **Hexa UI**: `@kaspersky/hexa-ui`, `@kaspersky/hexa-ui-icons` +- **Тесты**: Vitest (unit), Playwright (e2e) +- **Скрипты**: `npm run dev` (разработка), `npm run build`, `npm run test`, `npm run test:e2e`, `npm run release` (build + npm pack) + +--- + +## Структура репозитория + +``` +src/ + types/ + form-dsl.ts # DSL форм: типы, CONTROL_EVENTS, FORM_EVENTS, parseFormJs, + # formToJs, formToJson*, controlToJson, updateControlInTree, + # set*ChildrenInTree + form-dsl.test.ts + controls/ + registry.ts # createControl, getDescriptor, PALETTE_ITEMS, CONTROL_TYPES + types.ts # CanvasContext, ControlDescriptor + descriptors/ # по одному файлу на тип: hexa, tabs, toolbar, icon, row + registry.test.ts + components/ + ControlsPalette.tsx # палитра контролов с поиском + FormCanvas.tsx # холст, DnD, контейнеры grid/table/tabs, бейджи (fieldName, ⚡, fn) + PropertiesPanel.tsx # панель свойств: PropsEditor, FieldBindingEditor, ValidationEditor, + # ConditionEditor, SchemaEditor + HandlersEditor + HandlersEditor.tsx # универсальный редактор обработчиков событий + HandlerFilePicker.tsx # файловый браузер для выбора обработчика из каталога формы + FormPreview.tsx # предпросмотр формы с валидацией и условной логикой + CodeExportDialog.tsx # диалог экспорта DSL (JS-модуль, JSON) + SelectWithOptionWidth.tsx + CanvasPreviewErrorBoundary.tsx + hooks/ + useDirectoryPicker.ts + useFormFilesList.ts # дерево файлов .js в выбранном каталоге + useFormFile.ts # загрузка/сохранение формы (parseFormJs / formToJs) + useHistory.ts # undo/redo стек для состояния контролов + templates.ts # предустановленные шаблоны форм (FORM_TEMPLATES) + App.tsx # корневой компонент: layout, хоткеи, интеграция хуков + main.tsx # точка входа; проверка наличия #root + main.css + constants.ts # FORM_EXT = '.js' + utils/ + getErrorMessage.ts # единообразная обработка ошибок +jsons/ # демо-каталог: одна форма + обработчик (можно указать при разработке) + demo-form.js # демонстрационная форма с row, валидацией, обработчиками + handlers/ + handler.js # пример обработчика +e2e/ # Playwright: app-load, demo-form +TESTING-GAPS.md # документация непокрытых сценариев тестирования +``` + +--- + +## Формат формы (.js) + +Один файл формы — один ES-модуль с **`export default`** объектом: + +```js +export default { + name: "Название формы", + id: "form-123", + schema: { // опционально: схема данных + email: { type: "string", label: "Email" }, + age: { type: "number" } + }, + handlers: { // опционально: обработчики событий формы + onSubmit: () => import("./handlers/submit.js"), + onInit: () => import("./handlers/init.js") + }, + elements: [ + { + type: "input", + id: "input-1", + placeholder: "Email", + fieldName: "email", + dataType: "string", + validation: [{ type: "required", message: "Обязательное поле" }], + handlers: { + onChange: () => import("./handlers/email-change.js") + } + }, + { + type: "button", + id: "button-1", + text: "Отправить", + mode: "primary", + handlers: { + onClick: () => import("./handlers/submit.js") + } + } + ] +} +``` + +- **В DSL у каждого элемента свой семантический тип**: кнопка — `type: "button"`, табы — `type: "tabs"`, алерт — `type: "alert"` и т.д. Метатипа («component», «hexa») нет; реализация (Hexa UI) не входит в описание формы. +- **Обработчики** в данных хранятся как строки путей (например `handlers/submit.js`); при сериализации в JS подставляется `() => import("./handlers/submit.js")`. +- **Загрузка**: `parseFormJs(content)` → Blob → `URL.createObjectURL` → `import(url)` → `normalizeFormData(mod.default)`. Принимаются только семантические типы; элементы с неизвестным или устаревшим типом отбрасываются. +- **Сохранение**: `formToJs(formData)` → исходный код модуля. + +--- + +## Типы контролов (DSL) + +В DSL у каждого элемента свой **семантический тип** (как у кнопки и табов): кнопка — `type: "button"`, табы — `type: "tabs"`, алерт — `type: "alert"` и т.д. Метатипа («component»/«hexa») нет. + +- **Базовые**: `button`, `text`, `input`, `checkbox`, `radio`, `select`, `toggle`, `markdown` — плоские поля (text, mode, options и т.д.). +- **С типом + props**: `alert`, `heading`, `dropdown`, `field`, `fieldSet`, `p`, `link`, … (`EXTRA_UI_DSL_TYPES`) — `type` + `props: Record`. +- **`icon`** — иконка по имени (свой дескриптор). +- **`toolbar`** — тулбар с `left`/`right` (свой дескриптор). +- **Контейнеры**: `grid`, `row`, `table`, `tabs` + - `grid` — 2D сетка: `rows × cols`, `children: (FormControl | null)[]` + - `row` — горизонтальный flex-ряд: `gap?`, `align?`, `children` + - `table` — таблица: `rows × cols`, `toolbar`, `children` + - `tabs` — вкладки: `items[].key/label/children`, `activeKey` +- Типы и маппинг componentId↔тип DSL — в `src/types/form-dsl.ts` (`COMPONENT_ID_TO_DSL_TYPE`, `EXTRA_UI_DSL_TYPES`). + +Добавление нового UI-компонента: добавить запись в `COMPONENT_ID_TO_DSL_TYPE` и `EXTRA_UI_DSL_TYPES`, а также в `HEXA_COMPONENT_MAP`, `HEXA_PALETTE_GROUPS` и `COMPONENT_PROPS` в `hexa.tsx`; для базового типа (аналог button/input) — свой дескриптор в `descriptors/`. + +--- + +## Модель данных контрола (FormControlBase) + +Каждый контрол наследует `FormControlBase`: + +| Поле | Тип | Назначение | +|------|-----|-----------| +| `id` | `string` | Уникальный идентификатор | +| `fieldName?` | `string` | Привязка к полю данных формы | +| `dataType?` | `'string' \| 'number' \| 'boolean' \| 'date' \| 'array'` | Тип данных поля | +| `defaultValue?` | `unknown` | Начальное значение | +| `validation?` | `ValidationRule[]` | Правила валидации | +| `visibleWhen?` | `Condition` | Условие видимости | +| `disabledWhen?` | `Condition` | Условие блокировки | +| `handlers?` | `Record` | Обработчики событий (имя → путь к файлу) | + +`FormData` дополнительно содержит `schema?: Record` и `handlers?: Record`. + +--- + +## Обработчики событий + +Система обработчиков по принципу Unity: файлы-скрипты `.js`/`.ts` в каталоге формы назначаются на события через инспектор свойств. + +### Доступные события + +Определены в константах `CONTROL_EVENTS` и `FORM_EVENTS` (`form-dsl.ts`): + +**Формы**: `onSubmit`, `onInit`, `onChange`, `onValidationError` + +**Контролы**: +| Тип | События | +|-----|---------| +| `button`, `text`, `input`, … `alert`, `heading`, … | см. CONTROL_EVENTS в form-dsl.ts | +| `tabs` | `onTabChange` | +| `icon` | `onClick` | +| `toolbar` | `onAction` | +| `grid`, `row`, `table` | — | + +### UI + +- **`HandlersEditor`** (`src/components/HandlersEditor.tsx`) — универсальный компонент: показывает доступные события типа, для каждого — текстовое поле пути и кнопку выбора файла. +- **`HandlerFilePicker`** (`src/components/HandlerFilePicker.tsx`) — файловый браузер каталога формы (навигация по папкам, фильтр `.js`/`.ts`). +- Обработчики отображаются в `PropertiesPanel`: для контрола — секция «Обработчики событий», для формы (без выбранного контрола) — секция «Обработчики формы». +- На холсте контролы с обработчиками показывают фиолетовый бейдж **fn** (с количеством и тултипом). + +### Сериализация + +- В памяти: `handlers: { onClick: "handlers/click.js" }` (строки путей) +- В `.js`-модуле: `handlers: { "onClick": () => import("./handlers/click.js") }` (динамический импорт) +- При загрузке: `getImportPathFromHandler(fn)` извлекает путь из функции + +--- + +## Валидация + +Правила валидации задаются в `validation: ValidationRule[]` на контроле. + +Типы правил (`ValidationRuleType`): `required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, `custom`. + +Каждое правило: `{ type, value?, message }`. Редактируются в `ValidationEditor` (внутри `PropertiesPanel`). Контролы с `required` показывают красную звёздочку `*` на холсте. + +--- + +## Условная логика + +Контролы могут иметь `visibleWhen` и `disabledWhen` — объекты `Condition`: + +```ts +{ fieldName: string, operator: 'eq'|'neq'|'gt'|'lt'|'contains'|'empty'|'notEmpty', value?: string } +``` + +- В редакторе: `ConditionEditor` в панели свойств (чекбокс + поля). +- В предпросмотре (`FormPreview`): `evaluateCondition` скрывает/блокирует контролы в реальном времени. +- На холсте: бейдж ⚡ с тултипом условия. + +--- + +## Дескрипторы и холст + +- **ControlDescriptor**: `type`, `label`, `Icon`, `createDefault`, `CanvasPreview`, `PropsEditor`. +- **component** — универсальный тип для всех UI-компонентов на палитре: `componentId` + `props`. Заголовки H1–H6 объединены в один элемент «Заголовок» (Heading) с пропом уровня. Палитра сгруппирована по семантике (`getPaletteGroups()`); палитра имеет поиск. При добавлении компонента передаётся `options.componentId`. +- **CanvasContext** передаётся в превью: `selectedId`, `onSelect`, `onRemove`, `rootSetControls`, `renderControlBlock`, `createControl(type, options?)`, `setGridChildrenInTree`, `setRowChildrenInTree`, `setTableChildrenInTree`. +- Обновление дерева при DnD в контейнерах — через `setGridChildrenInTree` / `setRowChildrenInTree` / `setTableChildrenInTree` / `setTabsChildrenInTree` из `form-dsl.ts`. +- **Бейджи на холсте**: зелёный — fieldName (с `*` для required), жёлтый ⚡ — условия, фиолетовый fn — обработчики. + +--- + +## UX редактора + +- **Undo/redo**: `useHistory` (`src/hooks/useHistory.ts`) — стек до 50 состояний. Ctrl+Z / Ctrl+Shift+Z. +- **Горячие клавиши**: Ctrl+S (сохранить), Ctrl+C (копировать), Ctrl+V (вставить), Ctrl+D (дублировать), Delete (удалить), Escape (сбросить выбор / выйти из предпросмотра). +- **Предпросмотр**: `FormPreview` — рендер формы с интерактивными контролами, валидацией, условной логикой. Кнопка «Предпросмотр» в тулбаре. +- **Экспорт DSL**: `CodeExportDialog` — вкладки «JS модуль» и «JSON» с кнопкой копирования. Генерация React/TS-компонентов **не** входит в scope. +- **Шаблоны**: `FORM_TEMPLATES` (`src/templates.ts`) — предустановленные формы (вход, регистрация и т.д.). Отображаются в левой панели под палитрой. +- **Предупреждение при закрытии**: `useFormFile.closeFile` спрашивает подтверждение при наличии несохранённых изменений. + +--- + +## Безопасность + +- **hexa** (Link и др. с ссылками): в превью URL в `href`/`src`/`url` проверяются по белому списку схем (`http:`, `https:`, `mailto:`, `tel:`) во избежание XSS. +- **parseFormJs**: выполнение кода формы через динамический `import(blobUrl)`, без `eval`. + +--- + +## Файлы и каталог формы + +- **useFormFilesList**: строит дерево только для файлов с расширением **`.js`** (`FORM_EXT = '.js'`). +- **useFormFile**: загрузка — чтение файла и `parseFormJs(content)`; сохранение — `formToJs(data)` и запись в выбранный/текущий файл. При создании новой формы сохраняется как `.js`. Удаление файла через `removeFileByPath` (вложенные пути поддерживаются); ошибки оборачиваются в понятные сообщения. + +--- + +## E2E и демо-режим + +- При `window.__E2E_DEMO__ = true` приложение открывает редактор с пустой формой без выбора каталога (для тестов). +- E2E: `e2e/README.md`, сценарии `app-load.spec.ts`, `demo-form.spec.ts`; перед первым запуском — `npx playwright install`. + +--- + +## Важные соглашения + +- **Язык интерфейса**: русский (подписи кнопок, панели, сообщения). +- **Обработчики событий**: хранятся как `.js`/`.ts` файлы в каталоге формы (например `handlers/submit.js`). В DSL — строка пути; в JS-модуле — `() => import("./...")`. Назначаются через `HandlersEditor` в панели свойств. +- **Единственная реализация createControl** — в `src/controls/registry.ts`; в форме дерево контролов — массив `FormControl[]`, контейнеры содержат `children` или `items[].children` (без лишних null в конце при отображении табов). +- **controlToJson** — все ветки используют `{ ...base, ... }` для сохранения общих свойств (`fieldName`, `handlers`, `validation`, `visibleWhen`, `disabledWhen` и т.д.). +- **Корень приложения**: в `main.tsx` проверяется наличие `#root`; при отсутствии — throw. + +--- + +## Стиль кода и ревью + +- **Типы**: возвращаемые типы хуков вынесены в интерфейсы (`UseFormFileResult`, `UseFormFilesListResult`) для переиспользования. +- **Ошибки**: единообразная обработка через `getErrorMessage(err, fallback)` (`src/utils/getErrorMessage.ts`). +- **Константы**: расширение файлов форм — `FORM_EXT` в `src/constants.ts`; используется при фильтрации списка, создании файлов и в UI. +- **Цвета**: в стилях предпочтительны CSS-переменные Hexa (`var(--primary--main, ...)`, `var(--surface--neutral, ...)`, `var(--tagsoutlined--neutral-border, ...)`) для единообразия и темы. Бейджи на холсте: зелёный (#00a88e) — данные, жёлтый (#fa8c16) — условия, фиолетовый (#722ed1) — обработчики. + +--- + +## Полезные точки входа для правок + +| Задача | Файлы | +|--------|--------| +| Новый компонент Hexa UI | `hexa.tsx` (HEXA_COMPONENT_MAP, COMPONENT_PROPS, HEXA_PALETTE_GROUPS) | +| Новое свойство на FormControlBase | `form-dsl.ts` (тип + normalizeControl + controlToJson + base) | +| Логика загрузки/сохранения формы | `form-dsl.ts` (parseFormJs, formToJs), `useFormFile.ts` | +| DnD, контейнеры (grid/row/table/tabs) на холсте | `FormCanvas.tsx`, `form-dsl.ts` (set*ChildrenInTree) | +| Панель свойств | `PropertiesPanel.tsx`, отдельные дескрипторы (PropsEditor) | +| Обработчики событий | `HandlersEditor.tsx`, `HandlerFilePicker.tsx`, `form-dsl.ts` (CONTROL_EVENTS, FORM_EVENTS) | +| Валидация / условная логика | `PropertiesPanel.tsx` (ValidationEditor, ConditionEditor), `FormPreview.tsx` | +| Список файлов в каталоге | `useFormFilesList.ts` | +| Undo/redo | `useHistory.ts`, `App.tsx` (интеграция) | +| Предпросмотр формы | `FormPreview.tsx` | +| Экспорт DSL | `CodeExportDialog.tsx`, `form-dsl.ts` (formToJs, formToJsonString) | +| Шаблоны форм | `templates.ts` | +| Безопасность ссылок (XSS) | дескрипторы с URL (например `hexa.tsx` — CanvasPreview) | diff --git a/packages/kaspersky-ui-normalization-tool/DEPLOY.md b/packages/kaspersky-ui-normalization-tool/DEPLOY.md new file mode 100644 index 00000000..d5e220ee --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/DEPLOY.md @@ -0,0 +1,173 @@ +# Развёртывание UISB на любой ОС + +Инструкция для заказчика: как развернуть проект после получения архива на **Windows**, **macOS** или **Linux**. + +--- + +## Требования + +- **Node.js** версии **18** или выше (рекомендуется LTS). + Проверка: в терминале выполнить `node -v` — должна отобразиться версия (например, `v20.10.0`). + Установка: [nodejs.org](https://nodejs.org/) (выбрать LTS). +- **npm** поставляется с Node.js. Проверка: `npm -v`. +- **Браузер**: для работы с выбором каталога на компьютере нужен **Chrome** или **Edge** (поддержка [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API)). + +--- + +## 1. Получение архива + +Заказчик получает один из вариантов: + +- `uisb-0.0.1.tgz` (рекомендуется) — архив, созданный через `npm pack`; +- либо ZIP/тарболл с исходным кодом **без** папки `node_modules` и без `dist`. + +--- + +## 2. Распаковка + +### Если передан файл `uisb-0.0.1.tgz` + +В терминале (PowerShell, cmd, bash, zsh) перейти в каталог, куда положили архив, затем выполнить распаковку. + +**Windows (PowerShell):** +```powershell +tar -xf uisb-0.0.1.tgz +Rename-Item package uisb +cd uisb +``` + +Если `tar` недоступен, можно использовать 7-Zip или WinRAR: открыть `.tgz` как архив и извлечь содержимое папки `package`, затем переименовать её в `uisb`. + +**Linux / macOS:** +```bash +tar -xzf uisb-0.0.1.tgz +mv package uisb +cd uisb +``` + +### Если передан ZIP или архив с исходниками + +Распаковать архив в любую папку (например, `uisb`) и перейти в неё: + +```bash +cd uisb +``` + +(В Windows — открыть папку в проводнике и в адресной строке ввести `cmd` или `powershell`.) + +--- + +## 3. Установка зависимостей + +В каталоге проекта выполнить **одну** команду (одинаково на всех ОС): + +```bash +npm install +``` + +Дождаться окончания установки (появится папка `node_modules`). + +--- + +## 4. Режим разработки (локальный запуск) + +Запуск сервера разработки: + +```bash +npm run dev +``` + +В терминале появится адрес, например: **http://localhost:5173**. Открыть его в браузере Chrome или Edge. + +Остановка: в терминале нажать `Ctrl+C`. + +--- + +## 5. Сборка для продакшена + +Собрать статические файлы в папку `dist`: + +```bash +npm run build +``` + +После успешной сборки в каталоге появится папка **dist** с файлами для размещения на веб-сервере. + +--- + +## 6. Просмотр собранного приложения локально + +Проверить сборку без веб-сервера: + +```bash +npm run preview +``` + +Откроется локальный сервер (например, http://localhost:4173) с собранным приложением. Остановка: `Ctrl+C`. + +--- + +## 7. Размещение на сервере (любая ОС) + +Собранная папка **dist** — это статический сайт. Её можно: + +- Скопировать в каталог веб-сервера (IIS, nginx, Apache, и т.п.). +- Или развернуть на любом хостинге статики (Netlify, Vercel, GitHub Pages, свой VPS). + +Важно: в `vite.config.ts` задано `base: './'`, поэтому приложение корректно работает при размещении в подкаталог (например, `https://example.com/uisb/`). + +--- + +## Краткая шпаргалка для заказчика + +| Действие | Команда | +|-----------------------|-----------------| +| Установить зависимости | `npm install` | +| Запустить разработку | `npm run dev` | +| Собрать продакшен | `npm run build` | +| Посмотреть сборку | `npm run preview` | + +--- + +## Подготовка архива для передачи (для исполнителя) + +Используйте один из способов. + +### Способ 1: npm pack (рекомендуется, любая ОС) + +В корне проекта: + +```bash +npm run build +npm pack +``` + +Будет создан файл `uisb-0.0.1.tgz` (версия из `package.json`). Его можно передать заказчику; в архиве нет `node_modules` и нет `.git`. + +### Способ 2: Тарболл вручную (Linux / macOS) + +```bash +npm run build +tar -czvf uisb-release.tar.gz --exclude=node_modules --exclude=dist --exclude=.git --exclude=uisb-*.tgz . +``` + +Передать заказчику `uisb-release.tar.gz`. После распаковки заказчик выполняет `npm install` в каталоге проекта. + +### Способ 3: ZIP вручную (Windows, PowerShell) + +В корне проекта (без упаковки `node_modules` и `dist`): + +```powershell +npm run build +$exclude = @('node_modules', 'dist', '.git') +Get-ChildItem -Path . -Recurse | Where-Object { + $path = $_.FullName + -not ($exclude | Where-Object { $path -match [regex]::Escape($_) }) +} | Compress-Archive -DestinationPath ..\uisb-release.zip +``` + +Упрощённый вариант: вручную скопировать в новую папку всё, кроме `node_modules`, `dist` и `.git`, затем сжать эту папку в ZIP и передать заказчику. + +--- + +После передачи заказчику достаточно отдать **архив** и ссылку на эту инструкцию (**DEPLOY.md** в архиве или отдельным файлом). diff --git a/packages/kaspersky-ui-normalization-tool/README.md b/packages/kaspersky-ui-normalization-tool/README.md new file mode 100644 index 00000000..111cfeb7 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/README.md @@ -0,0 +1,61 @@ +# UISB — Работа с JSON + +Одностраничное веб-приложение для работы с JSON-файлами в выбранном каталоге. UI построен на [Hexa UI](https://github.com/KasperskyLab/uif) (Kaspersky Design System). + +## Возможности + +- **Выбор каталога** — кнопка «Выбрать каталог» открывает диалог выбора папки (File System Access API). +- **Список JSON-файлов** — после выбора каталога отображается таблица; клик по строке открывает файл формы. +- **Редактор форм (WYSIWYG)** — левое меню с контролами (Кнопка, Текст, Поле ввода) с иконками. Добавление: двойной клик по элементу в меню или перетаскивание на центральную область. У каждого контрола есть кнопка удаления. +- **Сохранение** — при изменении формы появляется кнопка «Сохранить»; по нажатию текущий состав формы записывается в выбранный JSON-файл (при первом сохранении браузер может запросить разрешение на запись в каталог). + +## Формат JSON формы + +Файл формы — массив контролов. Каждый элемент — объект с полями `type` и `id`: + +- Кнопка: `{ "type": "button", "id": "..." }` +- Текст: `{ "type": "text", "id": "..." }` +- Поле ввода: `{ "type": "input", "id": "..." }` + +## Требования + +- **Браузер**: Chrome или Edge (Desktop) — для выбора каталога нужна поддержка [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) (в Firefox и Safari пока нет). +- **Среда**: для разработки — Node.js 18+. + +## Установка и запуск + +```bash +npm install +npm run dev +``` + +Приложение откроется по адресу http://localhost:5173 (или другому порту из вывода Vite). + +Сборка для продакшена: + +```bash +npm run build +npm run preview # просмотр собранного приложения +``` + +## Передача заказчику + +Для передачи проекта заказчику: + +1. Создать архив: в корне проекта выполнить `npm run release`. Будет создан файл **uisb-0.0.1.tgz** (без node_modules и без .git). +2. Передать заказчику архив и инструкцию по развёртыванию: **DEPLOY.md** (в архиве или отдельно). + +Подробные шаги развёртывания на Windows, macOS и Linux описаны в [DEPLOY.md](./DEPLOY.md). + +--- + +## Структура проекта + +- `src/App.tsx` — главный экран: выбор каталога, список файлов, редактор формы. +- `src/components/ControlsPalette.tsx` — левое меню с контролами (иконки + двойной клик / drag). +- `src/components/FormCanvas.tsx` — центральная область формы (drop zone, превью контролов, удаление). +- `src/hooks/useDirectoryPicker.ts` — выбор каталога. +- `src/hooks/useJsonFilesList.ts` — список JSON-файлов в каталоге. +- `src/hooks/useFormFile.ts` — загрузка/сохранение файла формы, состояние контролов и «не сохранено». +- `src/types/form-dsl.ts` — типы DSL (FormControl, type: button | text | input). +- `src/types/file-system-access.d.ts` — типы File System Access API. diff --git a/packages/kaspersky-ui-normalization-tool/TESTING-GAPS.md b/packages/kaspersky-ui-normalization-tool/TESTING-GAPS.md new file mode 100644 index 00000000..77963f91 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/TESTING-GAPS.md @@ -0,0 +1,177 @@ +# Непокрытые сценарии тестирования — UISB + +## Unit-тесты (Vitest) + +### form-dsl.ts + +**Сериализация / нормализация `row`:** +- `normalizeControl` для `row`: парсит `gap`, `align`, вложенные `children` +- `controlToJson` для `row`: сохраняет `gap`, `align`, рекурсивно сериализует `children` +- `formToJs` с `row`: корректный JS-модуль с вложенными контролами в `children` +- `setRowChildrenInTree`: замена дочерних элементов ряда по `id`, включая вложенные контейнеры + +**Глубокая вложенность:** +- `removeControlFromTree` для контрола внутри `tabs` (не только `grid`) +- `removeControlFromTree` для контрола внутри `row`, вложенного в `grid` +- `forEachControlInTree` для `tabs` с вложенными элементами (`items[].children`) +- `forEachControlInTree` для `row` с вложенными контролами +- `findControlInTree` внутри `tabs`, `row` +- `updateControlInTree` для контрола внутри `tabs`, `row` +- `setGridChildrenInTree` рекурсия через `row` (grid внутри row) +- `setTableChildrenInTree` рекурсия через `row` +- `setTabsChildrenInTree` рекурсия через `row` + +**Обработчики:** +- `normalizeControl` мигрирует legacy `onClickHandler` → `handlers.onClick` для кнопок +- `normalizeFormData` парсит `handlers` на уровне формы +- `formToJs` корректно выводит обработчики с обратным слэшем в пути (Windows) + +**Валидация и условная логика:** +- `controlToJson` для каждого типа правила валидации (`required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, `custom`) +- `controlToJson` сохраняет `visibleWhen`, `disabledWhen` для всех типов контейнеров (`grid`, `table`, `tabs`, `row`) + +**Обратная совместимость:** +- `normalizeControl` приводит тип `'meta'` к `'hexa'` +- `normalizeControl` для `tabs` с пустым `items` +- `normalizeControl` для `tabs` с `activeKey`, не соответствующим ни одному `items[].key` + +**Создание пустой формы:** +- `createEmptyFormData()` возвращает форму с корректной структурой + +### registry.ts + +- `createControl('row')` возвращает `RowControl` с пустым `children`, `gap`, `align` +- `CONTROL_TYPES` не содержит `'row'` +- `ALL_CONTROL_TYPES` содержит `'row'` +- `getPaletteGroups()` содержит «Ряд» в группе «Разметка» +- `getDescriptor('row')` возвращает дескриптор + +### useHistory (хук отмены/повтора) + +- Начальное состояние: `canUndo = false`, `canRedo = false` +- `push` добавляет состояние, `canUndo = true` +- `undo` возвращает предыдущее состояние, `canRedo = true` +- `redo` возвращает отменённое состояние +- `push` после `undo` очищает redo-стек +- Ограничение максимального размера стека +- `reset` сбрасывает до начального состояния + +### useFormFile (загрузка/сохранение формы) + +- `selectFile` загружает файл и устанавливает `formData` +- `saveFile` сериализует `formData` и записывает в файл +- `createNewFile` создаёт файл с пустой формой +- `deleteFile` удаляет файл и сбрасывает состояние +- Гонка при быстром переключении файлов: поздний `selectFile` не перезаписывает ранний +- `closeFile` с несохранёнными изменениями: показ `window.confirm` +- Обработка ошибок при чтении/записи: сообщение через `getErrorMessage` + +### useFormFilesList (список файлов) + +- Построение дерева только из `.js`-файлов +- Вложенные папки отображаются в дереве +- Обновление дерева при создании/удалении файлов + +### FormPreview (превью формы) + +- `collectDefaults` собирает `defaultValue` из вложенных контролов (`grid`, `table`, `tabs`, `row`) +- `validateField` для каждого типа правила: `required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, `custom` +- `evaluateCondition` для каждого оператора: `eq`, `neq`, `gt`, `lt`, `contains`, `empty`, `notEmpty` +- Условное отображение: контрол скрывается при несоответствии `visibleWhen` +- Условная блокировка: контрол блокируется при соответствии `disabledWhen` +- Рендер вложенных контролов из контейнеров + +### getErrorMessage (утилита ошибок) + +- `Error` с `message` → строка сообщения +- `DOMException` → строка сообщения +- Объект с `message` → строка +- Строка → сама строка +- `null` / `undefined` → fallback +- Неизвестный тип → fallback + +--- + +## E2E-тесты (Playwright) + +### Текущее покрытие + +- Загрузка приложения в demo-режиме +- Добавление контролов двойным кликом из палитры (все типы) +- Базовый скриншот-тур по функционалу +- **Предпросмотр формы** (`preview-export.spec.ts`): открытие, возврат в редактор, отображение контролов +- **Экспорт кода** (`preview-export.spec.ts`): диалог экспорта, переключение JS/JSON, копирование, структура +- **Отмена/повтор** (`keyboard-undo.spec.ts`): Ctrl+Z, Ctrl+Shift+Z, кнопки ↩/↪ +- **Клавиатурные сочетания** (`keyboard-undo.spec.ts`): Delete, Ctrl+C/V, Ctrl+D, Escape +- **Редактирование свойств** (`properties-templates.spec.ts`): панель свойств, fieldName, валидация required +- **Шаблоны** (`properties-templates.spec.ts`): выбор шаблона «Форма входа», «Форма регистрации» +- **Ряд (Row)** (`properties-templates.spec.ts`): добавление ряда, редактирование gap/align + +### Непокрытые сценарии + +**Drag and Drop:** +- Перетаскивание контрола из палитры на холст +- Перетаскивание контрола внутрь ячейки сетки (grid) +- Перетаскивание контрола между ячейками сетки +- Перетаскивание контрола в слот ряда (row) +- Перетаскивание контрола во вкладку табов +- Изменение порядка контролов на корневом холсте + +**Редактирование свойств:** +- Изменение текста контрола через правую панель → обновление на холсте +- ~~Изменение `fieldName` → появление бейджа на холсте~~ ✓ +- ~~Добавление правила валидации → появление `*` в бейдже~~ ✓ +- Установка обработчика через file picker → появление бейджа `fn` +- ~~Редактирование свойств `row` (gap, align)~~ ✓ + +**Ряд (Row) контейнер:** +- ~~Добавление ряда на холст~~ ✓ +- Перетаскивание контролов в слоты ряда +- Удаление контрола из ряда +- ~~Изменение `gap` и `align` через панель свойств~~ ✓ +- Ряд с несколькими контролами отображает их горизонтально + +**Превью формы:** +- ~~Открытие предпросмотра~~ ✓ +- Ввод данных в поля формы +- Срабатывание валидации при некорректных данных +- Условное отображение: поле скрывается при изменении зависимого поля +- Отправка формы → вывод данных + +**Экспорт кода:** +- ~~Открытие диалога экспорта~~ ✓ +- ~~Переключение между «JS модуль» и «JSON»~~ ✓ +- ~~Кнопка «Копировать» копирует код в буфер обмена~~ ✓ +- ~~Экспортированный JS содержит корректную структуру~~ ✓ + +**Файловые операции:** +- Сохранение формы (Ctrl+S) +- Создание нового файла +- Удаление файла +- Переключение между файлами → загрузка соответствующей формы + +**Отмена/повтор:** +- ~~Ctrl+Z отменяет последнее действие~~ ✓ +- ~~Ctrl+Shift+Z / Ctrl+Y повторяет отменённое действие~~ ✓ +- ~~Кнопки «Отменить» / «Вернуть» в тулбаре~~ ✓ + +**Клавиатурные сочетания:** +- ~~Delete удаляет выбранный контрол (в т.ч. вложенный)~~ ✓ +- ~~Ctrl+C / Ctrl+V копирует и вставляет контрол~~ ✓ +- ~~Ctrl+D дублирует контрол~~ ✓ +- ~~Escape снимает выделение~~ ✓ + +**Шаблоны:** +- ~~Выбор шаблона из списка~~ ✓ +- Подтверждение замены текущей формы +- ~~Шаблон загружается с корректной структурой~~ ✓ + +**Обработчики событий:** +- Назначение обработчика кнопке через текстовое поле +- Назначение обработчика через file picker (выбор файла) +- Удаление обработчика + +**Схема данных:** +- Добавление поля в схему формы +- Изменение типа поля +- Удаление поля из схемы diff --git a/packages/kaspersky-ui-normalization-tool/e2e/PALETTE-E2E-REPORT.md b/packages/kaspersky-ui-normalization-tool/e2e/PALETTE-E2E-REPORT.md new file mode 100644 index 00000000..80b4ed1a --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/PALETTE-E2E-REPORT.md @@ -0,0 +1,39 @@ +# Отчёт по e2e: добавление компонентов палитры на форму + +**Роль:** только тестирование. Исходный код не изменялся. + +## Что сделано + +- Написаны e2e-сценарии в `e2e/palette-add-all.spec.ts`: для каждого элемента левой палитры проверяется, что после двойного клика по элементу на холсте появляется ровно один новый контрол (по наличию `.control-wrap` внутри `#form-canvas`). +- Сценарии прогонялись, результаты зафиксированы ниже. + +## Запуск + +Для прогона нужны: установленные браузеры Playwright (`npx playwright install`), конфиг с `baseURL` и при необходимости `webServer` (чтобы открывать приложение по URL), e2e-демо режим (в тестах выставляется `window.__E2E_DEMO__ = true` перед переходом). + +```bash +npx playwright install +npm run test:e2e -- e2e/palette-add-all.spec.ts +``` + +## Результаты прогона + +- **Всего сценариев:** 53 (3 разметки + 47 Hexa + 2 прочее). +- **Пройдено:** 50. +- **Упало:** 3. + +## Заявленные баги + +По результатам прогона после двойного клика по элементу палитры контрол на холсте **не появляется** (ожидался один новый `.control-wrap`, фактически 0) для следующих компонентов: + +| № | Компонент | testId | Краткое описание | +|---|-----------|--------|------------------| +| 1 | **Radio** | `palette-radio` | Двойной клик по «Radio» в палитре не приводит к появлению контрола на холсте. | +| 2 | **FieldSet** | `palette-fieldSet` | Двойной клик по «FieldSet» не приводит к появлению контрола на холсте. | +| 3 | **Dropdown** | `palette-dropdown` | Двойной клик по «Dropdown» не приводит к появлению контрола на холсте. | + +**Шаги воспроизведения (для каждого):** открыть приложение в e2e-демо режиме (например, с `window.__E2E_DEMO__ = true`), дважды кликнуть по соответствующему элементу в левой панели, проверить холст — на нём не появляется новый блок контрола. + +**Ожидаемое поведение:** после двойного клика по любому элементу палитры на холсте появляется один новый контрол. + +На этом отчёт тестировщика завершён. diff --git a/packages/kaspersky-ui-normalization-tool/e2e/demo-form.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/demo-form.spec.ts new file mode 100644 index 00000000..655cb16c --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/demo-form.spec.ts @@ -0,0 +1,29 @@ +import { test, expect } from '@playwright/test' + +test.describe('Демо-форма (e2e режим)', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + }) + + test('открывается редактор с пустой формой', async ({ page }) => { + await expect(page.getByText(/Форма: e2e-demo\.json/i)).toBeVisible() + await expect(page.getByRole('heading', { name: /Разметка/i })).toBeVisible() + }) + + test('двойной клик по «Текст» в палитре добавляет контрол на холст', async ({ page }) => { + const paletteText = page.getByTestId('palette-text') + await expect(paletteText).toBeVisible() + await paletteText.dblclick() + const canvas = page.getByTestId('form-canvas') + await expect(canvas.getByText('Текст')).toBeVisible() + }) + + test('двойной клик по «Кнопка» добавляет кнопку на холст', async ({ page }) => { + await page.getByTestId('palette-button').dblclick() + const canvas = page.getByTestId('form-canvas') + await expect(canvas.getByRole('button', { name: 'Кнопка' })).toBeVisible() + }) +}) diff --git a/packages/kaspersky-ui-normalization-tool/e2e/keyboard-undo.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/keyboard-undo.spec.ts new file mode 100644 index 00000000..4f6572db --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/keyboard-undo.spec.ts @@ -0,0 +1,117 @@ +import { test, expect } from '@playwright/test' + +/** + * E2E: Отмена/повтор и клавиатурные сочетания. + * Непокрытые ранее сценарии из TESTING-GAPS.md + */ +test.describe('Отмена / Повтор (Undo / Redo)', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('после добавления контрола Ctrl+Z отменяет действие', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-text').dblclick() + await expect(canvas.getByText('Текст')).toBeVisible() + + await page.keyboard.press('Control+z') + await expect(canvas.getByText('Текст')).not.toBeVisible() + }) + + test('после Undo, Ctrl+Shift+Z восстанавливает действие', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-button').dblclick() + await expect(canvas.getByRole('button', { name: 'Кнопка' })).toBeVisible() + + await page.keyboard.press('Control+z') + await expect(canvas.getByRole('button', { name: 'Кнопка' })).not.toBeVisible() + + await page.keyboard.press('Control+Shift+z') + await expect(canvas.getByRole('button', { name: 'Кнопка' })).toBeVisible() + }) + + test('кнопка «↩» отменяет действие', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-text').dblclick() + await expect(canvas.getByText('Текст')).toBeVisible() + + const undoBtn = page.getByRole('button').filter({ has: page.locator('text=↩') }) + await undoBtn.click() + await expect(canvas.getByText('Текст')).not.toBeVisible() + }) + + test('кнопка «↪» повторяет отменённое действие', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-text').dblclick() + await expect(canvas.getByText('Текст')).toBeVisible() + + const undoBtn = page.getByRole('button').filter({ has: page.locator('text=↩') }) + await undoBtn.click() + await expect(canvas.getByText('Текст')).not.toBeVisible() + + const redoBtn = page.getByRole('button').filter({ has: page.locator('text=↪') }) + await redoBtn.click() + await expect(canvas.getByText('Текст')).toBeVisible() + }) +}) + +test.describe('Клавиатурные сочетания', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('Delete удаляет выбранный контрол', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-text').dblclick() + await expect(canvas.getByText('Текст')).toBeVisible() + + await canvas.locator('.control-wrap').first().click() + await page.keyboard.press('Delete') + await expect(canvas.locator('.control-wrap')).toHaveCount(0) + }) + + test('Ctrl+C / Ctrl+V копирует и вставляет контрол', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-button').dblclick() + await expect(canvas.locator('.control-wrap')).toHaveCount(1) + + await canvas.locator('.control-wrap').first().click() + await page.waitForTimeout(100) + await page.keyboard.press('Control+c') + await page.waitForTimeout(100) + await page.keyboard.press('Control+v') + + await expect(canvas.locator('.control-wrap')).toHaveCount(2) + }) + + test('Ctrl+D дублирует контрол', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-button').dblclick() + await expect(canvas.locator('.control-wrap')).toHaveCount(1) + + await canvas.locator('.control-wrap').first().click() + await page.keyboard.press('Control+d') + await expect(canvas.locator('.control-wrap')).toHaveCount(2) + }) + + test('Escape снимает выделение — можно повторно кликнуть на контрол', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-text').dblclick() + const control = canvas.locator('.control-wrap').first() + await control.click() + + await page.keyboard.press('Escape') + await page.waitForTimeout(100) + + await control.click() + await expect(canvas.locator('.control-wrap').first()).toBeVisible() + }) +}) diff --git a/packages/kaspersky-ui-normalization-tool/e2e/palette-add-all.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/palette-add-all.spec.ts new file mode 100644 index 00000000..55f483f1 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/palette-add-all.spec.ts @@ -0,0 +1,56 @@ +import { test, expect } from '@playwright/test' + +/** + * Сценарии: добавление каждого компонента из панели слева на форму (двойной клик). + * Состав палитры — по getPaletteGroups() / HEXA_PALETTE_GROUPS в коде. + */ +const LAYOUT_ITEMS = [ + { testId: 'palette-grid', name: 'Сетка' }, + { testId: 'palette-table', name: 'Таблица' }, + { testId: 'palette-tabs', name: 'Табы' }, +] + +/** Соответствие componentId → тип в DSL (data-testid палитры: palette-). */ +const COMPONENT_ID_TO_DSL_TYPE: Record = { + Text: 'text', P: 'p', Heading: 'heading', ExpandableText: 'expandableText', Link: 'link', FormLabel: 'formLabel', Label: 'label', HelpMessage: 'helpMessage', Markdown: 'markdown', CodeViewer: 'codeViewer', + Button: 'button', ActionButton: 'actionButton', SegmentedButton: 'segmentedButton', SegmentedControl: 'segmentedControl', + Textbox: 'input', Search: 'search', Checkbox: 'checkbox', Radio: 'radio', Select: 'select', Toggle: 'toggle', Calendar: 'calendar', TimeInput: 'timeInput', + Badge: 'badge', Tag: 'tag', Chip: 'chip', KeyValue: 'keyValue', InformationCard: 'informationCard', StatusCard: 'statusCard', Severity: 'severity', Status: 'status', Indicator: 'indicator', + Alert: 'alert', SectionMessage: 'sectionMessage', Loader: 'loader', ProgressBar: 'progressBar', Tooltip: 'tooltip', Popover: 'popover', + Breadcrumbs: 'breadcrumbs', Pagination: 'pagination', PageHeader: 'pageHeader', Accordion: 'accordion', Divider: 'divider', Space: 'space', + Card: 'card', Field: 'field', FieldSet: 'fieldSet', Dropdown: 'dropdown', Scrollbar: 'scrollbar', +} + +const HEXA_IDS = Object.keys(COMPONENT_ID_TO_DSL_TYPE) + +const OTHER_ITEMS = [ + { testId: 'palette-toolbar', name: 'Тулбар' }, + { testId: 'palette-icon', name: 'Иконка' }, +] + +const ALL_ITEMS: { testId: string; name: string }[] = [ + ...LAYOUT_ITEMS, + ...HEXA_IDS.map((id) => ({ testId: `palette-${COMPONENT_ID_TO_DSL_TYPE[id]}`, name: id })), + ...OTHER_ITEMS, +] + +test.describe('Добавление каждого компонента палитры на форму', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + for (const item of ALL_ITEMS) { + test(`двойной клик по «${item.name}» добавляет контрол на холст`, async ({ page }) => { + const paletteItem = page.getByTestId(item.testId) + await expect(paletteItem).toBeVisible({ timeout: 5000 }) + const canvas = page.getByTestId('form-canvas') + const controlWrapsBefore = await canvas.locator('.control-wrap').count() + await paletteItem.dblclick() + await expect(canvas.locator('.control-wrap')).toHaveCount(controlWrapsBefore + 1, { timeout: 5000 }) + }) + } +}) diff --git a/packages/kaspersky-ui-normalization-tool/e2e/preview-export.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/preview-export.spec.ts new file mode 100644 index 00000000..f003d595 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/preview-export.spec.ts @@ -0,0 +1,79 @@ +import { test, expect } from '@playwright/test' + +/** + * E2E: Предпросмотр формы и экспорт кода. + * Непокрытые ранее сценарии из TESTING-GAPS.md + */ +test.describe('Предпросмотр формы', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('открытие предпросмотра показывает FormPreview и кнопку «Назад к редактору»', async ({ page }) => { + await page.getByRole('button', { name: 'Предпросмотр' }).click() + await expect(page.getByText(/Предпросмотр:/i)).toBeVisible() + await expect(page.getByRole('button', { name: 'Назад к редактору' })).toBeVisible() + }) + + test('кнопка «Назад к редактору» возвращает в редактор', async ({ page }) => { + await page.getByRole('button', { name: 'Предпросмотр' }).click() + await expect(page.getByText(/Предпросмотр:/i)).toBeVisible() + await page.getByRole('button', { name: 'Назад к редактору' }).click() + await expect(page.getByTestId('form-canvas')).toBeVisible() + await expect(page.getByText(/Форма:/i)).toBeVisible() + }) + + test('в предпросмотре отображаются контролы формы', async ({ page }) => { + await page.getByTestId('palette-component-Text').dblclick() + await page.getByRole('button', { name: 'Предпросмотр' }).click() + await expect(page.getByText('Текст')).toBeVisible() + }) +}) + +test.describe('Экспорт кода', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('открытие диалога экспорта показывает «Экспорт DSL»', async ({ page }) => { + await page.getByRole('button', { name: 'Экспорт кода' }).click() + await expect(page.getByText('Экспорт DSL')).toBeVisible() + await expect(page.getByRole('button', { name: 'JS модуль (.js)' })).toBeVisible() + await expect(page.getByRole('button', { name: 'JSON' })).toBeVisible() + }) + + test('переключение между «JS модуль» и «JSON» меняет содержимое', async ({ page }) => { + await page.getByTestId('palette-button').dblclick() + await page.getByRole('button', { name: 'Экспорт кода' }).click() + + const jsContent = page.locator('pre').first() + await expect(jsContent).toContainText('export default') + await expect(jsContent).toContainText('elements') + + await page.getByRole('button', { name: 'JSON' }).click() + await expect(page.locator('pre').first()).toContainText('"elements"') + }) + + test('кнопка «Копировать» копирует код в буфер обмена', async ({ page }) => { + await page.getByRole('button', { name: 'Экспорт кода' }).click() + await page.getByRole('button', { name: 'Копировать' }).click() + await expect(page.getByText('Скопировано!')).toBeVisible() + }) + + test('экспортированный JS содержит корректную структуру', async ({ page }) => { + await page.getByTestId('palette-component-Text').dblclick() + await page.getByRole('button', { name: 'Экспорт кода' }).click() + const pre = page.locator('pre').first() + await expect(pre).toContainText('export default') + await expect(pre).toContainText('name') + await expect(pre).toContainText('elements') + }) +}) diff --git a/packages/kaspersky-ui-normalization-tool/e2e/properties-templates.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/properties-templates.spec.ts new file mode 100644 index 00000000..2036ddb5 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/properties-templates.spec.ts @@ -0,0 +1,98 @@ +import { test, expect } from '@playwright/test' + +/** + * E2E: Редактирование свойств, Шаблоны, Ряд (row). + * Непокрытые ранее сценарии из TESTING-GAPS.md + */ +test.describe('Редактирование свойств', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('клик по контролу показывает панель свойств', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-input').dblclick() + await canvas.locator('.control-wrap').first().click() + await expect(page.getByText('Имя поля (fieldName)')).toBeVisible() + }) + + test('изменение fieldName через панель обновляет контрол', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-input').dblclick() + await canvas.locator('.control-wrap').first().click() + + const fieldNameInput = page.getByPlaceholder('например: email') + await fieldNameInput.fill('email') + await expect(canvas.getByText('email')).toBeVisible() + }) + + test('добавление правила валидации required показывает звёздочку', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByTestId('palette-input').dblclick() + await canvas.locator('.control-wrap').first().click() + + await page.getByRole('button', { name: 'Добавить правило' }).click() + await expect(page.getByText('Привязка данных')).toBeVisible() + await expect(page.locator('text=Привязка данных').locator('..')).toContainText('*') + }) +}) + +test.describe('Шаблоны', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('выбор шаблона «Форма входа» добавляет элементы на холст', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByRole('button', { name: 'Форма входа' }).click() + await expect(canvas.getByText('Вход в систему')).toBeVisible() + await expect(canvas.getByPlaceholder('Email')).toBeVisible() + }) + + test('выбор шаблона «Форма регистрации» загружает структуру', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + await page.getByRole('button', { name: 'Форма регистрации' }).click() + await expect(canvas.getByText('Регистрация')).toBeVisible() + }) +}) + +test.describe('Ряд (Row) контейнер', () => { + test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + ;(window as unknown as { __E2E_DEMO__?: boolean }).__E2E_DEMO__ = true + }) + await page.goto('/') + await expect(page.getByTestId('form-canvas')).toBeVisible() + }) + + test('двойной клик по «Ряд» добавляет ряд на холст', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + const beforeCount = await canvas.locator('.control-wrap').count() + const paletteRow = page.locator('.controls-palette-item').filter({ hasText: /^Ряд$/ }) + await paletteRow.scrollIntoViewIfNeeded() + await paletteRow.dblclick() + await expect(canvas.locator('.control-wrap')).toHaveCount(beforeCount + 1) + }) + + test('редактирование свойств row (gap, align) через панель', async ({ page }) => { + const canvas = page.getByTestId('form-canvas') + const paletteRow = page.locator('.controls-palette-item').filter({ hasText: /^Ряд$/ }) + await paletteRow.scrollIntoViewIfNeeded() + await paletteRow.dblclick() + await canvas.locator('.control-wrap').first().click() + + await expect(page.getByText('Отступ (gap, px)')).toBeVisible() + await expect(page.getByText('Выравнивание')).toBeVisible() + const gapInput = page.locator('input[type="number"]').first() + await gapInput.fill('12') + await expect(gapInput).toHaveValue('12') + }) +}) diff --git a/packages/kaspersky-ui-normalization-tool/e2e/ui-exploration.spec.ts b/packages/kaspersky-ui-normalization-tool/e2e/ui-exploration.spec.ts new file mode 100644 index 00000000..21c84d7e --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/e2e/ui-exploration.spec.ts @@ -0,0 +1,205 @@ +import { test, expect } from '@playwright/test' + +/** + * Комплексный сценарий для исследования UI редактора форм UISB. + * Создаёт скриншоты на каждом важном шаге и проверяет работоспособность функций. + */ + +test.describe('Исследование UI редактора UISB', () => { + test('полный тур по функциям редактора с скриншотами', async ({ page }) => { + // Шаг 1: Открываем приложение БЕЗ demo-режима (для скриншота начального состояния) + await page.goto('/') + await page.waitForLoadState('networkidle') + await page.screenshot({ path: 'e2e-screenshots/01-initial-state.png', fullPage: true }) + console.log('✓ Скриншот 1: Начальное состояние приложения') + + // Проверяем, что видим запрос на выбор каталога + const hasDirectoryPicker = await page.getByText(/выберите каталог/i).isVisible().catch(() => false) + console.log(`Видно ли приглашение выбрать каталог: ${hasDirectoryPicker}`) + + // Шаг 2: Включаем demo-режим через addInitScript и перезагружаем + // ВАЖНО: __E2E_DEMO__ должен быть установлен ПЕРЕД загрузкой приложения + await page.addInitScript(() => { + ;(window as any).__E2E_DEMO__ = true + }) + await page.reload() + await page.waitForLoadState('networkidle') + await page.screenshot({ path: 'e2e-screenshots/02-demo-mode-enabled.png', fullPage: true }) + console.log('✓ Скриншот 2: Demo-режим включён, страница перезагружена') + + // Проверяем, что редактор открылся + await expect(page.getByTestId('form-canvas')).toBeVisible({ timeout: 5000 }) + await expect(page.getByText(/Форма:/i)).toBeVisible() + console.log('✓ Редактор форм открыт') + + // Шаг 3: Исследуем панель палитры слева + const palettePanel = page.locator('[class*="palette"]').first() + await expect(palettePanel).toBeVisible() + + // Ищем заголовок "Разметка" или любой другой заголовок группы + const hasLayoutHeading = await page.getByRole('heading', { name: /Разметка/i }).isVisible().catch(() => false) + console.log(`Найден заголовок "Разметка": ${hasLayoutHeading}`) + + // Прокручиваем палитру, чтобы показать все группы + await page.screenshot({ path: 'e2e-screenshots/03-palette-top.png', fullPage: true }) + console.log('✓ Скриншот 3: Панель палитры (верх)') + + // Подсчитываем количество элементов палитры + const paletteItems = await page.locator('[data-testid^="palette-"]').count() + console.log(`Всего элементов в палитре: ${paletteItems}`) + + // Проверяем наличие основных типов контролов + const expectedControls = [ + { testId: 'palette-grid', name: 'Сетка' }, + { testId: 'palette-table', name: 'Таблица' }, + { testId: 'palette-tabs', name: 'Табы' }, + { testId: 'palette-button', name: 'Кнопка' }, + { testId: 'palette-text', name: 'Текст' }, + { testId: 'palette-input', name: 'Поле ввода' }, + ] + + for (const ctrl of expectedControls) { + const visible = await page.getByTestId(ctrl.testId).isVisible().catch(() => false) + console.log(` - ${ctrl.name} (${ctrl.testId}): ${visible ? '✓ виден' : '✗ не найден'}`) + } + + // Прокручиваем палитру вниз, чтобы показать больше элементов + const paletteContainer = page.locator('[class*="palette"]').first() + await paletteContainer.evaluate(el => el.scrollTo(0, el.scrollHeight / 3)) + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/04-palette-middle.png', fullPage: true }) + console.log('✓ Скриншот 4: Панель палитры (середина)') + + await paletteContainer.evaluate(el => el.scrollTo(0, el.scrollHeight)) + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/05-palette-bottom.png', fullPage: true }) + console.log('✓ Скриншот 5: Панель палитры (низ)') + + // Возвращаемся наверх палитры + await paletteContainer.evaluate(el => el.scrollTo(0, 0)) + await page.waitForTimeout(300) + + // Шаг 4: Проверяем холст (canvas) + const canvas = page.getByTestId('form-canvas') + await expect(canvas).toBeVisible() + const canvasControlsBefore = await canvas.locator('.control-wrap').count() + console.log(`Контролов на холсте до добавления: ${canvasControlsBefore}`) + + // Шаг 5: Добавляем текстовый элемент двойным кликом + const textPaletteItem = page.getByTestId('palette-text') + await expect(textPaletteItem).toBeVisible() + await textPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/06-text-added.png', fullPage: true }) + console.log('✓ Скриншот 6: Добавлен текстовый элемент') + + // Проверяем, что контрол добавился + const canvasControlsAfterText = await canvas.locator('.control-wrap').count() + console.log(`Контролов после добавления текста: ${canvasControlsAfterText}`) + expect(canvasControlsAfterText).toBe(canvasControlsBefore + 1) + + // Шаг 6: Добавляем кнопку + const buttonPaletteItem = page.getByTestId('palette-button') + await expect(buttonPaletteItem).toBeVisible() + await buttonPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/07-button-added.png', fullPage: true }) + console.log('✓ Скриншот 7: Добавлена кнопка') + + // Шаг 7: Добавляем поле ввода + const textboxPaletteItem = page.getByTestId('palette-input') + await expect(textboxPaletteItem).toBeVisible() + await textboxPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/08-textbox-added.png', fullPage: true }) + console.log('✓ Скриншот 8: Добавлено поле ввода') + + // Шаг 8: Добавляем чекбокс + const checkboxPaletteItem = page.getByTestId('palette-checkbox') + await expect(checkboxPaletteItem).toBeVisible() + await checkboxPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/09-checkbox-added.png', fullPage: true }) + console.log('✓ Скриншот 9: Добавлен чекбокс') + + // Шаг 9: Проверяем панель свойств справа + // Кликаем на первый контрол, чтобы увидеть его свойства + const firstControl = canvas.locator('.control-wrap').first() + await firstControl.click() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/10-properties-panel.png', fullPage: true }) + console.log('✓ Скриншот 10: Панель свойств (первый контрол выделен)') + + // Проверяем наличие панели свойств + const hasPropertiesPanel = await page.locator('[class*="properties"]').isVisible().catch(() => false) + console.log(`Панель свойств видна: ${hasPropertiesPanel}`) + + // Шаг 10: Добавляем контейнер Grid + const gridPaletteItem = page.getByTestId('palette-grid') + await expect(gridPaletteItem).toBeVisible() + await gridPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/11-grid-added.png', fullPage: true }) + console.log('✓ Скриншот 11: Добавлена сетка (Grid)') + + // Шаг 11: Добавляем табы + const tabsPaletteItem = page.getByTestId('palette-tabs') + await expect(tabsPaletteItem).toBeVisible() + await tabsPaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/12-tabs-added.png', fullPage: true }) + console.log('✓ Скриншот 12: Добавлены табы') + + // Шаг 12: Добавляем таблицу + const tablePaletteItem = page.getByTestId('palette-table') + await expect(tablePaletteItem).toBeVisible() + await tablePaletteItem.dblclick() + await page.waitForTimeout(300) + await page.screenshot({ path: 'e2e-screenshots/13-table-added.png', fullPage: true }) + console.log('✓ Скриншот 13: Добавлена таблица') + + // Финальный скриншот с полной формой + await page.screenshot({ path: 'e2e-screenshots/14-final-form.png', fullPage: true }) + console.log('✓ Скриншот 14: Финальное состояние формы') + + // Итоговая статистика + const finalControlsCount = await canvas.locator('.control-wrap').count() + console.log(`\n=== ИТОГОВАЯ СТАТИСТИКА ===`) + console.log(`Всего контролов на холсте: ${finalControlsCount}`) + console.log(`Элементов в палитре: ${paletteItems}`) + console.log(`Все скриншоты сохранены в папке e2e-screenshots/`) + + // Проверяем финальное количество + expect(finalControlsCount).toBeGreaterThanOrEqual(7) + }) + + test('проверка структуры UI и доступности элементов', async ({ page }) => { + await page.addInitScript(() => { + ;(window as any).__E2E_DEMO__ = true + }) + await page.goto('/') + await page.waitForLoadState('networkidle') + + // Проверяем основные панели + console.log('\n=== СТРУКТУРА UI ===') + + // Левая панель (палитра) + const paletteExists = await page.locator('[class*="palette"]').first().isVisible() + console.log(`Левая панель (палитра): ${paletteExists ? '✓' : '✗'}`) + + // Центральная панель (холст) + const canvasExists = await page.getByTestId('form-canvas').isVisible() + console.log(`Центральная панель (холст): ${canvasExists ? '✓' : '✗'}`) + + // Правая панель (свойства) - может быть видна только при выделении контрола + const propertiesExists = await page.locator('[class*="properties"]').isVisible().catch(() => false) + console.log(`Правая панель (свойства): ${propertiesExists ? '✓ (видна)' : 'скрыта (норма, если нет выделения)'}`) + + // Заголовок формы + const formTitleExists = await page.getByText(/Форма:/i).isVisible() + console.log(`Заголовок формы: ${formTitleExists ? '✓' : '✗'}`) + + await page.screenshot({ path: 'e2e-screenshots/20-ui-structure.png', fullPage: true }) + console.log('✓ Скриншот структуры UI сохранён') + }) +}) diff --git a/packages/kaspersky-ui-normalization-tool/index.html b/packages/kaspersky-ui-normalization-tool/index.html new file mode 100644 index 00000000..cde26358 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/index.html @@ -0,0 +1,13 @@ + + + + + + + UISB — Работа с JSON + + +
+ + + diff --git a/packages/kaspersky-ui-normalization-tool/jsons/form-1774124967510.js b/packages/kaspersky-ui-normalization-tool/jsons/form-1774124967510.js new file mode 100644 index 00000000..56b6d075 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/jsons/form-1774124967510.js @@ -0,0 +1,32 @@ +export default { + name: "", + id: "form-1774124967517", + elements: [ + { + "type": "grid", + "id": "grid-1774124980818-7sslddg", + "rows": 2, + "cols": 2, + "children": [ + { + "type": "text", + "id": "text-1774124983057-g88o6vy", + "defaultValue": "Hello world!", + "text": "Текст" + }, + null, + null, + { + "type": "button", + "id": "button-1774124998740-k5kscyr", + "defaultValue": "Click me!", + "handlers": { + "onClick": () => import("./handlers/click.js") + }, + "text": "Кнопка", + "mode": "dangerFilled" + } + ] + } + ] +} diff --git a/packages/kaspersky-ui-normalization-tool/jsons/handlers/click.js b/packages/kaspersky-ui-normalization-tool/jsons/handlers/click.js new file mode 100644 index 00000000..b184a14b --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/jsons/handlers/click.js @@ -0,0 +1,3 @@ +export default function ButtonClick () { + alert('o!') +} diff --git a/packages/kaspersky-ui-normalization-tool/package-lock.json b/packages/kaspersky-ui-normalization-tool/package-lock.json new file mode 100644 index 00000000..84e215aa --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/package-lock.json @@ -0,0 +1,9140 @@ +{ + "name": "uisb", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "uisb", + "version": "0.0.1", + "dependencies": { + "@kaspersky/hexa-ui": "^6.198.2", + "@kaspersky/hexa-ui-icons": "^2.6.11", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@playwright/test": "^1.49.0", + "@testing-library/jest-dom": "^6.4.0", + "@testing-library/react": "^12.1.5", + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "jsdom": "^24.0.0", + "less": "^4.2.0", + "react-is": "^17.0.2", + "typescript": "^5.2.2", + "vite": "^5.2.0", + "vitest": "^2.1.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha1-m5NmJXz/zEfbQrnQIDu1ksE8Apg=", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.8.3.tgz", + "integrity": "sha512-HGlIQZzrEbAhpJR6+IGdzfbPym94Owr6JZkJ2QCCnOkPVIWMO2xgIVcOKnl8YcpijIo39V7l2qQL5fmtw56cMw==", + "license": "MIT", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.3.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "lodash": "^4.17.15", + "rc-util": "^5.9.4" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", + "license": "MIT" + }, + "node_modules/@ant-design/react-slick": { + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.28.4.tgz", + "integrity": "sha1-iylrh618euh38qUnuBt+69ndKak=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "lodash": "^4.17.21", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.0.tgz", + "integrity": "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.7.1.tgz", + "integrity": "sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz", + "integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", + "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", + "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-xml": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", + "integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/xml": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.10.8", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.8.tgz", + "integrity": "sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.4.tgz", + "integrity": "sha512-ABc9vJ8DEmvOWuH26P3i8FpMWPQkduD9Rvba5iwb6O3hxASgclm3T3krGo8NASXkHCidz6b++LWlzWIUfEPSWw==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.0.tgz", + "integrity": "sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==", + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.36.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.1.tgz", + "integrity": "sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.5.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha1-2yixxDaKJZtgqXMR1qlS1P0BrBo=", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha1-Gb8PWvGRSREcQNmLsM+CEZ9dnus=", + "license": "MIT" + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha1-3qyzib1u530ef8rMzp4WxcfnjgQ=", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha1-dyESkcGQCnALinjPr9oxYNdpSe0=", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kaspersky/hexa-ui": { + "version": "6.323.10", + "resolved": "https://registry.npmjs.org/@kaspersky/hexa-ui/-/hexa-ui-6.323.10.tgz", + "integrity": "sha512-iqm1sQ/MX9Nuntf/TGodlF4aJh1K68oud4SmJxA82fLv/Fr55xKl9PvzOksIdZUNwEX3qb2LiTG90sOfsYIgXw==", + "bundleDependencies": [ + "style-inject" + ], + "license": "Apache-2.0", + "dependencies": { + "@codemirror/commands": "6.7.1", + "@codemirror/lang-html": "6.4.9", + "@codemirror/lang-javascript": "6.2.2", + "@codemirror/lang-json": "6.0.1", + "@codemirror/lang-xml": "6.1.0", + "@codemirror/language": "6.10.8", + "@codemirror/state": "6.5.0", + "@codemirror/view": "6.36.1", + "@kaspersky/hexa-ui-core": "0.17.2", + "@lezer/highlight": "1.2.1", + "@popperjs/core": "2.11.2", + "@tanstack/react-virtual": "3.10.1", + "@types/markdown-it": "10.0.2", + "@xterm/addon-clipboard": "0.1.0", + "@xterm/addon-fit": "0.10.0", + "@xterm/addon-web-links": "0.11.0", + "@xterm/addon-webgl": "0.18.0", + "@xterm/xterm": "5.5.0", + "antd": "4.18.8", + "classnames": "2.3.1", + "clipboard-copy": "4.0.1", + "date-fns": "2.30.0", + "dompurify": "3.3.1", + "hotkeys-js": "3.8.7", + "i18next": "22.5.1", + "i18next-browser-languagedetector": "7.1.0", + "lodash": "4.17.23", + "mark.js": "8.11.1", + "markdown-it": "12.3.2", + "rc-collapse": "4.0.0", + "rc-dropdown": "4.2.1", + "rc-menu": "9.16.1", + "rc-select": "14.1.2", + "rc-tooltip": "6.4.0", + "rc-upload": "4.8.1", + "react-custom-scrollbars-2": "4.5.0", + "react-diff-view": "3.3.1", + "react-i18next": "12.3.1", + "react-imask": "6.4.2", + "react-resizable": "3.0.4", + "react-sortable-hoc": "2.0.0", + "react-zoom-pan-pinch": "2.1.3", + "resize-observer-polyfill": "1.5.1", + "style-inject": "0.3.0", + "styled-components": "5.3.3", + "unidiff": "1.0.4", + "uuid": "9.0.0" + }, + "peerDependencies": { + "@kaspersky/hexa-ui-icons": "^2.13.0", + "react": "16.x || 17.x || 18.x", + "react-dom": "16.x || 17.x || 18.x", + "typescript": ">=4.0.0" + } + }, + "node_modules/@kaspersky/hexa-ui-core": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@kaspersky/hexa-ui-core/-/hexa-ui-core-0.17.2.tgz", + "integrity": "sha512-n9SX1aHRYvpi2vt/fqJHo5EbD1v0pXTtRzQJ4157x2sBBtLwXxGxhgef+MQcQbxlJR6NPiv4vCvVWWxJa4rEoA==", + "license": "Apache-2.0" + }, + "node_modules/@kaspersky/hexa-ui-icons": { + "version": "2.13.4", + "resolved": "https://registry.npmjs.org/@kaspersky/hexa-ui-icons/-/hexa-ui-icons-2.13.4.tgz", + "integrity": "sha512-Y/C1Y/D7N30FAjh11X1mDT4BZLiA2JiJmwqo7Dvda9Eq1KB8UyYOcqkTiWwc1ER2+71TAbj/uNdKFy4MfYJPqg==", + "license": "Apache-2.0", + "peerDependencies": { + "@kaspersky/hexa-ui-core": "0.x", + "react": "16.x || 17.x || 18.x", + "react-dom": "16.x || 17.x || 18.x" + } + }, + "node_modules/@lezer/common": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.1.tgz", + "integrity": "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==", + "license": "MIT" + }, + "node_modules/@lezer/css": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.1.tgz", + "integrity": "sha512-PYAKeUVBo3HFThruRyp/iK91SwiZJnzXh8QzkQlwijB5y+N5iB28+iLk78o2zmKqqV0uolNhCwFqB8LA7b0Svg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/html": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.13.tgz", + "integrity": "sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz", + "integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.8.tgz", + "integrity": "sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/xml": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.6.tgz", + "integrity": "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po=", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@playwright/test": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", + "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz", + "integrity": "sha1-gwvq7EtAkanpOYrFD4Zd3qUhhrk=", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rc-component/portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", + "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/portal/node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/@rc-component/trigger": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.3.1.tgz", + "integrity": "sha512-ORENF39PeXTzM+gQEshuk460Z8N4+6DkjpxlpE7Q3gYy1iBpLrx0FOJz3h62ryrJZ/3zCAUIkT1Pb/8hHWpb3A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@rc-component/portal": "^1.1.0", + "classnames": "^2.3.2", + "rc-motion": "^2.0.0", + "rc-resize-observer": "^1.3.1", + "rc-util": "^5.44.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/trigger/node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.1.tgz", + "integrity": "sha512-h5kNeE+yQwspjl9E3sJ3UYQu/MuspNOBT5cVdc+NA0uU9B1XSkxbzp86teV3arMDVcQ4ESExqs4JyIirYAMcuA==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.1.tgz", + "integrity": "sha512-JDi3wU1HIxuxx8BgD7Ix8IXlelCKdTJIh9c0qBs+QXHdix3mjMbkXI3wOq0TuCx1w1RGgzZue34QrM/NPdp/sw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", + "integrity": "sha1-uySPcvAqWsnZSd6gcnkJX6V3ljs=", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0", + "@types/react-dom": "<18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "<18.0.0", + "react-dom": "<18.0.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-10.0.2.tgz", + "integrity": "sha1-+TM0uceCHdsZhl39kez2iAlMJiY=", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "17.0.91", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.91.tgz", + "integrity": "sha512-xauZca6qMeCU3Moy0KxCM9jtf1vyk6qRYK39Ryf3afUqwgNUjRIGoDdS9BcGWgAMGSg1hvP4XcmlYrM66PtqeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "^0.16", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.26.tgz", + "integrity": "sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xterm/addon-clipboard": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.1.0.tgz", + "integrity": "sha512-zdoM7p53T5sv/HbRTyp4hY0kKmEQ3MZvAvEtiXqNIHc/JdpqwByCtsTaQF5DX2n4hYdXRPO4P/eOS0QEhX1nPw==", + "license": "MIT", + "dependencies": { + "js-base64": "^3.7.5" + }, + "peerDependencies": { + "@xterm/xterm": "^5.4.0" + } + }, + "node_modules/@xterm/addon-fit": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", + "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==", + "license": "MIT", + "peerDependencies": { + "@xterm/xterm": "^5.0.0" + } + }, + "node_modules/@xterm/addon-web-links": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.11.0.tgz", + "integrity": "sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==", + "license": "MIT", + "peerDependencies": { + "@xterm/xterm": "^5.0.0" + } + }, + "node_modules/@xterm/addon-webgl": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.18.0.tgz", + "integrity": "sha512-xCnfMBTI+/HKPdRnSOHaJDRqEpq2Ugy8LEj9GiY4J3zJObo3joylIFaMvzBwbYRg8zLtkO0KQaStCeSfoaI2/w==", + "license": "MIT", + "peerDependencies": { + "@xterm/xterm": "^5.0.0" + } + }, + "node_modules/@xterm/xterm": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", + "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/add-px-to-style": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-px-to-style/-/add-px-to-style-1.0.0.tgz", + "integrity": "sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo=", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antd": { + "version": "4.18.8", + "resolved": "https://registry.npmjs.org/antd/-/antd-4.18.8.tgz", + "integrity": "sha1-q9elR5AxHHztQRI8+fluR1gsYps=", + "license": "MIT", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons": "^4.7.0", + "@ant-design/react-slick": "~0.28.1", + "@babel/runtime": "^7.12.5", + "@ctrl/tinycolor": "^3.4.0", + "classnames": "^2.2.6", + "copy-to-clipboard": "^3.2.0", + "lodash": "^4.17.21", + "memoize-one": "^6.0.0", + "moment": "^2.25.3", + "rc-cascader": "~3.2.1", + "rc-checkbox": "~2.3.0", + "rc-collapse": "~3.1.0", + "rc-dialog": "~8.6.0", + "rc-drawer": "~4.4.2", + "rc-dropdown": "~3.2.5", + "rc-field-form": "~1.22.0-2", + "rc-image": "~5.2.5", + "rc-input-number": "~7.3.0", + "rc-mentions": "~1.6.1", + "rc-menu": "~9.2.1", + "rc-motion": "^2.4.4", + "rc-notification": "~4.5.7", + "rc-pagination": "~3.1.9", + "rc-picker": "~2.5.17", + "rc-progress": "~3.2.1", + "rc-rate": "~2.9.0", + "rc-resize-observer": "^1.2.0", + "rc-select": "~14.0.0-alpha.15", + "rc-slider": "~9.7.4", + "rc-steps": "~4.1.0", + "rc-switch": "~3.2.0", + "rc-table": "~7.23.0", + "rc-tabs": "~11.10.0", + "rc-textarea": "~0.3.0", + "rc-tooltip": "~5.1.1", + "rc-tree": "~5.4.3", + "rc-tree-select": "~5.1.1", + "rc-trigger": "^5.2.10", + "rc-upload": "~4.3.0", + "rc-util": "^5.14.0", + "scroll-into-view-if-needed": "^2.2.25" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/antd/node_modules/rc-collapse": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.4.tgz", + "integrity": "sha1-Bj4z/MQno3jmPadXiYzR+6Ymlnk=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.2.1", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/antd/node_modules/rc-dropdown": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.5.tgz", + "integrity": "sha1-whHlcdKdFef3JbWnX8jH83H8M0g=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-trigger": "^5.0.4" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/antd/node_modules/rc-menu": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.2.1.tgz", + "integrity": "sha1-b75H9IRjY7uBpaIfCWACbDraSXo=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/antd/node_modules/rc-select": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.0.6.tgz", + "integrity": "sha1-k74LGFqdZtyEeV4HkSHw9lMQ2L8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.2.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/antd/node_modules/rc-tooltip": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz", + "integrity": "sha1-lBeO0WLQJSvEmTtyX13CrA/M8VQ=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/antd/node_modules/rc-upload": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.6.tgz", + "integrity": "sha512-Bt7ESeG5tT3IY82fZcP+s0tQU2xmo1W6P3S8NboUUliquJLQYLkUcsaExi3IlBVr43GQMCjo30RA2o0i70+NjA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA=", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha1-t5hCCtvrHego2ErNii4j0+/oXo0=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", + "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE=", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha1-38+jiR4wbsHa0QXQ6I9EF7hTXo4=", + "license": "MIT" + }, + "node_modules/clipboard-copy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-4.0.1.tgz", + "integrity": "sha1-Mm75cm1P/nLZqCp7vhk3neaSAX0=", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha1-CSRU6pWEp7etVXMGKyqH9ZAPxIA=", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha1-q7WE1fEM0Rlt/FWqA3AVkq4/ezc=", + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8=", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==", + "license": "MIT" + }, + "node_modules/dom-css": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dom-css/-/dom-css-2.1.0.tgz", + "integrity": "sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI=", + "license": "MIT", + "dependencies": { + "add-px-to-style": "1.0.0", + "prefix-style": "2.0.1", + "to-camel-case": "1.0.0" + } + }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "license": "ISC" + }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha1-mS0xKc999ocLlsV4WMJJoSD4uLU=", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha1-i7Ppx9Rjvkl2/4iPdrSAnrwugR8=", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha1-LupSkHAvJquP5TcDcP+GyWXSESM=", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha1-IRst2WWcsDlLBz5zI6w8kz1SICc=", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha1-BAT+TuK6L2B/Dg7DyAuumUEzuDQ=", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha1-MqbudsPX9S1GsrGuXZP+qFgKJeA=", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gitdiff-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/gitdiff-parser/-/gitdiff-parser-0.3.1.tgz", + "integrity": "sha512-YQJnY8aew65id8okGxKCksH3efDCJ9HzV7M9rsvd65habf39Pkh4cgYJ27AaoDMqo1X98pgNJhNMrm/kpV7UVQ==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM=", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha1-vUvpi7BC+D15b344EZkfvoKg00s=", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha1-7OCsr3HWLClpwuxZ/v9CpLGoW0U=", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=", + "license": "MIT" + }, + "node_modules/hotkeys-js": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz", + "integrity": "sha1-wWyrl4tT1yQvhgyjky6Xa5I5mYE=", + "license": "MIT" + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha1-38EBc0fOn3fIFBpQfyMwQMWcVdI=", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/i18next": { + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz", + "integrity": "sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.6" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.1.0.tgz", + "integrity": "sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.19.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha1-pS+AvzjaGVLrXGgXkHGYcaGnJQE=", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/imask": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/imask/-/imask-6.6.3.tgz", + "integrity": "sha512-a9MTDhm+ET4G2IRcdUGuVTXHS05WsRNPGM5CeNJnXiXuoi4zv7g0/UDFLlRF4lBBeb8EWds4C4JVwhI0nuAIug==", + "license": "MIT", + "engines": { + "npm": ">=4.0.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha1-0jE2LlOgf/Kw4Op/7QSRYf/RYoM=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha1-Fx7W8Z46xVQ5Tt94yqBXhKRb67U=", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha1-4SIvRt3ahd6tD9HJ3xMXYOd3VcE=", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha1-ivHkwSISRMxiRZ+vOJQNTmRKVyM=", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/js-base64": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "license": "BSD-3-Clause" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "24.1.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.3.tgz", + "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha1-kziAKjDTtmBfvgYT4JQAjKjAWhM=", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true, + "license": "MIT" + }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "license": "MIT", + "dependencies": { + "string-convert": "^0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/less": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.5.1.tgz", + "integrity": "sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha1-qYuvRM5FpVDvtNScdp0HUkzC+i4=", + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha1-VTIeswn+u8WcSAHZMackUqaB0oY=", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo=", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha1-GA8fnr74sOY45BZq1S24eb6y/8U=", + "license": "MIT" + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha1-v5Kskig/6YP+Tej/ir+1rXLNDJA=", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "license": "MIT" + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha1-slkbhx7YKUiu5HJ9xqvO7qyMEEU=", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha1-pj9oFnOzBXH76LwlaGrnRu76mGk=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true, + "license": "MIT" + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha1-4rXb7eAOf6m8NjYH9TMn6LBzGJs=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha1-O6ODNzNkbZ0+SZWUbBNlpn+wekI=", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha1-cjwJkgg2um0+WvAZ+SvAlxwC5RQ=", + "license": "MIT" + }, + "node_modules/prefix-style": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/prefix-style/-/prefix-style-2.0.1.tgz", + "integrity": "sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY=", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha1-IYGHn96lGnpYUfs52SD6pj8B2I4=", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha1-B0SWkK1Fd30ZJKwquy/IiV26g2s=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha1-Z9h78aaU9IQ1zzMsJK8QIUoxQLU=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=", + "license": "MIT" + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha1-M0WUG0FTy50ILY7uTNogFqmu9/Y=", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM=", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk=", + "license": "MIT", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/rc-align": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.26.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-cascader": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.2.9.tgz", + "integrity": "sha1-uZP6KCnXfpy5jPS3cR4TobGBLbY=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.3.1", + "rc-select": "~14.0.0-alpha.23", + "rc-tree": "~5.4.3", + "rc-util": "^5.6.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-cascader/node_modules/rc-select": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.0.6.tgz", + "integrity": "sha1-k74LGFqdZtyEeV4HkSHw9lMQ2L8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.2.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-checkbox": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.2.tgz", + "integrity": "sha1-+Rs2eMftsrqoEhyUg8Zk+m8K78E=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-4.0.0.tgz", + "integrity": "sha512-SwoOByE39/3oIokDs/BnkqI+ltwirZbP8HZdq1/3SkPSBi7xDdvWHTp7cpNI9ullozkR6mwTWQi6/E/9huQVrA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.6.0.tgz", + "integrity": "sha1-OyKNrAhd5e7YxiN/MRYhBGh0Quc=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.6.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.4.3.tgz", + "integrity": "sha1-IJSTeoROVdyWRCNqLZ+6ecNE4yE=", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.7.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dropdown": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.1.tgz", + "integrity": "sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.6", + "rc-util": "^5.44.1" + }, + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/rc-field-form": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.22.1.tgz", + "integrity": "sha1-C9L05zD/LwcVKdAL7yjgYjYokPU=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4", + "async-validator": "^4.0.2", + "rc-util": "^5.8.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">= 16.9.0", + "react-dom": ">= 16.9.0" + } + }, + "node_modules/rc-image": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-5.2.5.tgz", + "integrity": "sha1-ROb/yEJiaCeWDnq3LhwNbzqM5EA=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-dialog": "~8.6.0", + "rc-util": "^5.0.6" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-input-number": { + "version": "7.3.11", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-7.3.11.tgz", + "integrity": "sha512-aMWPEjFeles6PQnMqP5eWpxzsvHm9rh1jQOWXExUEIxhX62Fyl/ptifLHOn17+waDG1T/YUb6flfJbvwRhHrbA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.23.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.6.5.tgz", + "integrity": "sha1-2VFqvRmnV8Z03xyIo0WWKP6VoUk=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-menu": "~9.3.2", + "rc-textarea": "^0.3.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions/node_modules/rc-menu": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.3.2.tgz", + "integrity": "sha1-u4QtN+v3HakSvqIBz37wonJnrUk=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-menu": { + "version": "9.16.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.16.1.tgz", + "integrity": "sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.0.0", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.3.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.5.tgz", + "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.44.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-notification": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.7.tgz", + "integrity": "sha1-Jl5uagwaD6xj1qvU2DLrj/MVIvE=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.2.0", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-overflow": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.5.0.tgz", + "integrity": "sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-pagination": { + "version": "3.1.17", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.17.tgz", + "integrity": "sha512-/BQ5UxcBnW28vFAcP2hfh+Xg15W0QZn8TWYwdCApchMH1H0CxiaUUcULP8uXcFM1TygcdKWdt3JqsL9cTAfdkQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-picker": { + "version": "2.5.19", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.5.19.tgz", + "integrity": "sha1-c9B1RvrDmS8L+r8niWVKyto55G8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "2.x", + "dayjs": "1.x", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-progress": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.2.4.tgz", + "integrity": "sha1-QDas2uJWZDhUW8TfIgMki6uvdUk=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-rate": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.3.tgz", + "integrity": "sha512-2THssUSnRhtqIouQIIXqsZGzRczvp4WsH4WvGuhiwm+LG2fVpDUJliP9O1zeDOZvYfBE/Bup4SgHun/eCkbjgQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz", + "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.44.1", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-select": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.1.2.tgz", + "integrity": "sha512-/QgarL/T/d7MIPcoRmTca2TWHBoHBM1EQIgdaFmvl3qsYRSbrb8NpWcQuJoc9fprXERWxdYSTUThQObHvdEVBQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.2.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-slider": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.5.tgz", + "integrity": "sha1-GTFBxo6Zsdw7dG2utr+FKUb1t/Q=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.16.1", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-slider/node_modules/rc-tooltip": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.3.1.tgz", + "integrity": "sha512-e6H0dMD38EPaSPD2XC8dRfct27VvT2TkPdoBSuNl3RRZ5tspiY/c5xYEmGC0IrABvMBgque4Mr2SMZuliCvoiQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.3.1", + "rc-trigger": "^5.3.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-steps": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.4.tgz", + "integrity": "sha1-C6gtsgLVnKUtBpPcmIDdFFsZ3CM=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.2", + "classnames": "^2.2.3", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-switch": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz", + "integrity": "sha1-0AH3fxJmTVJZW09vtCXdnmb7qOg=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.0.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-table": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.23.2.tgz", + "integrity": "sha1-9vkG6Pr7Bd2/3WnUUP64dc4mCns=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.1.0", + "rc-util": "^5.14.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs": { + "version": "11.10.8", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.10.8.tgz", + "integrity": "sha1-gy00Jb3iMrnERHB1td7vPi/vpI8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "^3.2.0", + "rc-menu": "~9.3.2", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs/node_modules/rc-dropdown": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.6.2.tgz", + "integrity": "sha1-0juLJ2KUGsOeZlZzlG9nypw5EY8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-trigger": "^5.0.4", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/rc-tabs/node_modules/rc-menu": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.3.2.tgz", + "integrity": "sha1-u4QtN+v3HakSvqIBz37wonJnrUk=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-textarea": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.7.tgz", + "integrity": "sha1-mHFCiR797bd0iDwH4vUbMY/eWhE=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.7.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.4.0.tgz", + "integrity": "sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.3.1", + "rc-util": "^5.44.3" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.4.4.tgz", + "integrity": "sha1-LqNmOtPFZq73mka6ah4FDSQyPgE=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.4.2" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.1.5.tgz", + "integrity": "sha1-7VHMRetJDRjWfrpoZOnHMhGZ/MA=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~14.0.0-alpha.8", + "rc-tree": "~5.4.3", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select/node_modules/rc-select": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.0.6.tgz", + "integrity": "sha1-k74LGFqdZtyEeV4HkSHw9lMQ2L8=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.2.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-trigger": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.19.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-upload": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.8.1.tgz", + "integrity": "sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.44.4", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz", + "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/rc-virtual-list": { + "version": "3.19.2", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.19.2.tgz", + "integrity": "sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha1-0LXMUW0p6z7uOD91tihkz7aAADc=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-custom-scrollbars-2": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-custom-scrollbars-2/-/react-custom-scrollbars-2-4.5.0.tgz", + "integrity": "sha512-/z0nWAeXfMDr4+OXReTpYd1Atq9kkn4oI3qxq3iMXGQx1EEfwETSqB8HTAvg1X7dEqcCachbny1DRNGlqX5bDQ==", + "license": "MIT", + "dependencies": { + "dom-css": "^2.0.0", + "prop-types": "^15.5.10", + "raf": "^3.1.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-diff-view": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/react-diff-view/-/react-diff-view-3.3.1.tgz", + "integrity": "sha512-Xeh3g5p6IUN4GvtSLAeNDyZwC9mYUqpVhCN6973B7pBywn+d5SMjTKL0pTt3WyXBCzhwCX8STk2Az2tEizCwCA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.2", + "diff-match-patch": "^1.0.5", + "gitdiff-parser": "^0.3.1", + "lodash": "^4.17.21", + "shallow-equal": "^3.1.0", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/react-diff-view/node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha1-7P+2hF462Nv83EmPDQqTlzZQLCM=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-i18next": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.3.1.tgz", + "integrity": "sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.6", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 19.0.0", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-imask": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/react-imask/-/react-imask-6.4.2.tgz", + "integrity": "sha512-xBGZyM0RwQ/ujX7f2ccaYxE41eB81q5Yqek6SYXAq6XT88+TdCSmIpgh5GeygRedPJu6tnnN8OXrUMTc2uFNSw==", + "license": "MIT", + "dependencies": { + "imask": "^6.4.2", + "prop-types": "^15.7.2" + }, + "engines": { + "npm": ">=4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-resizable": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz", + "integrity": "sha1-qiAQjv8oxSxv3apJq/vvir9eWBs=", + "license": "MIT", + "dependencies": { + "prop-types": "15.x", + "react-draggable": "^4.0.3" + }, + "peerDependencies": { + "react": ">= 16.3" + } + }, + "node_modules/react-resizable/node_modules/react-draggable": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.5.0.tgz", + "integrity": "sha512-VC+HBLEZ0XJxnOxVAZsdRi8rD04Iz3SiiKOoYzamjylUcju/hP9np/aZdLHf/7WOD268WMoNJMvYfB5yAK45cw==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/react-sortable-hoc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz", + "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.2.0", + "invariant": "^2.2.4", + "prop-types": "^15.5.7" + }, + "peerDependencies": { + "prop-types": "^15.5.7", + "react": "^16.3.0 || ^17.0.0", + "react-dom": "^16.3.0 || ^17.0.0" + } + }, + "node_modules/react-zoom-pan-pinch": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-2.1.3.tgz", + "integrity": "sha1-O4RZQgA0MTbA1Dl8M/7DjcDuBq0=", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha1-5Ve3mYMWu1PJ8fVvpiY1LGljBZ8=", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true, + "license": "MIT" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ=", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4=", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "dev": true, + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha1-S67jlDbjSqk7SHS93L8P6Li1DpE=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "license": "MIT", + "dependencies": { + "compute-scroll-into-view": "^1.0.20" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-equal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz", + "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==", + "license": "MIT" + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha1-GI1SHelbkIdAT9TctosT3wrk5/g=", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=", + "license": "MIT" + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha1-wy4c7pQLazQyx3G8LFS8znPNMAE=", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-mod": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", + "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==", + "license": "MIT" + }, + "node_modules/styled-components": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", + "integrity": "sha1-MSo9mlSfRwjw+w7cgp6zS94DJ0M=", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^0.8.8", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha1-btpL00SjyUrqN21MwxvHcxEDngk=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I=", + "dev": true, + "license": "MIT" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-camel-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-camel-case/-/to-camel-case-1.0.0.tgz", + "integrity": "sha1-GlYFSy+daWKYzmamCJcyK29CPkY=", + "license": "MIT", + "dependencies": { + "to-space-case": "^1.0.0" + } + }, + "node_modules/to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "license": "MIT", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha1-G/IH9LKPkVg2ZstfvTJ4hzAc1fQ=", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha1-nEEagCpAmpH8bPdAgbq6NLJEmaw=", + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unidiff": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unidiff/-/unidiff-1.0.4.tgz", + "integrity": "sha512-ynU0vsAXw0ir8roa+xPCUHmnJ5goc5BTM2Kuc3IJd8UwgaeRs7VSD5+eeaQL+xp1JtB92hu/Zy/Lgy7RZcr1pQ==", + "license": "MIT", + "dependencies": { + "diff": "^5.1.0" + } + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha1-nTwvc2wddd070r5QfcwRHx4uqcE=", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha1-JWtOGIK+feu/AdBfCqIDl3jqCAo=", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha1-Bg/hvLf5x2/ioX24apvDq4lCEMs=", + "dev": true, + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0=", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/packages/kaspersky-ui-normalization-tool/package.json b/packages/kaspersky-ui-normalization-tool/package.json new file mode 100644 index 00000000..c5e7d0be --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/package.json @@ -0,0 +1,44 @@ +{ + "name": "uisb", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "release": "npm run build && npm pack", + "test": "vitest run", + "test:watch": "vitest", + "test:e2e": "playwright test", + "test:e2e:headed": "playwright test --headed", + "test:e2e:ui": "playwright test --ui" + }, + "dependencies": { + "@kaspersky/hexa-ui": "^6.198.2", + "@kaspersky/hexa-ui-icons": "^2.6.11", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "less": "^4.2.0", + "typescript": "^5.2.2", + "vite": "^5.2.0", + "vitest": "^2.1.0", + "@testing-library/react": "^12.1.5", + "@testing-library/jest-dom": "^6.4.0", + "jsdom": "^24.0.0", + "react-is": "^17.0.2", + "@playwright/test": "^1.49.0" + } +} diff --git a/packages/kaspersky-ui-normalization-tool/playwright.config.ts b/packages/kaspersky-ui-normalization-tool/playwright.config.ts new file mode 100644 index 00000000..9fd73c7e --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/playwright.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, devices } from '@playwright/test' + +/** + * Playwright e2e: baseURL и webServer для прогона без ручного поднятия приложения. + * @see https://playwright.dev/docs/test-webserver + */ +export default defineConfig({ + testDir: 'e2e', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + baseURL: 'http://localhost:5173', + trace: 'on-first-retry', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + webServer: { + command: 'npm run dev', + url: 'http://localhost:5173', + reuseExistingServer: !process.env.CI, + timeout: 180 * 1000, + }, +}) diff --git a/packages/kaspersky-ui-normalization-tool/public/favicon.svg b/packages/kaspersky-ui-normalization-tool/public/favicon.svg new file mode 100644 index 00000000..d567b3e8 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/kaspersky-ui-normalization-tool/scripts/generate-random-forms.js b/packages/kaspersky-ui-normalization-tool/scripts/generate-random-forms.js new file mode 100644 index 00000000..bc6ff6ed --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/scripts/generate-random-forms.js @@ -0,0 +1,165 @@ +/** + * Генерирует 10 случайных форм в папке jsons. Запуск: node scripts/generate-random-forms.js + */ +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const OUT_DIR = path.join(__dirname, '..', 'jsons') + +const NAMES = [ + 'Регистрация', 'Опрос', 'Настройки', 'Профиль', 'Заказ', 'Обратная связь', + 'Логин', 'Фильтры', 'Поиск', 'Карточка товара' +] + +const BUTTON_MODES = ['primary', 'secondary', 'tertiary', 'dangerFilled', 'dangerOutlined'] +const LABEL_POSITIONS = ['after', 'before'] +const META_COMPONENTS = ['Button', 'Text', 'Textbox', 'Badge', 'Tag', 'Link', 'H6'] + +function id(prefix) { + return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}` +} + +function pick(arr) { + return arr[Math.floor(Math.random() * arr.length)] +} + +function randInt(min, max) { + return min + Math.floor(Math.random() * (max - min + 1)) +} + +function elements(count) { + const types = [ + 'button', 'text', 'input', 'checkbox', 'radio', 'select', 'toggle', 'meta' + ] + const out = [] + for (let i = 0; i < count; i++) { + const type = pick(types) + const cid = id(type) + switch (type) { + case 'button': + out.push({ + type: 'button', + id: cid, + text: pick(['Отправить', 'Сохранить', 'Отмена', 'Далее', 'Назад']), + mode: pick(BUTTON_MODES), + ...(Math.random() > 0.7 && { onClickHandler: 'handlers/handler.js' }) + }) + break + case 'text': + out.push({ + type: 'text', + id: cid, + text: pick(['Подпись', 'Описание', 'Инструкция', 'Заголовок']) + }) + break + case 'input': + out.push({ + type: 'input', + id: cid, + text: pick(['Имя', 'Email', 'Телефон', 'Адрес']), + value: '', + placeholder: pick(['Введите значение', '...', 'Не обязательно']) + }) + break + case 'checkbox': + out.push({ + type: 'checkbox', + id: cid, + text: pick(['Согласен с условиями', 'Подписаться', 'Запомнить']), + checked: Math.random() > 0.5 + }) + break + case 'radio': + out.push({ + type: 'radio', + id: cid, + options: [ + { label: 'Вариант A', value: 'a' }, + { label: 'Вариант B', value: 'b' }, + { label: 'Вариант C', value: 'c' } + ], + value: pick(['a', 'b', 'c']), + vertical: Math.random() > 0.5 + }) + break + case 'select': + out.push({ + type: 'select', + id: cid, + options: [ + { label: 'Опция 1', value: '1' }, + { label: 'Опция 2', value: '2' }, + { label: 'Опция 3', value: '3' } + ], + placeholder: 'Выберите...', + mode: Math.random() > 0.8 ? 'multiple' : undefined + }) + break + case 'toggle': + out.push({ + type: 'toggle', + id: cid, + text: pick(['Включить', 'Уведомления', 'Тёмная тема']), + checked: Math.random() > 0.5, + labelPosition: pick(LABEL_POSITIONS) + }) + break + case 'meta': + out.push({ + type: 'meta', + id: cid, + componentId: pick(META_COMPONENTS), + props: { text: pick(['Мета', 'Бейдж', 'Ссылка']), mode: 'primary' } + }) + break + default: + out.push({ type: 'text', id: cid, text: 'Текст' }) + } + } + return out +} + +function toJsSource(form) { + const esc = (v) => JSON.stringify(v) + const elLines = form.elements.map((el) => { + const entries = Object.entries(el).filter(([, v]) => v !== undefined) + const inner = entries.map(([k, v]) => { + const val = k === 'onClickHandler' && typeof v === 'string' + ? `() => import("./${v.replace(/\\/g, '/')}")` + : JSON.stringify(v) + return ` ${esc(k)}: ${val}` + }).join(',\n') + return ` {\n${inner}\n }` + }).join(',\n') + return `export default { + name: ${esc(form.name)}, + id: ${esc(form.id)}, + elements: [ +${elLines} + ] +} +` +} + +function generateForms() { + if (!fs.existsSync(OUT_DIR)) fs.mkdirSync(OUT_DIR, { recursive: true }) + const usedNames = new Set() + for (let n = 1; n <= 10; n++) { + let name = pick(NAMES) + while (usedNames.has(name)) name = pick(NAMES) + usedNames.add(name) + const form = { + name, + id: `form-${Date.now()}-${n}-${Math.random().toString(36).slice(2, 6)}`, + elements: elements(randInt(2, 6)) + } + const filename = `form-random-${n}.js` + const filepath = path.join(OUT_DIR, filename) + fs.writeFileSync(filepath, toJsSource(form), 'utf8') + console.log('Created', filename) + } +} + +generateForms() diff --git a/packages/kaspersky-ui-normalization-tool/src/App.tsx b/packages/kaspersky-ui-normalization-tool/src/App.tsx new file mode 100644 index 00000000..212b7776 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/App.tsx @@ -0,0 +1,631 @@ +import { useState, useCallback, useEffect, useRef } from 'react' +import { ConfigProvider } from '@kaspersky/hexa-ui/design-system/context/provider' +import { ThemeKey } from '@kaspersky/hexa-ui/design-system' +import { GlobalStyle } from '@kaspersky/hexa-ui/design-system/global-style' +import { Button, Tree, PageHeader, Space, SectionMessage, Text, H6, Tooltip } from '@kaspersky/hexa-ui' +import type { DataNode } from '@kaspersky/hexa-ui' +import { Folder, Save, Cross, Add, Delete, Copy } from '@kaspersky/hexa-ui-icons/16' +import { useDirectoryPicker } from './hooks/useDirectoryPicker' +import { useFormFilesList, findFileInTree } from './hooks/useFormFilesList' +import { useFormFile } from './hooks/useFormFile' +import { useHistory } from './hooks/useHistory' +import { ControlsPalette } from './components/ControlsPalette' +import { FormCanvas } from './components/FormCanvas' +import { FormPreview } from './components/FormPreview' +import { CodeExportDialog } from './components/CodeExportDialog' +import { PropertiesPanel } from './components/PropertiesPanel' +import { updateControlInTree, findControlInTree, removeControlFromTree } from './types/form-dsl' +import { createControl } from './controls/registry' +import { FORM_TEMPLATES } from './templates' +import type { FormControl, FormControlType } from './types/form-dsl' +import type { FormFileNode } from './hooks/useFormFilesList' +import { FORM_EXT } from './constants' + +const layoutStyle: React.CSSProperties = { + display: 'flex', + flexDirection: 'column', + height: '100vh', + width: '100%', + padding: 24, + overflow: 'hidden', +} + +const editorLayoutStyle: React.CSSProperties = { + display: 'flex', + flex: 1, + minHeight: 0, + minWidth: 0, + overflow: 'hidden', +} + +const MIN_PALETTE_WIDTH = 160 +const MAX_PALETTE_WIDTH = 480 +const MIN_PANEL_WIDTH = 200 +const MAX_PANEL_WIDTH = 520 +const RESIZER_WIDTH = 6 + +const leftSidebarBaseStyle: React.CSSProperties = { + flexShrink: 0, + padding: 16, + borderRight: '1px solid var(--tagsoutlined--neutral-border, #E7E7E9)', + background: 'var(--surface--neutral, #FFFFFF)', + overflowY: 'auto', + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + textAlign: 'left', +} + +const resizerStyle: React.CSSProperties = { + width: RESIZER_WIDTH, + flexShrink: 0, + cursor: 'col-resize', + background: 'var(--tagsoutlined--neutral-border, #E7E7E9)', + transition: 'background 0.15s', + userSelect: 'none', + position: 'relative', + zIndex: 2, +} + +const resizerHoverStyle: React.CSSProperties = { + ...resizerStyle, + background: 'var(--primary--main, #00a88e)', +} + +const mainAreaStyle: React.CSSProperties = { + flex: 1, + minWidth: 0, + minHeight: 0, + display: 'flex', + flexDirection: 'column', + padding: 16, + overflow: 'hidden', +} + +const canvasWrapperStyle: React.CSSProperties = { + flex: 1, + minHeight: 0, + minWidth: 0, + display: 'flex', + flexDirection: 'column', + overflow: 'auto', +} + +function App() { + const [themeKey] = useState(ThemeKey.Light) + const [saveError, setSaveError] = useState(null) + const { directoryHandle, directoryName, selectDirectory, error: pickerError, clearError: clearPickerError } = + useDirectoryPicker() + const { treeNodes, loading, error: listError, clearError: clearListError, refresh: refreshFileList } = + useFormFilesList(directoryHandle) + const { + selectedFile, + formData, + setFormData, + formControls, + setFormControls, + hasUnsavedChanges, + selectFile, + closeFile, + saveFile, + createNewForm, + deleteCurrentForm, + loading: fileLoading, + loadError, + } = useFormFile(directoryHandle) + + const history = useHistory(formControls) + const lastFormControlsRef = useRef(formControls) + + useEffect(() => { + if (formControls !== lastFormControlsRef.current) { + lastFormControlsRef.current = formControls + history.resetHistory(formControls) + } + }, [formControls, history]) + + useEffect(() => { + if (history.state !== lastFormControlsRef.current) { + lastFormControlsRef.current = history.state + setFormControls(history.state) + } + }, [history.state, setFormControls]) + + const historySetControls = useCallback( + (action: React.SetStateAction) => { + const next = typeof action === 'function' ? action(history.state) : action + history.setState(next) + lastFormControlsRef.current = next + setFormControls(next) + }, + [history, setFormControls] + ) + + const [selectedControlId, setSelectedControlId] = useState(null) + const [createFormError, setCreateFormError] = useState(null) + const [deleteError, setDeleteError] = useState(null) + const [paletteWidth, setPaletteWidth] = useState(240) + const [panelWidth, setPanelWidth] = useState(280) + const [resizing, setResizing] = useState<'palette' | 'panel' | null>(null) + const [resizerHover, setResizerHover] = useState<'left' | 'right' | null>(null) + const [previewMode, setPreviewMode] = useState(false) + const [showExport, setShowExport] = useState(false) + const [clipboard, setClipboard] = useState(null) + const dragRef = useRef({ startX: 0, startWidth: 0 }) + + useEffect(() => { + if (!resizing) return + const onMove = (e: MouseEvent) => { + const { startX, startWidth } = dragRef.current + if (resizing === 'palette') { + const newW = startWidth + (e.clientX - startX) + setPaletteWidth(Math.min(MAX_PALETTE_WIDTH, Math.max(MIN_PALETTE_WIDTH, newW))) + } else { + const newW = startWidth + (startX - e.clientX) + setPanelWidth(Math.min(MAX_PANEL_WIDTH, Math.max(MIN_PANEL_WIDTH, newW))) + } + } + const onUp = () => setResizing(null) + document.addEventListener('mousemove', onMove) + document.addEventListener('mouseup', onUp) + return () => { + document.removeEventListener('mousemove', onMove) + document.removeEventListener('mouseup', onUp) + } + }, [resizing]) + + const handleUpdateControl = useCallback( + (id: string, patch: Partial) => { + historySetControls((prev) => updateControlInTree(prev, id, patch)) + }, + [historySetControls] + ) + + const selectedControl = + selectedControlId != null + ? findControlInTree(formControls, selectedControlId) + : null + + const handleAddControl = useCallback( + (type: FormControlType, options?: { componentId?: string }) => { + historySetControls((prev) => [...prev, createControl(type, options)]) + }, + [historySetControls] + ) + + const handleSave = useCallback(async () => { + setSaveError(null) + const err = await saveFile() + if (err) setSaveError(err) + }, [saveFile]) + + const handleCreateNewForm = useCallback(async () => { + setCreateFormError(null) + const err = await createNewForm() + if (err) { + setCreateFormError(err) + } else { + refreshFileList() + } + }, [createNewForm, refreshFileList]) + + const handleDeleteForm = useCallback(async () => { + if (!selectedFile) return + const confirmMessage = hasUnsavedChanges + ? `Удалить форму «${selectedFile.path}»? Несохранённые изменения будут потеряны.` + : `Удалить форму «${selectedFile.path}»?` + if (!window.confirm(confirmMessage)) return + setDeleteError(null) + const err = await deleteCurrentForm() + if (err) { + setDeleteError(err) + } else { + refreshFileList() + } + }, [selectedFile, hasUnsavedChanges, deleteCurrentForm, refreshFileList]) + + const handleCopyControl = useCallback(() => { + if (selectedControl) { + setClipboard(JSON.parse(JSON.stringify(selectedControl))) + } + }, [selectedControl]) + + const handlePasteControl = useCallback(() => { + if (!clipboard) return + const newId = `${clipboard.type}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}` + const pasted = { ...JSON.parse(JSON.stringify(clipboard)), id: newId } + historySetControls((prev) => [...prev, pasted]) + }, [clipboard, historySetControls]) + + const handleDuplicateControl = useCallback(() => { + if (!selectedControl) return + const newId = `${selectedControl.type}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}` + const dup = { ...JSON.parse(JSON.stringify(selectedControl)), id: newId } + historySetControls((prev) => { + const idx = prev.findIndex((c) => c.id === selectedControl.id) + if (idx >= 0) { + const next = [...prev] + next.splice(idx + 1, 0, dup) + return next + } + return [...prev, dup] + }) + }, [selectedControl, historySetControls]) + + const handleApplyTemplate = useCallback( + (templateElements: FormControl[]) => { + historySetControls((prev) => [ + ...prev, + ...templateElements.map((el) => ({ + ...JSON.parse(JSON.stringify(el)), + id: `${el.type}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, + })), + ]) + }, + [historySetControls] + ) + + useEffect(() => { + if (!selectedFile) return + const handler = (e: KeyboardEvent) => { + const isInput = (e.target as HTMLElement)?.tagName === 'INPUT' || + (e.target as HTMLElement)?.tagName === 'TEXTAREA' || + (e.target as HTMLElement)?.getAttribute('contenteditable') === 'true' + + if (e.ctrlKey || e.metaKey) { + if (e.key === 's') { + e.preventDefault() + handleSave() + return + } + if (e.key === 'z' && !e.shiftKey) { + if (isInput) return + e.preventDefault() + history.undo() + return + } + if ((e.key === 'z' && e.shiftKey) || e.key === 'y') { + if (isInput) return + e.preventDefault() + history.redo() + return + } + if (e.key === 'c' && !isInput) { + e.preventDefault() + handleCopyControl() + return + } + if (e.key === 'v' && !isInput) { + e.preventDefault() + handlePasteControl() + return + } + if (e.key === 'd') { + e.preventDefault() + handleDuplicateControl() + return + } + } + if (e.key === 'Delete' && !isInput && selectedControlId) { + e.preventDefault() + historySetControls((prev) => removeControlFromTree(prev, selectedControlId)) + setSelectedControlId(null) + return + } + if (e.key === 'Escape') { + setSelectedControlId(null) + setPreviewMode(false) + return + } + } + document.addEventListener('keydown', handler) + return () => document.removeEventListener('keydown', handler) + }, [selectedFile, selectedControlId, handleSave, history, handleCopyControl, handlePasteControl, handleDuplicateControl, historySetControls]) + + const treeData: DataNode[] = treeNodes.map((node) => nodeToDataNode(node)) + + function nodeToDataNode(n: FormFileNode): DataNode { + return { + key: n.key, + title: n.title, + isLeaf: n.isLeaf, + children: n.children?.length ? n.children.map(nodeToDataNode) : undefined, + } + } + + const handleTreeSelect = useCallback( + (_: unknown, info: { node: { key: string } }) => { + const found = findFileInTree(treeNodes, info.node.key as string) + if (found) selectFile({ path: found.path, handle: found.handle }) + }, + [treeNodes, selectFile] + ) + + const showMessage = pickerError || listError + const messageText = pickerError || listError || '' + const clearMessageError = useCallback(() => { + clearPickerError() + clearListError() + }, [clearPickerError, clearListError]) + + const contentWrapperStyle: React.CSSProperties = { + flex: 1, + minHeight: 0, + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + width: '100%', + } + + return ( + + +
+ +
+
+
+
+ + {showMessage && ( + + {messageText} + + )} + + {saveError && ( + setSaveError(null)} + > + {saveError} + + )} + + {loadError && ( + + {loadError} + + )} + + {createFormError && ( + setCreateFormError(null)} + > + {createFormError} + + )} + + {deleteError && ( + setDeleteError(null)} + > + {deleteError} + + )} + + {directoryHandle && + !selectedFile && + (loading ? ( +
Загрузка списка файлов…
+ ) : treeData.length > 0 ? ( +
+ + {`Выберите файл формы ${FORM_EXT} (дерево каталогов):`} + + )} + /> +
+ ) : ( + + {`В выбранном каталоге нет файлов ${FORM_EXT}`} + + ))} + + {selectedFile && ( + <> + {fileLoading ? ( +
Загрузка формы…
+ ) : previewMode ? ( +
+
+
Предпросмотр: {formData.name || selectedFile.path}
+
+ +
+ ) : ( +
+ +
{ + e.preventDefault() + dragRef.current = { startX: e.clientX, startWidth: paletteWidth } + setResizing('palette') + }} + onMouseEnter={() => setResizerHover('left')} + onMouseLeave={() => setResizerHover(null)} + /> +
+
+
+ Форма: {selectedFile.path} + {hasUnsavedChanges && ( + + не сохранено + + )} +
+ + +
+
+ handleAddControl(type as FormControlType, undefined)} + selectedId={selectedControlId} + onSelect={setSelectedControlId} + /> +
+
+
+
{ + e.preventDefault() + e.stopPropagation() + dragRef.current = { startX: e.clientX, startWidth: panelWidth } + setResizing('panel') + }} + onMouseEnter={() => setResizerHover('right')} + onMouseLeave={() => setResizerHover(null)} + /> +
+ setFormData((prev) => ({ ...prev, ...patch }))} + control={selectedControl} + onUpdate={handleUpdateControl} + formDirectoryHandle={directoryHandle} + /> +
+
+
+ )} + + )} +
+
+
+ {showExport && ( + setShowExport(false)} /> + )} + + ) +} + +export default App diff --git a/packages/kaspersky-ui-normalization-tool/src/components/CanvasPreviewErrorBoundary.tsx b/packages/kaspersky-ui-normalization-tool/src/components/CanvasPreviewErrorBoundary.tsx new file mode 100644 index 00000000..902373ec --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/CanvasPreviewErrorBoundary.tsx @@ -0,0 +1,39 @@ +import React from 'react' +import { Text } from '@kaspersky/hexa-ui' + +interface Props { + children: React.ReactNode + fallback?: React.ReactNode + componentLabel?: string +} + +interface State { + hasError: boolean +} + +/** + * Ловит ошибки рендера превью контрола на холсте, чтобы блок .control-wrap оставался в DOM + * (например для e2e и чтобы не ломать весь холст при падении одного компонента). + */ +export class CanvasPreviewErrorBoundary extends React.Component { + state: State = { hasError: false } + + static getDerivedStateFromError(): State { + return { hasError: true } + } + + componentDidCatch(error: Error, info: React.ErrorInfo): void { + console.warn('[CanvasPreviewErrorBoundary]', error?.message, info?.componentStack) + } + + render(): React.ReactNode { + if (this.state.hasError) { + return this.props.fallback ?? ( + + {this.props.componentLabel ? `Компонент «${this.props.componentLabel}»` : 'Компонент не удалось отобразить'} + + ) + } + return this.props.children + } +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/CodeExportDialog.tsx b/packages/kaspersky-ui-normalization-tool/src/components/CodeExportDialog.tsx new file mode 100644 index 00000000..f709114f --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/CodeExportDialog.tsx @@ -0,0 +1,111 @@ +import { useState, useMemo } from 'react' +import { Button, Text, H6, Space } from '@kaspersky/hexa-ui' +import { Cross, Copy } from '@kaspersky/hexa-ui-icons/16' +import type { FormData } from '../types/form-dsl' +import { formToJs, formToJsonString } from '../types/form-dsl' + +type ExportTab = 'js' | 'json' + +const tabLabels: Record = { + js: 'JS модуль (.js)', + json: 'JSON', +} + +export function CodeExportDialog({ + formData, + onClose, +}: { + formData: FormData + onClose: () => void +}) { + const [activeTab, setActiveTab] = useState('js') + const [copied, setCopied] = useState(false) + + const code = useMemo(() => { + switch (activeTab) { + case 'js': return formToJs(formData) + case 'json': return formToJsonString(formData) + } + }, [formData, activeTab]) + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(code) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } catch { + const textarea = document.createElement('textarea') + textarea.value = code + document.body.appendChild(textarea) + textarea.select() + document.execCommand('copy') + document.body.removeChild(textarea) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + } + + return ( +
+
+
+
Экспорт DSL
+
+
+ {(Object.keys(tabLabels) as ExportTab[]).map((tab) => ( +
+
+
+            {code}
+          
+
+
+ + + Скопировано! + +
+
+
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/ControlsPalette.tsx b/packages/kaspersky-ui-normalization-tool/src/components/ControlsPalette.tsx new file mode 100644 index 00000000..2d4a00ad --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/ControlsPalette.tsx @@ -0,0 +1,96 @@ +import React, { useState, useMemo } from 'react' +import { Space, H6, Textbox } from '@kaspersky/hexa-ui' +import type { FormControlType } from '../types/form-dsl' +import { getPaletteGroups } from '../controls/registry' + +const paletteItemStyle: React.CSSProperties = { + display: 'flex', + alignItems: 'center', + gap: 10, + padding: '10px 12px', + cursor: 'grab', + border: '1px solid transparent', + borderRadius: 8, + userSelect: 'none', + width: '100%', + boxSizing: 'border-box', + justifyContent: 'flex-start', +} + +export interface ControlsPaletteAddOptions { + componentId?: string +} + +export interface ControlsPaletteProps { + onAddControl: (type: FormControlType, options?: ControlsPaletteAddOptions) => void +} + +function dragKey(item: { type: FormControlType; label: string; componentId?: string }): string { + return item.componentId != null ? `${item.type}:${item.componentId}` : item.type +} + +export function ControlsPalette({ onAddControl }: ControlsPaletteProps) { + const allGroups = getPaletteGroups() + const [search, setSearch] = useState('') + + const groups = useMemo(() => { + const q = search.trim().toLowerCase() + if (!q) return allGroups + return allGroups + .map(({ group, items }) => ({ + group, + items: items.filter( + (item) => + item.label.toLowerCase().includes(q) || + item.type.toLowerCase().includes(q) || + (item.componentId && item.componentId.toLowerCase().includes(q)) + ), + })) + .filter(({ items }) => items.length > 0) + }, [allGroups, search]) + + return ( + + + {groups.map(({ group, items }) => ( +
+
+ {group} +
+ + {items.map((item) => ( +
onAddControl(item.type)} + onDragStart={(e) => { + e.dataTransfer.setData('application/x-form-control-type', item.type) + e.dataTransfer.setData('text/plain', item.type) + e.dataTransfer.effectAllowed = 'copy' + }} + draggable + > + + {item.label} +
+ ))} +
+
+ ))} + {groups.length === 0 && search && ( +
+ Ничего не найдено +
+ )} +
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/FormCanvas.tsx b/packages/kaspersky-ui-normalization-tool/src/components/FormCanvas.tsx new file mode 100644 index 00000000..9eb476c2 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/FormCanvas.tsx @@ -0,0 +1,1130 @@ +import React, { useCallback, useState, useRef, useEffect } from 'react' +import { Button, Space, Text, Grid, GridItem, Tabs } from '@kaspersky/hexa-ui' +import { Delete, ArrowsVertical } from '@kaspersky/hexa-ui-icons/16' +import type { FormControl, FormControlType, GridControl, TableControl, TabsControl, RowControl } from '../types/form-dsl' +import { setGridChildrenInTree, setRowChildrenInTree, setTableChildrenInTree, setTabsChildrenInTree } from '../types/form-dsl' +import { createControl, getDescriptor, ALL_CONTROL_TYPES } from '../controls/registry' +import type { CanvasContext } from '../controls/types' +import { ToolbarStaticPreview } from '../controls/descriptors/toolbar' +import { CanvasPreviewErrorBoundary } from './CanvasPreviewErrorBoundary' + +const canvasStyle: React.CSSProperties = { + padding: 24, + border: `2px dashed var(--tagsoutlined--neutral-border, #ccc)`, + borderRadius: 12, + background: 'var(--surface--neutral, #fafafa)', + flex: 1, + minHeight: 0, /* flex-элемент может сжиматься по вертикали */ + minWidth: 0, /* иначе холст растягивается по контенту и не появляется горизонтальный скролл */ + overflow: 'auto', +} + +const controlWrapStyle: React.CSSProperties = { + display: 'inline-flex', + alignItems: 'center', + gap: 8, + margin: 4, + padding: 8, + borderRadius: 8, + border: '2px solid transparent', + borderColor: 'transparent', + cursor: 'grab', + outline: 'none', +} + +const controlWrapSelectedStyle: React.CSSProperties = { + ...controlWrapStyle, + borderColor: 'var(--primary--main, #00a88e)', + background: 'rgba(0,168,142,0.08)', +} + +const dragHandleStyle: React.CSSProperties = { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: 28, + minWidth: 28, + height: 28, + padding: 0, + borderRadius: 6, + flexShrink: 0, + cursor: 'grab', + color: '#8c8c8c', +} + +const removeBtnStyle: React.CSSProperties = { + width: 28, + minWidth: 28, + height: 28, + padding: 0, + borderRadius: 6, + flexShrink: 0, +} + +const dropZoneStyle: React.CSSProperties = { + minHeight: 48, + width: '100%', + margin: 2, + borderRadius: 6, + background: 'transparent', + border: '1px dashed #d9d9d9', + transition: 'background 0.15s, border-color 0.15s', + flexShrink: 0, +} + +/** Та же геометрия, что и dropZoneStyle; только рамка/фон скрыты (без opacity, чтобы не скрывать контрол внутри) */ +const dropZoneHiddenStyle: React.CSSProperties = { + ...dropZoneStyle, + borderColor: 'transparent', + background: 'transparent', +} + +/** Дроп-зона без отступа: когда драг не над табом, зоны не занимают место */ +const dropZoneCollapsedStyle: React.CSSProperties = { + minHeight: 0, + margin: 0, + padding: 0, + width: '100%', + border: 'none', + background: 'transparent', + flexShrink: 0, +} + +const dropZoneActiveStyle: React.CSSProperties = { + ...dropZoneStyle, + background: 'rgba(0,168,142,0.2)', + borderColor: 'var(--primary--main, #00a88e)', +} + +const gridWrapStyle: React.CSSProperties = { + minWidth: 200, + width: '100%', + minHeight: 80, + padding: 8, + borderRadius: 8, + border: '1px solid #e8e8e8', + background: 'rgba(0,0,0,0.02)', + boxSizing: 'border-box', +} + +const gridCellStyle: React.CSSProperties = { + minHeight: 48, + borderRadius: 6, + border: '1px dashed #e0e0e0', + background: 'rgba(255,255,255,0.6)', + boxSizing: 'border-box', +} + +const gridCellDropStyle: React.CSSProperties = { + minHeight: '100%', + width: '100%', + minWidth: 0, + boxSizing: 'border-box', + borderRadius: 6, +} + +const tableWrapStyle: React.CSSProperties = { + ...gridWrapStyle, + border: '1px solid #d0d0d0', + background: 'rgba(255,255,255,0.8)', +} + +const tableCellStyle: React.CSSProperties = { + ...gridCellStyle, + border: '1px solid #e0e0e0', + minHeight: 40, +} + +const tabsWrapStyle: React.CSSProperties = { + minWidth: 200, + width: '100%', + minHeight: 80, + padding: 8, + borderRadius: 8, + border: '1px solid #e8e8e8', + background: 'rgba(255,255,255,0.6)', + boxSizing: 'border-box', +} + +const DATA_TYPE_KEY = 'application/x-form-control-type' +const DATA_ID_KEY = 'application/x-form-control-id' + +function getDropTypeAndOptions(e: React.DragEvent): { type: FormControlType; options?: { componentId?: string } } | null { + const raw = e.dataTransfer.getData(DATA_TYPE_KEY) || e.dataTransfer.getData('text/plain') + const type = raw.includes(':') ? raw.split(':')[0] : raw + if (!type || !ALL_CONTROL_TYPES.includes(type as FormControl['type'])) return null + return { type: type as FormControlType } +} + +export interface FormCanvasProps { + controls: FormControl[] + onControlsChange: React.Dispatch> + onDropControl?: (type: string) => void + selectedId: string | null + onSelect: (id: string | null) => void +} + +function GridControlBlock({ + control, + selectedId, + onSelect, + rootSetControls, +}: { + control: GridControl + selectedId: string | null + onSelect: (id: string | null) => void + onRemove: (id: string) => void + rootSetControls: React.Dispatch> +}) { + const g = control + const setGridChildren = useCallback( + (next: React.SetStateAction<(FormControl | null)[]>) => { + rootSetControls((prev) => + setGridChildrenInTree( + prev, + g.id, + typeof next === 'function' ? next(g.children) : next + ) as FormControl[] + ) + }, + [g.id, g.children, rootSetControls] + ) + + return ( +
+ '1fr'), + }} + layoutProperty={{ gap: 8 }} + > + {Array.from({ length: g.rows * g.cols }, (_, i) => { + const handleCellDrop = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + const id = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (id) { + const idx = g.children.findIndex((ch) => ch && ch.id === id) + if (idx === -1) return + if (idx === i) return + const movingControl = g.children[idx] + setGridChildren((prev) => { + const next = [...prev] + const wasInTarget = next[i] + next[idx] = wasInTarget + next[i] = movingControl + return next + }) + } else if (dropInfo) { + setGridChildren((prev) => { + const next = [...prev] + next[i] = createControl(dropInfo.type, dropInfo.options) + return next + }) + } + } + const slotControl = g.children[i] + return ( + +
{ + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + }} + onDrop={handleCellDrop} + > + {slotControl ? ( + + setGridChildren((prev) => { + const next = [...prev] + next[i] = null + return next + }) + } + onControlsChange={setGridChildren} + rootSetControls={rootSetControls} + /> + ) : null} +
+
+ ) + })} +
+
+ ) +} + +const rowWrapStyle: React.CSSProperties = { + minWidth: 100, + width: '100%', + minHeight: 48, + padding: 8, + borderRadius: 8, + background: 'var(--surface--neutral, #f7f7f7)', +} + +const rowSlotStyle: React.CSSProperties = { + minHeight: 40, + minWidth: 48, + borderRadius: 6, + border: '1px dashed #e0e0e0', + background: 'rgba(255,255,255,0.6)', + boxSizing: 'border-box', + flex: '1 1 0', +} + +function RowControlBlock({ + control, + selectedId, + onSelect, + rootSetControls, +}: { + control: RowControl + selectedId: string | null + onSelect: (id: string | null) => void + onRemove: (id: string) => void + rootSetControls: React.Dispatch> +}) { + const r = control + + const setRowChildren = useCallback( + (next: React.SetStateAction) => { + rootSetControls((prev) => + setRowChildrenInTree( + prev, + r.id, + typeof next === 'function' ? next(r.children) : next + ) as FormControl[] + ) + }, + [r.id, r.children, rootSetControls] + ) + + const handleSlotDrop = useCallback((e: React.DragEvent, index: number) => { + e.preventDefault() + e.stopPropagation() + const existingId = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (existingId) { + const fromIdx = r.children.findIndex((ch) => ch.id === existingId) + if (fromIdx === -1 || fromIdx === index) return + setRowChildren((prev) => { + const next = [...prev] + const [moved] = next.splice(fromIdx, 1) + next.splice(index > fromIdx ? index - 1 : index, 0, moved) + return next + }) + } else if (dropInfo) { + setRowChildren((prev) => { + const next = [...prev] + next.splice(index, 0, createControl(dropInfo.type, dropInfo.options)) + return next + }) + } + }, [r.children, setRowChildren]) + + const handleAppendDrop = useCallback((e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + const existingId = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (existingId) { + const fromIdx = r.children.findIndex((ch) => ch.id === existingId) + if (fromIdx === -1) return + setRowChildren((prev) => { + const next = [...prev] + const [moved] = next.splice(fromIdx, 1) + next.push(moved) + return next + }) + } else if (dropInfo) { + setRowChildren((prev) => [...prev, createControl(dropInfo.type, dropInfo.options)]) + } + }, [r.children, setRowChildren]) + + const alignItems = r.align === 'start' ? 'flex-start' : r.align === 'end' ? 'flex-end' : 'center' + + return ( +
+
+ {r.children.map((child, i) => ( +
{ e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' }} + onDrop={(e) => handleSlotDrop(e, i)} + > + setRowChildren((prev) => prev.filter((c) => c.id !== _id))} + onControlsChange={(next) => { + if (typeof next === 'function') { + rootSetControls((prev) => setRowChildrenInTree(prev, r.id, next(r.children).filter((c): c is FormControl => c != null)) as FormControl[]) + } + }} + rootSetControls={rootSetControls} + /> +
+ ))} +
{ e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = 'copy' }} + onDrop={handleAppendDrop} + > + + +
+
+
+ ) +} + +function TableControlBlock({ + control, + selectedId, + onSelect, + rootSetControls, +}: { + control: TableControl + selectedId: string | null + onSelect: (id: string | null) => void + onRemove: (id: string) => void + rootSetControls: React.Dispatch> +}) { + const t = control + const setTableChildren = useCallback( + (next: React.SetStateAction<(FormControl | null)[]>) => { + rootSetControls((prev) => + setTableChildrenInTree( + prev, + t.id, + typeof next === 'function' ? next(t.children) : next + ) as FormControl[] + ) + }, + [t.id, t.children, rootSetControls] + ) + + const hasAnyChild = t.children.some((ch) => ch != null) + const cellAlign = t.columnVerticalAlign ?? 'inherit' + const isCompact = t.rowMode === 'compact' + const cellStyle: React.CSSProperties = { + ...tableCellStyle, + verticalAlign: cellAlign !== 'inherit' ? cellAlign : undefined, + padding: isCompact ? 4 : 8, + } + + const hasToolbar = t.toolbar && ((t.toolbar.left?.length ?? 0) > 0 || (t.toolbar.right?.length ?? 0) > 0) + return ( +
+ {hasToolbar && ( +
+ +
+ )} + {!hasAnyChild && t.emptyText ? ( +
+ {t.emptyText} +
+ ) : ( + '1fr') }} + layoutProperty={{ gap: 0 }} + > + {Array.from({ length: t.rows * t.cols }, (_, i) => { + const handleCellDrop = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + const id = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (id) { + const idx = t.children.findIndex((ch) => ch && ch.id === id) + if (idx === -1) return + if (idx === i) return + const movingControl = t.children[idx] + setTableChildren((prev) => { + const next = [...prev] + const wasInTarget = next[i] + next[idx] = wasInTarget + next[i] = movingControl + return next + }) + } else if (dropInfo) { + setTableChildren((prev) => { + const next = [...prev] + next[i] = createControl(dropInfo.type, dropInfo.options) + return next + }) + } + } + const slotControl = t.children[i] + return ( + +
{ + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + }} + onDrop={handleCellDrop} + > + {slotControl ? ( + + setTableChildren((prev) => { + const next = [...prev] + next[i] = null + return next + }) + } + onControlsChange={setTableChildren} + rootSetControls={rootSetControls} + /> + ) : null} +
+
+ ) + })} +
+ )} +
+ ) +} + +function TabsControlBlock({ + control, + selectedId, + onSelect, + rootSetControls, +}: { + control: TabsControl + selectedId: string | null + onSelect: (id: string | null) => void + onRemove: (id: string) => void + rootSetControls: React.Dispatch> +}) { + const t = control + const [activeKey, setActiveKey] = useState(() => t.activeKey ?? t.items[0]?.key ?? '') + const [tabDropTarget, setTabDropTarget] = useState<{ tabIndex: number; dropIndex: number } | null>(null) + const tabDropTargetRef = useRef<{ tabIndex: number; dropIndex: number } | null>(null) + const compactTabChildren = useCallback( + (list: (FormControl | null)[]) => list.filter((ch): ch is FormControl => ch != null), + [] + ) + useEffect(() => { + setActiveKey(t.activeKey ?? t.items[0]?.key ?? '') + }, [t.id, t.activeKey, t.items[0]?.key]) + const setTabChildrenAt = useCallback( + (tabIndex: number, next: React.SetStateAction<(FormControl | null)[]>) => { + rootSetControls((prev) => + setTabsChildrenInTree( + prev, + t.id, + tabIndex, + compactTabChildren( + typeof next === 'function' ? next(t.items[tabIndex]?.children ?? []) : next + ) + ) as FormControl[] + ) + }, + [t.id, t.items, rootSetControls, compactTabChildren] + ) + + const handleTabZoneDrop = useCallback( + (tabIndex: number, dropIndex: number, e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + setTabDropTarget(null) + tabDropTargetRef.current = null + const id = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + const item = t.items[tabIndex] + const itemChildren = compactTabChildren(item.children ?? []) + if (id) { + const sameTabIdx = itemChildren.findIndex((ch) => ch.id === id) + if (sameTabIdx !== -1) { + const movingControl = itemChildren[sameTabIdx] + if (!movingControl) return + if (sameTabIdx === dropIndex || sameTabIdx + 1 === dropIndex) return + setTabChildrenAt(tabIndex, (prev) => { + const filtered = compactTabChildren(prev).filter((_, j) => j !== sameTabIdx) + const insertAt = dropIndex > sameTabIdx ? dropIndex - 1 : dropIndex + return [...filtered.slice(0, insertAt), movingControl, ...filtered.slice(insertAt)] + }) + return + } + const fromWhich = t.items.findIndex((it) => compactTabChildren(it.children ?? []).some((ch) => ch.id === id)) + if (fromWhich === -1) return + const fromItem = t.items[fromWhich] + const fromChildren = compactTabChildren(fromItem.children ?? []) + const fromIdx = fromChildren.findIndex((ch) => ch.id === id) + const movingControl = fromChildren[fromIdx] + if (!movingControl) return + rootSetControls((prev) => { + const afterRemove = setTabsChildrenInTree( + prev, + t.id, + fromWhich, + fromChildren.filter((_, j) => j !== fromIdx) + ) + const toChildren = compactTabChildren(t.items[tabIndex].children ?? []) + toChildren.splice(dropIndex, 0, movingControl) + return setTabsChildrenInTree(afterRemove, t.id, tabIndex, toChildren) as FormControl[] + }) + } else if (dropInfo) { + setTabChildrenAt(tabIndex, (prev) => { + const next = compactTabChildren(prev) + next.splice(dropIndex, 0, createControl(dropInfo.type, dropInfo.options)) + return next + }) + } + }, + [t.id, t.items, setTabChildrenAt, rootSetControls, compactTabChildren] + ) + + return ( +
+ setActiveKey(key)} + > + {t.items.map((item, tabIndex) => { + const children = compactTabChildren(item.children ?? []) + const isDropActive = tabDropTarget != null && tabDropTarget.tabIndex === tabIndex + const showDropZones = isDropActive + return ( + +
{ + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + if (!tabDropTargetRef.current || tabDropTargetRef.current.tabIndex !== tabIndex) { + const next = { tabIndex, dropIndex: children.length } + tabDropTargetRef.current = next + setTabDropTarget(next) + } + }} + onDragLeave={(e) => { + const related = e.relatedTarget + if (related instanceof Node && e.currentTarget.contains(related)) return + setTabDropTarget(null) + tabDropTargetRef.current = null + }} + > + + {children.map((slotControl, slotIndex) => ( +
{ + e.stopPropagation() + const next = { tabIndex, dropIndex: slotIndex } + if (tabDropTargetRef.current?.tabIndex !== next.tabIndex || tabDropTargetRef.current?.dropIndex !== next.dropIndex) { + tabDropTargetRef.current = next + setTabDropTarget(next) + } + }} + onDragOver={(e) => { + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + const next = { tabIndex, dropIndex: slotIndex } + if (tabDropTargetRef.current?.tabIndex !== next.tabIndex || tabDropTargetRef.current?.dropIndex !== next.dropIndex) { + tabDropTargetRef.current = next + setTabDropTarget(next) + } + }} + onDrop={(e) => handleTabZoneDrop(tabIndex, slotIndex, e)} + > + {slotControl ? ( + + setTabChildrenAt(tabIndex, (prev) => { + return compactTabChildren(prev).filter((_, j) => j !== slotIndex) + }) + } + onControlsChange={(up) => + setTabChildrenAt(tabIndex, (tabChildren) => { + const slot = tabChildren[slotIndex] + if (slot && (slot.type === 'grid' || slot.type === 'table') && typeof up === 'function') { + const nextInner = up((slot as GridControl).children) + return tabChildren.map((c, j) => + j === slotIndex ? ({ ...c, children: nextInner } as FormControl) : c + ) + } + return typeof up === 'function' ? up(tabChildren) : up + }) + } + rootSetControls={rootSetControls} + /> + ) : null} +
+ ))} +
{ + e.stopPropagation() + const next = { tabIndex, dropIndex: children.length } + if (tabDropTargetRef.current?.tabIndex !== next.tabIndex || tabDropTargetRef.current?.dropIndex !== next.dropIndex) { + tabDropTargetRef.current = next + setTabDropTarget(next) + } + }} + onDragOver={(e) => { + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + const next = { tabIndex, dropIndex: children.length } + if (tabDropTargetRef.current?.tabIndex !== next.tabIndex || tabDropTargetRef.current?.dropIndex !== next.dropIndex) { + tabDropTargetRef.current = next + setTabDropTarget(next) + } + }} + onDrop={(e) => handleTabZoneDrop(tabIndex, children.length, e)} + /> + +
+ + ) + })} + +
+ ) +} + +function ControlBlock({ + control, + selectedId, + onSelect, + onRemove, + onControlsChange, + rootSetControls, + onDropAt, + dropIndex, +}: { + control: FormControl + selectedId: string | null + onSelect: (id: string | null) => void + onRemove: (id: string) => void + onControlsChange: React.Dispatch> + rootSetControls: React.Dispatch> + onDropAt?: (e: React.DragEvent) => void + dropIndex?: number +}) { + const selectControl = useCallback( + (e: React.MouseEvent, id: string) => { + e.stopPropagation() + onSelect(id) + }, + [onSelect] + ) + + const handleDragStart = useCallback((e: React.DragEvent, id: string) => { + e.stopPropagation() + e.dataTransfer.setData(DATA_ID_KEY, id) + e.dataTransfer.setData('text/plain', id) + e.dataTransfer.effectAllowed = 'move' + }, []) + + const isSelected = selectedId === control.id + + return ( +
handleDragStart(e, control.id)} + onClick={(e) => selectControl(e, control.id)} + onDragOver={onDropAt ? (e) => { e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = 'move' } : undefined} + onDrop={onDropAt ? (e) => { e.preventDefault(); e.stopPropagation(); onDropAt(e) } : undefined} + > +
e.stopPropagation()} + title="Перетащите для изменения порядка" + > + +
+ {control.type === 'grid' ? ( + + ) : control.type === 'row' ? ( + + ) : control.type === 'table' ? ( + + ) : control.type === 'tabs' ? ( + + ) : ( +
+ + {(() => { + const descriptor = getDescriptor(control.type as FormControlType) + if (descriptor) { + const context: CanvasContext = { + selectedId, + onSelect, + onRemove, + rootSetControls, + onControlsChange, + renderControlBlock: (c) => ( + + ), + createControl, + controlTypes: ALL_CONTROL_TYPES, + dataTypeKey: DATA_TYPE_KEY, + dataIdKey: DATA_ID_KEY, + setGridChildrenInTree, + setRowChildrenInTree, + setTableChildrenInTree, + } + return descriptor.CanvasPreview({ control: control as Parameters[0]['control'], context }) + } + return null + })()} + +
+ )} + {(control.fieldName || (control.validation && control.validation.some((r) => r.type === 'required'))) && ( + + {control.validation?.some((r) => r.type === 'required') && ( + * + )} + {control.fieldName || ''} + + )} + {(control.visibleWhen || control.disabledWhen) && ( + + ⚡ + + )} + {control.handlers && Object.keys(control.handlers).length > 0 && ( + `${k}: ${v}`).join('\n')}> + fn{Object.keys(control.handlers).length > 1 ? ` ×${Object.keys(control.handlers).length}` : ''} + + )} +
+ ) +} + +export function FormCanvas({ + controls, + onControlsChange, + selectedId, + onSelect, +}: FormCanvasProps) { + const [dragOver, setDragOver] = useState(false) + const [dropIndex, setDropIndex] = useState(null) + const dropIndexRef = useRef(null) + const canvasRef = useRef(null) + + useEffect(() => { + const id = 'canvas-radio-overrides' + if (document.getElementById(id)) return + const style = document.createElement('style') + style.id = id + style.textContent = ` + .control-wrap .ant-radio-group .ant-radio::after, + .control-wrap .ant-radio-group .ant-radio-checked .ant-radio-inner::after, + .control-wrap .ant-radio-group .ant-radio-inner::after { + display: none !important; visibility: hidden !important; opacity: 0 !important; + width: 0 !important; height: 0 !important; overflow: hidden !important; + content: none !important; background: none !important; border: none !important; + } + .canvas-tabs-wrapper .kl6-tabs-more-button { + display: none !important; + } + ` + document.head.appendChild(style) + }, []) + + const handleDrop = useCallback( + (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + setDragOver(false) + setDropIndex(null) + dropIndexRef.current = null + const raw = (e.currentTarget as HTMLElement).getAttribute('data-drop-index') + const index = raw != null ? parseInt(raw, 10) : NaN + if (Number.isNaN(index) || index < 0) return + const id = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (id) { + const fromIndex = controls.findIndex((c) => c.id === id) + if (fromIndex === -1) return + const toIndex = fromIndex < index ? index - 1 : index + if (toIndex === fromIndex) return + const next = [...controls] + const [removed] = next.splice(fromIndex, 1) + next.splice(toIndex, 0, removed) + onControlsChange(next) + return + } + if (dropInfo) { + const next = [...controls] + next.splice(index, 0, createControl(dropInfo.type, dropInfo.options)) + onControlsChange(next) + } + }, + [controls, onControlsChange] + ) + + const handleCanvasDragEnter = useCallback((e: React.DragEvent) => { + e.preventDefault() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + setDragOver(true) + }, []) + + const handleCanvasDragLeave = useCallback((e: React.DragEvent) => { + const relatedTarget = e.relatedTarget + if (relatedTarget instanceof Node && canvasRef.current?.contains(relatedTarget)) { + return + } + setDragOver(false) + setDropIndex(null) + dropIndexRef.current = null + }, []) + + const handleDragOver = useCallback((e: React.DragEvent, index: number) => { + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + setDragOver(true) + if (dropIndexRef.current !== index) { + dropIndexRef.current = index + setDropIndex(index) + } + }, []) + + const handleDragLeave = useCallback((e: React.DragEvent) => { + e.stopPropagation() + const relatedTarget = e.relatedTarget + if (relatedTarget instanceof Node && canvasRef.current?.contains(relatedTarget)) { + return + } + setDragOver(false) + setDropIndex(null) + dropIndexRef.current = null + }, []) + + const handleDragEnter = useCallback((e: React.DragEvent, index: number) => { + e.preventDefault() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + setDragOver(true) + if (dropIndexRef.current !== index) { + dropIndexRef.current = index + setDropIndex(index) + } + }, []) + + return ( +
{ + setDragOver(false) + setDropIndex(null) + dropIndexRef.current = null + }} + onDrop={(e) => { + e.preventDefault() + const id = e.dataTransfer.getData(DATA_ID_KEY) + const dropInfo = getDropTypeAndOptions(e) + if (id) return + if (dropInfo) { + const next = [...controls, createControl(dropInfo.type, dropInfo.options)] + onControlsChange(next) + } + setDragOver(false) + setDropIndex(null) + dropIndexRef.current = null + }} + onDragEnter={handleCanvasDragEnter} + onDragOver={(e) => { + e.preventDefault() + e.dataTransfer.dropEffect = e.dataTransfer.types.includes(DATA_ID_KEY) ? 'move' : 'copy' + setDragOver(true) + }} + onDragLeave={handleCanvasDragLeave} + onClick={(e) => { + if (!(e.target as HTMLElement).closest('.control-wrap')) { + if (document.activeElement && document.activeElement instanceof HTMLElement) { + document.activeElement.blur() + } + onSelect(null) + } + }} + > + {controls.length === 0 && !dragOver && ( + + Перетащите сюда контрол из меню или дважды щёлкните по элементу в меню + + )} + + {controls.map((control, index) => ( +
{ + e.stopPropagation() + handleDragEnter(e, index) + }} + onDragOver={(e) => handleDragOver(e, index)} + onDragLeave={handleDragLeave} + onDrop={handleDrop} + > + { + onControlsChange(controls.filter((c) => c.id !== id)) + if (selectedId === id) onSelect(null) + }} + onControlsChange={onControlsChange as React.Dispatch>} + rootSetControls={onControlsChange} + /> +
+ ))} +
{ + e.stopPropagation() + handleDragEnter(e, controls.length) + }} + onDragOver={(e) => handleDragOver(e, controls.length)} + onDragLeave={handleDragLeave} + onDrop={handleDrop} + /> + +
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/FormPreview.tsx b/packages/kaspersky-ui-normalization-tool/src/components/FormPreview.tsx new file mode 100644 index 00000000..e1b1e856 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/FormPreview.tsx @@ -0,0 +1,227 @@ +import React, { useState, useCallback } from 'react' +import { Button, Text, H6, Space, SectionMessage } from '@kaspersky/hexa-ui' +import type { FormControl, FormData, ValidationRule, Condition } from '../types/form-dsl' +import { getDescriptor } from '../controls/registry' +import type { CanvasContext } from '../controls/types' +import { setGridChildrenInTree, setRowChildrenInTree, setTableChildrenInTree, forEachControlInTree } from '../types/form-dsl' +import { createControl, ALL_CONTROL_TYPES } from '../controls/registry' +import { CanvasPreviewErrorBoundary } from './CanvasPreviewErrorBoundary' + +function validateField(value: unknown, rules: ValidationRule[]): string | null { + for (const rule of rules) { + const strVal = value != null ? String(value) : '' + switch (rule.type) { + case 'required': + if (!strVal.trim()) return rule.message + break + case 'minLength': + if (typeof rule.value === 'number' && strVal.length < rule.value) return rule.message + break + case 'maxLength': + if (typeof rule.value === 'number' && strVal.length > rule.value) return rule.message + break + case 'min': + if (typeof rule.value === 'number' && Number(strVal) < rule.value) return rule.message + break + case 'max': + if (typeof rule.value === 'number' && Number(strVal) > rule.value) return rule.message + break + case 'pattern': + if (typeof rule.value === 'string') { + try { + if (!new RegExp(rule.value).test(strVal)) return rule.message + } catch { /* invalid regex */ } + } + break + case 'custom': + /* custom rules require runtime logic; in preview we skip them */ + break + } + } + return null +} + +function evaluateCondition(condition: Condition, values: Record): boolean { + const fieldVal = values[condition.fieldName] + const strVal = fieldVal != null ? String(fieldVal) : '' + switch (condition.operator) { + case 'eq': return strVal === (condition.value ?? '') + case 'neq': return strVal !== (condition.value ?? '') + case 'gt': return Number(strVal) > Number(condition.value ?? 0) + case 'lt': return Number(strVal) < Number(condition.value ?? 0) + case 'contains': return strVal.includes(condition.value ?? '') + case 'empty': return !strVal.trim() + case 'notEmpty': return !!strVal.trim() + default: return true + } +} + +function PreviewControl({ + control, + values, + errors, + onValueChange, +}: { + control: FormControl + values: Record + errors: Record + onValueChange: (fieldName: string, value: unknown) => void +}) { + if (control.visibleWhen && !evaluateCondition(control.visibleWhen, values)) { + return null + } + + const isDisabledByCondition = control.disabledWhen ? evaluateCondition(control.disabledWhen, values) : false + const fieldName = control.fieldName + const error = fieldName ? errors[fieldName] : undefined + + const noop = () => {} + const dummyContext: CanvasContext = { + selectedId: null, + onSelect: noop, + onRemove: noop, + rootSetControls: noop as React.Dispatch>, + renderControlBlock: () => null, + createControl, + controlTypes: ALL_CONTROL_TYPES, + dataTypeKey: '', + dataIdKey: '', + setGridChildrenInTree, + setRowChildrenInTree, + setTableChildrenInTree, + } + + const descriptor = getDescriptor(control.type as FormControl['type']) + + return ( +
+ {fieldName && ( + + {fieldName} + {control.validation?.some((r) => r.type === 'required') && ( + * + )} + + )} +
+ {descriptor ? ( + + [0]['control']} context={dummyContext} /> + + ) : ( + [{control.type}] + )} +
+ {fieldName && ( + onValueChange(fieldName, e.target.value)} + placeholder={`Значение ${fieldName}`} + style={{ + width: '100%', + marginTop: 4, + padding: '4px 8px', + border: error ? '1px solid var(--danger--main, #e00)' : '1px solid #d9d9d9', + borderRadius: 4, + fontSize: 13, + }} + /> + )} + {error && ( + + {error} + + )} +
+ ) +} + +export function FormPreview({ + controls, + formData, +}: { + controls: FormControl[] + formData: FormData +}) { + const [values, setValues] = useState>(() => { + const init: Record = {} + forEachControlInTree(controls, (c) => { + if (c.fieldName && c.defaultValue !== undefined) { + init[c.fieldName] = c.defaultValue + } + }) + return init + }) + const [errors, setErrors] = useState>({}) + const [submitted, setSubmitted] = useState(false) + const [submitData, setSubmitData] = useState(null) + + const handleValueChange = useCallback((fieldName: string, value: unknown) => { + setValues((prev) => ({ ...prev, [fieldName]: value })) + setErrors((prev) => { + const next = { ...prev } + delete next[fieldName] + return next + }) + }, []) + + const handleSubmit = useCallback(() => { + const newErrors: Record = {} + forEachControlInTree(controls, (c) => { + if (c.fieldName && c.validation && c.validation.length > 0) { + const err = validateField(values[c.fieldName], c.validation) + if (err) newErrors[c.fieldName] = err + } + }) + setErrors(newErrors) + setSubmitted(true) + if (Object.keys(newErrors).length === 0) { + setSubmitData(JSON.stringify(values, null, 2)) + } else { + setSubmitData(null) + } + }, [controls, values]) + + return ( +
+
{formData.name || 'Форма'}
+ + {controls.map((control) => ( + + ))} + +
+
+ {submitted && submitData && ( + +
{submitData}
+
+ )} + {submitted && Object.keys(errors).length > 0 && ( + + {Object.entries(errors).map(([field, msg]) => ( +
{field}: {msg}
+ ))} +
+ )} +
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/HandlerFilePicker.tsx b/packages/kaspersky-ui-normalization-tool/src/components/HandlerFilePicker.tsx new file mode 100644 index 00000000..2c9a2893 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/HandlerFilePicker.tsx @@ -0,0 +1,120 @@ +import { useState, useEffect, useCallback } from 'react' +import { Button, Text, Space } from '@kaspersky/hexa-ui' +import { Folder, ArrowUp1, Files } from '@kaspersky/hexa-ui-icons/16' +import { getErrorMessage } from '../utils/getErrorMessage' + +const HANDLER_EXT = ['.js', '.ts'] + +export function HandlerFilePicker({ + directoryHandle, + onSelect, + onClose, +}: { + directoryHandle: FileSystemDirectoryHandle + onSelect: (path: string) => void + onClose: () => void +}) { + const [stack, setStack] = useState<{ handle: FileSystemDirectoryHandle; pathPrefix: string }[]>([ + { handle: directoryHandle, pathPrefix: '' }, + ]) + const [entries, setEntries] = useState<{ name: string; kind: 'file' | 'directory' }[]>([]) + const [loading, setLoading] = useState(true) + + const current = stack[stack.length - 1] + + useEffect(() => { + let cancelled = false + setLoading(true) + ;(async () => { + const list: { name: string; kind: 'file' | 'directory' }[] = [] + try { + for await (const [name, handle] of current.handle.entries()) { + if (cancelled) return + const kind = handle.kind as 'file' | 'directory' + if (kind === 'directory') list.push({ name, kind: 'directory' }) + else if (HANDLER_EXT.some((e) => name.toLowerCase().endsWith(e))) list.push({ name, kind: 'file' }) + } + if (!cancelled) { + list.sort((a, b) => (a.kind !== b.kind ? (a.kind === 'directory' ? -1 : 1) : a.name.localeCompare(b.name))) + setEntries(list) + } + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { cancelled = true } + }, [current.handle]) + + const [dirError, setDirError] = useState(null) + const goIn = useCallback( + (name: string) => { + setDirError(null) + current.handle + .getDirectoryHandle(name) + .then((handle) => { + setStack((prev) => [...prev, { handle, pathPrefix: current.pathPrefix + name + '/' }]) + }) + .catch((err) => { + setDirError(getErrorMessage(err, 'Не удалось открыть каталог')) + }) + }, + [current] + ) + + const goUp = useCallback(() => { + setStack((prev) => (prev.length <= 1 ? prev : prev.slice(0, -1))) + }, []) + + const entryHoverStyle = { background: 'var(--surface--neutral2, #f5f5f5)' } + + return ( +
+
+ {stack.length > 1 && ( +
+ {dirError && {dirError}} + {loading ? ( + Загрузка… + ) : entries.length === 0 ? ( + Нет файлов .js / .ts + ) : ( + + {entries.map(({ name, kind }) => ( +
kind === 'directory' ? goIn(name) : (onSelect(current.pathPrefix + name), onClose())} + onKeyDown={(e) => { + if (e.key !== 'Enter') return + kind === 'directory' ? goIn(name) : (onSelect(current.pathPrefix + name), onClose()) + }} + onMouseOver={(e) => Object.assign(e.currentTarget.style, entryHoverStyle)} + onMouseOut={(e) => { e.currentTarget.style.background = '' }} + style={{ + display: 'flex', alignItems: 'center', gap: 6, + padding: '4px 8px', cursor: 'pointer', borderRadius: 4, + }} + > + {kind === 'directory' ? : } + {name} +
+ ))} +
+ )} +
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/HandlersEditor.tsx b/packages/kaspersky-ui-normalization-tool/src/components/HandlersEditor.tsx new file mode 100644 index 00000000..8d949fd5 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/HandlersEditor.tsx @@ -0,0 +1,89 @@ +import { useState } from 'react' +import { Text, Textbox, Button, Space } from '@kaspersky/hexa-ui' +import { Cross, Folder } from '@kaspersky/hexa-ui-icons/16' +import type { EventDefinition } from '../types/form-dsl' +import { HandlerFilePicker } from './HandlerFilePicker' + +export function HandlersEditor({ + title, + events, + handlers, + onChange, + directoryHandle, +}: { + title: string + events: EventDefinition[] + handlers: Record + onChange: (handlers: Record) => void + directoryHandle?: FileSystemDirectoryHandle | null +}) { + const [openPicker, setOpenPicker] = useState(null) + + if (events.length === 0) return null + + const setHandler = (eventName: string, path: string | undefined) => { + const next = { ...handlers } + if (path) next[eventName] = path + else delete next[eventName] + onChange(next) + } + + return ( +
+ + {title} + + + {events.map((event) => { + const value = handlers[event.name] ?? '' + const isPickerOpen = openPicker === event.name + return ( +
+ + {event.label} ({event.name}) + +
+ setHandler(event.name, v || undefined)} + placeholder="handlers/example.js" + style={{ flex: 1 }} + /> + {value && ( +
+ {isPickerOpen && directoryHandle && ( + { + setHandler(event.name, path) + setOpenPicker(null) + }} + onClose={() => setOpenPicker(null)} + /> + )} +
+ ) + })} +
+
+ ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/PropertiesPanel.tsx b/packages/kaspersky-ui-normalization-tool/src/components/PropertiesPanel.tsx new file mode 100644 index 00000000..5d953ab5 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/PropertiesPanel.tsx @@ -0,0 +1,626 @@ +import React, { useState } from 'react' +import { Space, Text, H6, Textbox, Select, Checkbox as HexaCheckbox, Button } from '@kaspersky/hexa-ui' +import { Add, Delete } from '@kaspersky/hexa-ui-icons/16' +import { SelectWithOptionWidth } from './SelectWithOptionWidth' +import type { FormControl, FormData, GridControl, TableControl, FieldSchema, ValidationRule, ValidationRuleType, Condition } from '../types/form-dsl' +import { EXTRA_UI_DSL_TYPES } from '../types/form-dsl' +import { CONTROL_EVENTS, FORM_EVENTS } from '../types/form-dsl' +import { getDescriptor } from '../controls/registry' +import { ToolbarItemEditor } from '../controls/descriptors/toolbar' +import { HandlersEditor } from './HandlersEditor' + +const INPUT_CONTROL_TYPES: string[] = ['button', 'text', 'input', 'checkbox', 'radio', 'select', 'toggle', ...EXTRA_UI_DSL_TYPES] +const DATA_TYPE_OPTIONS = [ + { value: 'string', label: 'string' }, + { value: 'number', label: 'number' }, + { value: 'boolean', label: 'boolean' }, + { value: 'date', label: 'date' }, + { value: 'array', label: 'array' }, +] + +function isInputControl(control: FormControl): boolean { + if (INPUT_CONTROL_TYPES.includes(control.type)) return true + return false +} + +function FieldBindingEditor({ + control, + onUpdate, + selectCloseKey, + onSelectClose, +}: { + control: FormControl + onUpdate: (patch: Partial) => void + selectCloseKey: number + onSelectClose: () => void +}) { + if (!isInputControl(control)) return null + const hasRequired = (control.validation ?? []).some((r) => r.type === 'required') + return ( + <> +
+ + Привязка данных + {hasRequired && *} + + +
+ Имя поля (fieldName) + onUpdate({ fieldName: v || undefined } as Partial)} + placeholder="например: email" + /> +
+
+ Тип данных + + onSchemaUpdate({ ...schema, [name]: { ...field, type: e.target.value as FieldSchema['type'] } })} + style={{ height: 32, borderRadius: 4, border: '1px solid #ccc', padding: '0 4px' }} + > + + + + + + +
+ ))} +
+ { if (e.key === 'Enter') addField() }} + /> +
+
+
+ ) +} + +const VALIDATION_RULE_OPTIONS: { value: ValidationRuleType; label: string }[] = [ + { value: 'required', label: 'Обязательное' }, + { value: 'minLength', label: 'Мин. длина' }, + { value: 'maxLength', label: 'Макс. длина' }, + { value: 'min', label: 'Мин. значение' }, + { value: 'max', label: 'Макс. значение' }, + { value: 'pattern', label: 'Регулярное выражение' }, + { value: 'custom', label: 'Пользовательское' }, +] + +function ValidationEditor({ + rules, + onChange, +}: { + rules: ValidationRule[] + onChange: (rules: ValidationRule[]) => void +}) { + const addRule = () => { + onChange([...rules, { type: 'required', message: 'Обязательное поле' }]) + } + + return ( +
+ Валидация + + {rules.map((rule, i) => ( +
+
+ +
+ {rule.type !== 'required' && ( +
+ Значение + { + const next = [...rules] + const numVal = Number(v) + next[i] = { ...rule, value: !isNaN(numVal) && v.trim() !== '' && ['minLength', 'maxLength', 'min', 'max'].includes(rule.type) ? numVal : v } + onChange(next) + }} + placeholder={rule.type === 'pattern' ? '^[a-z]+$' : '0'} + /> +
+ )} +
+ Сообщение об ошибке + { + const next = [...rules] + next[i] = { ...rule, message: v } + onChange(next) + }} + placeholder="Обязательное поле" + /> +
+
+ ))} +
+ ) +} + +const CONDITION_OPERATORS: { value: Condition['operator']; label: string }[] = [ + { value: 'eq', label: '=' }, + { value: 'neq', label: '≠' }, + { value: 'gt', label: '>' }, + { value: 'lt', label: '<' }, + { value: 'contains', label: 'содержит' }, + { value: 'empty', label: 'пусто' }, + { value: 'notEmpty', label: 'не пусто' }, +] + +function ConditionEditor({ + label, + condition, + onChange, +}: { + label: string + condition?: Condition + onChange: (c: Condition | undefined) => void +}) { + const enabled = !!condition + return ( +
+ { + if (e.target.checked) { + onChange({ fieldName: '', operator: 'eq', value: '' }) + } else { + onChange(undefined) + } + }} + > + {label} + + {enabled && condition && ( +
+ onChange({ ...condition, fieldName: v })} + placeholder="поле" + style={{ flex: 1, minWidth: 60 }} + /> + + {condition.operator !== 'empty' && condition.operator !== 'notEmpty' && ( + onChange({ ...condition, value: v })} + placeholder="значение" + style={{ flex: 1, minWidth: 60 }} + /> + )} +
+ )} +
+ ) +} + +const panelStyle: React.CSSProperties = { + width: '100%', + minWidth: 0, + flexShrink: 0, + padding: 16, + borderLeft: '1px solid var(--tagsoutlined--neutral-border, #E7E7E9)', + background: 'var(--surface--neutral, #FFFFFF)', + overflowY: 'auto', + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'stretch', + textAlign: 'left', +} + +export interface PropertiesPanelProps { + /** Данные формы (для отображения свойств формы при отсутствии выбранного элемента) */ + formData: FormData | null + onFormUpdate: (patch: Partial) => void + /** Выбранный контрол на форме; при null показываются свойства формы */ + control: FormControl | null + onUpdate: (id: string, patch: Partial) => void + /** Каталог формы (для file picker обработчика кнопки) */ + formDirectoryHandle?: FileSystemDirectoryHandle | null +} + +export function PropertiesPanel({ formData, onFormUpdate, control, onUpdate, formDirectoryHandle }: PropertiesPanelProps) { + /** Смена key после выбора пересоздаёт Select и закрывает выпадающий список */ + const [selectCloseKey, setSelectCloseKey] = useState(0) + + if (!control) { + return ( + + ) + } + + const update = (patch: Partial) => onUpdate(control.id, patch) + + return ( + + ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/components/SelectWithOptionWidth.tsx b/packages/kaspersky-ui-normalization-tool/src/components/SelectWithOptionWidth.tsx new file mode 100644 index 00000000..0d7553e2 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/components/SelectWithOptionWidth.tsx @@ -0,0 +1,51 @@ +import React, { useRef, useEffect, useState } from 'react' + +/** Обёртка: ширина селекта = макс. ширина опций (измерение по тексту опций) */ +export function SelectWithOptionWidth({ + options, + children, +}: { + options: { label: string; value: string }[] + children: React.ReactNode +}) { + const [minWidth, setMinWidth] = useState(100) + const rulerRef = useRef(null) + + useEffect(() => { + if (!rulerRef.current || !options.length) { + setMinWidth(100) + return + } + const spans = rulerRef.current.querySelectorAll('span') + let max = 0 + spans.forEach((s) => { + max = Math.max(max, (s as HTMLSpanElement).offsetWidth) + }) + setMinWidth(max + 48) // отступы под стрелку и padding селектора + }, [options]) + + return ( + <> +
+ {options.map((o) => ( + + {String(o.label)} + + ))} +
+
{children}
+ + ) +} diff --git a/packages/kaspersky-ui-normalization-tool/src/constants.ts b/packages/kaspersky-ui-normalization-tool/src/constants.ts new file mode 100644 index 00000000..5352435d --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/constants.ts @@ -0,0 +1,2 @@ +/** Расширение файлов форм. Используется для фильтра списка, создания новых файлов и текстов в UI. */ +export const FORM_EXT = '.js' diff --git a/packages/kaspersky-ui-normalization-tool/src/controls/descriptors/button.tsx b/packages/kaspersky-ui-normalization-tool/src/controls/descriptors/button.tsx new file mode 100644 index 00000000..7162ec83 --- /dev/null +++ b/packages/kaspersky-ui-normalization-tool/src/controls/descriptors/button.tsx @@ -0,0 +1,54 @@ +import { Button, Text, Textbox, Space } from '@kaspersky/hexa-ui' +import { Cursor } from '@kaspersky/hexa-ui-icons/16' +import type { ControlDescriptor } from '../types' +import type { ButtonControl } from '../../types/form-dsl' + +export const buttonDescriptor: ControlDescriptor = { + type: 'button', + label: 'Кнопка', + Icon: Cursor, + + createDefault: () => ({ + type: 'button', + id: '', + text: 'Кнопка', + mode: 'primary', + }), + + CanvasPreview: ({ control }) => ( +