Compare commits

..

9 Commits

Author SHA1 Message Date
Ivan
1f84abbc24 M: Small UI layout fixes
Some checks failed
Backend CI / build (3.12) (push) Has been cancelled
Frontend CI / build (22.x) (push) Has been cancelled
2024-09-21 20:24:18 +03:00
Ivan
d12e8fed22 M: Fix syntax error message 2024-09-21 17:27:59 +03:00
Ivan
6d8462565a M: Minor UI fixes 2024-09-19 21:14:51 +03:00
Ivan
02b07d2874 R: React.PropsWithChildren 2024-09-19 17:48:48 +03:00
Ivan
08634e396e R: use React.ComponentProps 2024-09-19 17:36:24 +03:00
Ivan
ccf1818e20 B: Fix inserting operation in empty OSS 2024-09-19 16:26:49 +03:00
Ivan
9e075dc67d npm update 2024-09-18 16:28:25 +03:00
Ivan
c3c38ac7da B: Fix initial data 2024-09-18 16:25:44 +03:00
Ivan
a753273d6d M: Minor fix to AST viewer 2024-09-18 15:53:43 +03:00
58 changed files with 393 additions and 1030 deletions

View File

@ -1,616 +1,4 @@
[
{
"model": "auth.permission",
"pk": 1,
"fields": {
"name": "Can add log entry",
"content_type": 1,
"codename": "add_logentry"
}
},
{
"model": "auth.permission",
"pk": 2,
"fields": {
"name": "Can change log entry",
"content_type": 1,
"codename": "change_logentry"
}
},
{
"model": "auth.permission",
"pk": 3,
"fields": {
"name": "Can delete log entry",
"content_type": 1,
"codename": "delete_logentry"
}
},
{
"model": "auth.permission",
"pk": 4,
"fields": {
"name": "Can view log entry",
"content_type": 1,
"codename": "view_logentry"
}
},
{
"model": "auth.permission",
"pk": 5,
"fields": {
"name": "Can add permission",
"content_type": 2,
"codename": "add_permission"
}
},
{
"model": "auth.permission",
"pk": 6,
"fields": {
"name": "Can change permission",
"content_type": 2,
"codename": "change_permission"
}
},
{
"model": "auth.permission",
"pk": 7,
"fields": {
"name": "Can delete permission",
"content_type": 2,
"codename": "delete_permission"
}
},
{
"model": "auth.permission",
"pk": 8,
"fields": {
"name": "Can view permission",
"content_type": 2,
"codename": "view_permission"
}
},
{
"model": "auth.permission",
"pk": 9,
"fields": {
"name": "Can add group",
"content_type": 3,
"codename": "add_group"
}
},
{
"model": "auth.permission",
"pk": 10,
"fields": {
"name": "Can change group",
"content_type": 3,
"codename": "change_group"
}
},
{
"model": "auth.permission",
"pk": 11,
"fields": {
"name": "Can delete group",
"content_type": 3,
"codename": "delete_group"
}
},
{
"model": "auth.permission",
"pk": 12,
"fields": {
"name": "Can view group",
"content_type": 3,
"codename": "view_group"
}
},
{
"model": "auth.permission",
"pk": 13,
"fields": {
"name": "Can add user",
"content_type": 4,
"codename": "add_user"
}
},
{
"model": "auth.permission",
"pk": 14,
"fields": {
"name": "Can change user",
"content_type": 4,
"codename": "change_user"
}
},
{
"model": "auth.permission",
"pk": 15,
"fields": {
"name": "Can delete user",
"content_type": 4,
"codename": "delete_user"
}
},
{
"model": "auth.permission",
"pk": 16,
"fields": {
"name": "Can view user",
"content_type": 4,
"codename": "view_user"
}
},
{
"model": "auth.permission",
"pk": 17,
"fields": {
"name": "Can add content type",
"content_type": 5,
"codename": "add_contenttype"
}
},
{
"model": "auth.permission",
"pk": 18,
"fields": {
"name": "Can change content type",
"content_type": 5,
"codename": "change_contenttype"
}
},
{
"model": "auth.permission",
"pk": 19,
"fields": {
"name": "Can delete content type",
"content_type": 5,
"codename": "delete_contenttype"
}
},
{
"model": "auth.permission",
"pk": 20,
"fields": {
"name": "Can view content type",
"content_type": 5,
"codename": "view_contenttype"
}
},
{
"model": "auth.permission",
"pk": 21,
"fields": {
"name": "Can add session",
"content_type": 6,
"codename": "add_session"
}
},
{
"model": "auth.permission",
"pk": 22,
"fields": {
"name": "Can change session",
"content_type": 6,
"codename": "change_session"
}
},
{
"model": "auth.permission",
"pk": 23,
"fields": {
"name": "Can delete session",
"content_type": 6,
"codename": "delete_session"
}
},
{
"model": "auth.permission",
"pk": 24,
"fields": {
"name": "Can view session",
"content_type": 6,
"codename": "view_session"
}
},
{
"model": "auth.permission",
"pk": 25,
"fields": {
"name": "Can add Password Reset Token",
"content_type": 7,
"codename": "add_resetpasswordtoken"
}
},
{
"model": "auth.permission",
"pk": 26,
"fields": {
"name": "Can change Password Reset Token",
"content_type": 7,
"codename": "change_resetpasswordtoken"
}
},
{
"model": "auth.permission",
"pk": 27,
"fields": {
"name": "Can delete Password Reset Token",
"content_type": 7,
"codename": "delete_resetpasswordtoken"
}
},
{
"model": "auth.permission",
"pk": 28,
"fields": {
"name": "Can view Password Reset Token",
"content_type": 7,
"codename": "view_resetpasswordtoken"
}
},
{
"model": "auth.permission",
"pk": 29,
"fields": {
"name": "Can add Редактор",
"content_type": 8,
"codename": "add_editor"
}
},
{
"model": "auth.permission",
"pk": 30,
"fields": {
"name": "Can change Редактор",
"content_type": 8,
"codename": "change_editor"
}
},
{
"model": "auth.permission",
"pk": 31,
"fields": {
"name": "Can delete Редактор",
"content_type": 8,
"codename": "delete_editor"
}
},
{
"model": "auth.permission",
"pk": 32,
"fields": {
"name": "Can view Редактор",
"content_type": 8,
"codename": "view_editor"
}
},
{
"model": "auth.permission",
"pk": 33,
"fields": {
"name": "Can add Подписка",
"content_type": 9,
"codename": "add_subscription"
}
},
{
"model": "auth.permission",
"pk": 34,
"fields": {
"name": "Can change Подписка",
"content_type": 9,
"codename": "change_subscription"
}
},
{
"model": "auth.permission",
"pk": 35,
"fields": {
"name": "Can delete Подписка",
"content_type": 9,
"codename": "delete_subscription"
}
},
{
"model": "auth.permission",
"pk": 36,
"fields": {
"name": "Can view Подписка",
"content_type": 9,
"codename": "view_subscription"
}
},
{
"model": "auth.permission",
"pk": 37,
"fields": {
"name": "Can add Версия",
"content_type": 10,
"codename": "add_version"
}
},
{
"model": "auth.permission",
"pk": 38,
"fields": {
"name": "Can change Версия",
"content_type": 10,
"codename": "change_version"
}
},
{
"model": "auth.permission",
"pk": 39,
"fields": {
"name": "Can delete Версия",
"content_type": 10,
"codename": "delete_version"
}
},
{
"model": "auth.permission",
"pk": 40,
"fields": {
"name": "Can view Версия",
"content_type": 10,
"codename": "view_version"
}
},
{
"model": "auth.permission",
"pk": 41,
"fields": {
"name": "Can add Схема",
"content_type": 11,
"codename": "add_libraryitem"
}
},
{
"model": "auth.permission",
"pk": 42,
"fields": {
"name": "Can change Схема",
"content_type": 11,
"codename": "change_libraryitem"
}
},
{
"model": "auth.permission",
"pk": 43,
"fields": {
"name": "Can delete Схема",
"content_type": 11,
"codename": "delete_libraryitem"
}
},
{
"model": "auth.permission",
"pk": 44,
"fields": {
"name": "Can view Схема",
"content_type": 11,
"codename": "view_libraryitem"
}
},
{
"model": "auth.permission",
"pk": 45,
"fields": {
"name": "Can add Шаблон",
"content_type": 12,
"codename": "add_librarytemplate"
}
},
{
"model": "auth.permission",
"pk": 46,
"fields": {
"name": "Can change Шаблон",
"content_type": 12,
"codename": "change_librarytemplate"
}
},
{
"model": "auth.permission",
"pk": 47,
"fields": {
"name": "Can delete Шаблон",
"content_type": 12,
"codename": "delete_librarytemplate"
}
},
{
"model": "auth.permission",
"pk": 48,
"fields": {
"name": "Can view Шаблон",
"content_type": 12,
"codename": "view_librarytemplate"
}
},
{
"model": "auth.permission",
"pk": 49,
"fields": {
"name": "Can add Конституента",
"content_type": 13,
"codename": "add_constituenta"
}
},
{
"model": "auth.permission",
"pk": 50,
"fields": {
"name": "Can change Конституента",
"content_type": 13,
"codename": "change_constituenta"
}
},
{
"model": "auth.permission",
"pk": 51,
"fields": {
"name": "Can delete Конституента",
"content_type": 13,
"codename": "delete_constituenta"
}
},
{
"model": "auth.permission",
"pk": 52,
"fields": {
"name": "Can view Конституента",
"content_type": 13,
"codename": "view_constituenta"
}
},
{
"model": "auth.permission",
"pk": 53,
"fields": {
"name": "Can add Аргумент",
"content_type": 14,
"codename": "add_argument"
}
},
{
"model": "auth.permission",
"pk": 54,
"fields": {
"name": "Can change Аргумент",
"content_type": 14,
"codename": "change_argument"
}
},
{
"model": "auth.permission",
"pk": 55,
"fields": {
"name": "Can delete Аргумент",
"content_type": 14,
"codename": "delete_argument"
}
},
{
"model": "auth.permission",
"pk": 56,
"fields": {
"name": "Can view Аргумент",
"content_type": 14,
"codename": "view_argument"
}
},
{
"model": "auth.permission",
"pk": 57,
"fields": {
"name": "Can add Наследование синтеза",
"content_type": 15,
"codename": "add_inheritance"
}
},
{
"model": "auth.permission",
"pk": 58,
"fields": {
"name": "Can change Наследование синтеза",
"content_type": 15,
"codename": "change_inheritance"
}
},
{
"model": "auth.permission",
"pk": 59,
"fields": {
"name": "Can delete Наследование синтеза",
"content_type": 15,
"codename": "delete_inheritance"
}
},
{
"model": "auth.permission",
"pk": 60,
"fields": {
"name": "Can view Наследование синтеза",
"content_type": 15,
"codename": "view_inheritance"
}
},
{
"model": "auth.permission",
"pk": 61,
"fields": {
"name": "Can add Отождествление синтеза",
"content_type": 16,
"codename": "add_substitution"
}
},
{
"model": "auth.permission",
"pk": 62,
"fields": {
"name": "Can change Отождествление синтеза",
"content_type": 16,
"codename": "change_substitution"
}
},
{
"model": "auth.permission",
"pk": 63,
"fields": {
"name": "Can delete Отождествление синтеза",
"content_type": 16,
"codename": "delete_substitution"
}
},
{
"model": "auth.permission",
"pk": 64,
"fields": {
"name": "Can view Отождествление синтеза",
"content_type": 16,
"codename": "view_substitution"
}
},
{
"model": "auth.permission",
"pk": 65,
"fields": {
"name": "Can add Операция",
"content_type": 17,
"codename": "add_operation"
}
},
{
"model": "auth.permission",
"pk": 66,
"fields": {
"name": "Can change Операция",
"content_type": 17,
"codename": "change_operation"
}
},
{
"model": "auth.permission",
"pk": 67,
"fields": {
"name": "Can delete Операция",
"content_type": 17,
"codename": "delete_operation"
}
},
{
"model": "auth.permission",
"pk": 68,
"fields": {
"name": "Can view Операция",
"content_type": 17,
"codename": "view_operation"
}
},
{
"model": "auth.user",
"pk": 1,

View File

@ -35,25 +35,25 @@
},
"devDependencies": {
"@lezer/generator": "^1.7.1",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.4",
"@types/react": "^18.3.5",
"@types/jest": "^29.5.13",
"@types/node": "^22.5.5",
"@types/react": "^18.3.7",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^8.0.1",
"@typescript-eslint/parser": "^8.0.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.20",
"eslint": "^9.10.0",
"eslint-plugin-react": "^7.35.2",
"eslint-plugin-react": "^7.36.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^15.9.0",
"jest": "^29.7.0",
"postcss": "^8.4.45",
"tailwindcss": "^3.4.10",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.12",
"ts-jest": "^29.2.5",
"typescript": "^5.6.2",
"typescript-eslint": "^8.5.0",
"vite": "^5.4.4"
"typescript-eslint": "^8.6.0",
"vite": "^5.4.6"
}
},
"node_modules/@alloc/quick-lru": {
@ -663,9 +663,9 @@
"license": "MIT"
},
"node_modules/@codemirror/autocomplete": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz",
"integrity": "sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA==",
"version": "6.18.1",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.1.tgz",
"integrity": "sha512-iWHdj/B1ethnHRTwZj+C1obmmuCzquH29EbcKr0qIjA9NfDeBDJ7vs+WOHsFeLeflE4o+dHfYndJloMKHUkWUA==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
@ -681,9 +681,9 @@
}
},
"node_modules/@codemirror/commands": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.1.tgz",
"integrity": "sha512-iBfKbyIoXS1FGdsKcZmnrxmbc8VcbMrSgD7AVrsnX+WyAYjmUDWvE93dt5D874qS4CCVu4O1JpbagHdXbbLiOw==",
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.2.tgz",
"integrity": "sha512-Fq7eWOl1Rcbrfn6jD8FPCj9Auaxdm5nIK5RYOeW7ughnd/rY5AmPg6b+CfsG39ZHdwiwe8lde3q8uR7CF5S0yQ==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
@ -1321,9 +1321,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
"integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
"dev": true,
"license": "MIT",
"engines": {
@ -1464,28 +1464,28 @@
}
},
"node_modules/@floating-ui/core": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz",
"integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==",
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.7"
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz",
"integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==",
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz",
"integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.7"
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz",
"integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==",
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@formatjs/ecma402-abstract": {
@ -2897,9 +2897,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
"integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz",
"integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==",
"cpu": [
"arm"
],
@ -2911,9 +2911,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
"integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz",
"integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==",
"cpu": [
"arm64"
],
@ -2925,9 +2925,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
"integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz",
"integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==",
"cpu": [
"arm64"
],
@ -2939,9 +2939,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
"integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz",
"integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==",
"cpu": [
"x64"
],
@ -2953,9 +2953,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
"integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz",
"integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==",
"cpu": [
"arm"
],
@ -2967,9 +2967,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
"integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz",
"integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==",
"cpu": [
"arm"
],
@ -2981,9 +2981,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
"integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz",
"integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==",
"cpu": [
"arm64"
],
@ -2995,9 +2995,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
"integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz",
"integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==",
"cpu": [
"arm64"
],
@ -3009,9 +3009,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
"integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz",
"integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==",
"cpu": [
"ppc64"
],
@ -3023,9 +3023,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
"integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz",
"integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==",
"cpu": [
"riscv64"
],
@ -3037,9 +3037,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
"integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz",
"integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==",
"cpu": [
"s390x"
],
@ -3051,9 +3051,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
"integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz",
"integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==",
"cpu": [
"x64"
],
@ -3065,9 +3065,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
"integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz",
"integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==",
"cpu": [
"x64"
],
@ -3079,9 +3079,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
"integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz",
"integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==",
"cpu": [
"arm64"
],
@ -3093,9 +3093,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
"integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz",
"integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==",
"cpu": [
"ia32"
],
@ -3107,9 +3107,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
"integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz",
"integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==",
"cpu": [
"x64"
],
@ -3551,9 +3551,9 @@
}
},
"node_modules/@types/jest": {
"version": "29.5.12",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
"integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
"version": "29.5.13",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.13.tgz",
"integrity": "sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3562,9 +3562,9 @@
}
},
"node_modules/@types/node": {
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
"version": "22.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
"integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3584,15 +3584,15 @@
"license": "MIT"
},
"node_modules/@types/prop-types": {
"version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.5",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz",
"integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==",
"version": "18.3.7",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.7.tgz",
"integrity": "sha512-KUnDCJF5+AiZd8owLIeVHqmW9yM4sqmDVf2JRJiBMFkGvkoZ4/WyV2lL4zVsoinmRS/W3FeEdZLEWFRofnT2FQ==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
@ -3685,17 +3685,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz",
"integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz",
"integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.5.0",
"@typescript-eslint/type-utils": "8.5.0",
"@typescript-eslint/utils": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0",
"@typescript-eslint/scope-manager": "8.6.0",
"@typescript-eslint/type-utils": "8.6.0",
"@typescript-eslint/utils": "8.6.0",
"@typescript-eslint/visitor-keys": "8.6.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@ -3719,16 +3719,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz",
"integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz",
"integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/scope-manager": "8.5.0",
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/typescript-estree": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0",
"@typescript-eslint/scope-manager": "8.6.0",
"@typescript-eslint/types": "8.6.0",
"@typescript-eslint/typescript-estree": "8.6.0",
"@typescript-eslint/visitor-keys": "8.6.0",
"debug": "^4.3.4"
},
"engines": {
@ -3748,14 +3748,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz",
"integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz",
"integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0"
"@typescript-eslint/types": "8.6.0",
"@typescript-eslint/visitor-keys": "8.6.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3766,14 +3766,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz",
"integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz",
"integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/typescript-estree": "8.5.0",
"@typescript-eslint/utils": "8.5.0",
"@typescript-eslint/typescript-estree": "8.6.0",
"@typescript-eslint/utils": "8.6.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@ -3791,9 +3791,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz",
"integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz",
"integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==",
"dev": true,
"license": "MIT",
"engines": {
@ -3805,14 +3805,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz",
"integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz",
"integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0",
"@typescript-eslint/types": "8.6.0",
"@typescript-eslint/visitor-keys": "8.6.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@ -3834,16 +3834,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz",
"integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz",
"integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.5.0",
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/typescript-estree": "8.5.0"
"@typescript-eslint/scope-manager": "8.6.0",
"@typescript-eslint/types": "8.6.0",
"@typescript-eslint/typescript-estree": "8.6.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3857,13 +3857,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz",
"integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz",
"integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/types": "8.6.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@ -3985,9 +3985,9 @@
}
},
"node_modules/@webgpu/types": {
"version": "0.1.44",
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.44.tgz",
"integrity": "sha512-JDpYJN5E/asw84LTYhKyvPpxGnD+bAKPtpW9Ilurf7cZpxaTbxkQcGwOd7jgB9BPBrTYQ+32ufo4HiuomTjHNQ==",
"version": "0.1.45",
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.45.tgz",
"integrity": "sha512-0TBBF/mhakJoK0qUWCZugBnh23x+VwmYA5RLmtNQwvZt1pQ4P2fzIvQUiSe6jxzkBi4GF8R4BejJjro0ZSoSXQ==",
"license": "BSD-3-Clause",
"peer": true
},
@ -5534,9 +5534,9 @@
}
},
"node_modules/detect-gpu": {
"version": "5.0.47",
"resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.47.tgz",
"integrity": "sha512-hxOjFbFN6/ToNzDs0SIt/P/Y1WxoxAEUXXlrw/HT2IPtDtIxSi57zP/TC6kTvWDWmwSnvfVHsPoDZihscx8OJQ==",
"version": "5.0.48",
"resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.48.tgz",
"integrity": "sha512-AdG8ur7loIIIzG8XBjNiLk6Seq4jGp7GAL2TEsjq7etgK8ia6ha3rTbBCRCHsnwYiLqYn4uWJfS7hVwZz7DKNQ==",
"license": "MIT",
"dependencies": {
"webgl-constants": "^1.1.1"
@ -5629,9 +5629,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.19",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.19.tgz",
"integrity": "sha512-kpLJJi3zxTR1U828P+LIUDZ5ohixyo68/IcYOHLqnbTPr/wdgn4i1ECvmALN9E16JPA6cvCG5UG79gVwVdEK5w==",
"version": "1.5.25",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.25.tgz",
"integrity": "sha512-kMb204zvK3PsSlgvvwzI3wBIcAw15tRkYk+NQdsjdDtcQWTp2RABbMQ9rUBy8KNEOM+/E6ep+XC3AykiWZld4g==",
"dev": true,
"license": "ISC"
},
@ -5955,9 +5955,9 @@
}
},
"node_modules/eslint-plugin-react": {
"version": "7.35.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz",
"integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==",
"version": "7.36.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
"integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -10573,9 +10573,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.45",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
"integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
"version": "8.4.47",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"dev": true,
"funding": [
{
@ -10594,8 +10594,8 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
"picocolors": "^1.1.0",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@ -11442,9 +11442,9 @@
}
},
"node_modules/rollup": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
"integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz",
"integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -11458,22 +11458,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.21.2",
"@rollup/rollup-android-arm64": "4.21.2",
"@rollup/rollup-darwin-arm64": "4.21.2",
"@rollup/rollup-darwin-x64": "4.21.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
"@rollup/rollup-linux-arm-musleabihf": "4.21.2",
"@rollup/rollup-linux-arm64-gnu": "4.21.2",
"@rollup/rollup-linux-arm64-musl": "4.21.2",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
"@rollup/rollup-linux-riscv64-gnu": "4.21.2",
"@rollup/rollup-linux-s390x-gnu": "4.21.2",
"@rollup/rollup-linux-x64-gnu": "4.21.2",
"@rollup/rollup-linux-x64-musl": "4.21.2",
"@rollup/rollup-win32-arm64-msvc": "4.21.2",
"@rollup/rollup-win32-ia32-msvc": "4.21.2",
"@rollup/rollup-win32-x64-msvc": "4.21.2",
"@rollup/rollup-android-arm-eabi": "4.21.3",
"@rollup/rollup-android-arm64": "4.21.3",
"@rollup/rollup-darwin-arm64": "4.21.3",
"@rollup/rollup-darwin-x64": "4.21.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.3",
"@rollup/rollup-linux-arm-musleabihf": "4.21.3",
"@rollup/rollup-linux-arm64-gnu": "4.21.3",
"@rollup/rollup-linux-arm64-musl": "4.21.3",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.3",
"@rollup/rollup-linux-riscv64-gnu": "4.21.3",
"@rollup/rollup-linux-s390x-gnu": "4.21.3",
"@rollup/rollup-linux-x64-gnu": "4.21.3",
"@rollup/rollup-linux-x64-musl": "4.21.3",
"@rollup/rollup-win32-arm64-msvc": "4.21.3",
"@rollup/rollup-win32-ia32-msvc": "4.21.3",
"@rollup/rollup-win32-x64-msvc": "4.21.3",
"fsevents": "~2.3.2"
}
},
@ -12111,9 +12111,9 @@
}
},
"node_modules/tailwindcss": {
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
"integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz",
"integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -12251,9 +12251,9 @@
}
},
"node_modules/three-stdlib": {
"version": "2.32.2",
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.32.2.tgz",
"integrity": "sha512-ZN25Na/Xg7APhGKwJ1zhGdhZDsDGGnnm1k5Z+9LLlnfsFye4jigvbN3eA/Ta8hQmBNmEHXoozpmpKK1x8dCePQ==",
"version": "2.33.0",
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.33.0.tgz",
"integrity": "sha512-V/uycBuqQOP/3Z+FBtpMdj2Ds5PyfJ3VDfMzktEmG4niOIzv7q1y5uMSbMcng0+057m1l0N147FQxsodQo9zBg==",
"license": "MIT",
"dependencies": {
"@types/draco3d": "^1.4.0",
@ -12544,15 +12544,15 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.5.0.tgz",
"integrity": "sha512-uD+XxEoSIvqtm4KE97etm32Tn5MfaZWgWfMMREStLxR6JzvHkc2Tkj7zhTEK5XmtpTmKHNnG8Sot6qDfhHtR1Q==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.6.0.tgz",
"integrity": "sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.5.0",
"@typescript-eslint/parser": "8.5.0",
"@typescript-eslint/utils": "8.5.0"
"@typescript-eslint/eslint-plugin": "8.6.0",
"@typescript-eslint/parser": "8.6.0",
"@typescript-eslint/utils": "8.6.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -12711,9 +12711,9 @@
}
},
"node_modules/vite": {
"version": "5.4.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.4.tgz",
"integrity": "sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==",
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz",
"integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@ -39,25 +39,25 @@
},
"devDependencies": {
"@lezer/generator": "^1.7.1",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.4",
"@types/react": "^18.3.5",
"@types/jest": "^29.5.13",
"@types/node": "^22.5.5",
"@types/react": "^18.3.7",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^8.0.1",
"@typescript-eslint/parser": "^8.0.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.20",
"eslint": "^9.10.0",
"eslint-plugin-react": "^7.35.2",
"eslint-plugin-react": "^7.36.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^15.9.0",
"jest": "^29.7.0",
"postcss": "^8.4.45",
"tailwindcss": "^3.4.10",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.12",
"ts-jest": "^29.2.5",
"typescript": "^5.6.2",
"typescript-eslint": "^8.5.0",
"vite": "^5.4.4"
"typescript-eslint": "^8.6.0",
"vite": "^5.4.6"
},
"jest": {
"preset": "ts-jest",

View File

@ -28,10 +28,7 @@ function ApplicationLayout() {
maxHeight: viewportHeight
}}
>
<main
className='w-full h-full cc-scroll-y'
style={{ overflowY: showScroll ? 'scroll' : 'auto', minHeight: mainHeight }}
>
<main className='cc-scroll-y' style={{ overflowY: showScroll ? 'scroll' : 'auto', minHeight: mainHeight }}>
<Outlet />
</main>
<Footer />

View File

@ -23,7 +23,7 @@ const logError = (error: Error, info: { componentStack?: string | null | undefin
};
// prettier-ignore
function GlobalProviders({ children }: { children: React.ReactNode }) {
function GlobalProviders({ children }: React.PropsWithChildren) {
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}

View File

@ -28,7 +28,6 @@ function Navigation() {
className={clsx(
'z-navigation', // prettier: split lines
'sticky top-0 left-0 right-0',
'w-full',
'clr-app',
'select-none'
)}
@ -36,7 +35,7 @@ function Navigation() {
<ToggleNavigation />
<motion.div
className={clsx(
'pl-2 pr-[1.5rem] sm:pr-[0.9rem] h-[3rem] w-full', // prettier: split lines
'pl-2 pr-[1.5rem] sm:pr-[0.9rem] h-[3rem]', // prettier: split lines
'flex',
'cc-shadow-border'
)}

View File

@ -156,7 +156,6 @@ interface IconSVGProps {
size?: string;
className?: string;
props?: React.SVGProps<SVGSVGElement>;
children: React.ReactNode;
}
export interface IconProps {
@ -164,7 +163,7 @@ export interface IconProps {
className?: string;
}
function MetaIconSVG({ viewBox, size = '1.5rem', className, props, children }: IconSVGProps) {
function MetaIconSVG({ viewBox, size = '1.5rem', className, props, children }: React.PropsWithChildren<IconSVGProps>) {
return (
<svg
width={size}

View File

@ -61,7 +61,7 @@ function InfoError({ error }: InfoErrorProps) {
return (
<AnimateFade
className={clsx(
'min-w-[25rem] w-full',
'min-w-[25rem]',
'px-3 py-2 flex flex-col',
'clr-text-red',
'text-sm font-semibold',

View File

@ -53,7 +53,7 @@ function TooltipOperation({ node, anchor }: TooltipOperationProps) {
dense
noHeader
noFooter
className='w-full text-sm border select-none mb-2'
className='text-sm border select-none mb-2'
data={node.data.operation.substitutions}
columns={columns}
/>

View File

@ -66,35 +66,27 @@ export namespace CProps {
/**
* Represents `div` component with all standard HTML attributes and React-specific properties.
*/
export type Div = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
export type Div = React.ComponentProps<'div'>;
/**
* Represents `button` component with optional title and HTML attributes.
*/
export type Button = Titled &
Omit<
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
'children' | 'type'
>;
export type Button = Titled & Omit<React.ComponentProps<'button'>, 'children' | 'type'>;
/**
* Represents `label` component with HTML attributes.
*/
export type Label = Omit<
React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>,
'children'
>;
export type Label = Omit<React.ComponentProps<'label'>, 'children'>;
/**
* Represents `textarea` component with optional title and HTML attributes.
*/
export type TextArea = Titled &
React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;
export type TextArea = Titled & React.ComponentProps<'textarea'>;
/**
* Represents `input` component with optional title and HTML attributes.
*/
export type Input = Titled & React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
export type Input = Titled & React.ComponentProps<'input'>;
/**
* Represents `button` component with optional title and animation properties.

View File

@ -130,7 +130,6 @@ function PickMultiOperation({ rows, items, selected, setSelected }: PickMultiOpe
items={nonSelectedItems} // prettier: split-line
value={lastSelected}
onSelectValue={handleSelect}
className='w-full'
/>
<DataTable
dense

View File

@ -124,7 +124,7 @@ function PickSchema({
<div className='flex justify-between clr-input items-center pr-1'>
<SearchBar
id={id ? `${id}__search` : undefined}
className='clr-input w-full'
className='clr-input flex-grow'
noBorder
value={filterText}
onChange={newValue => setFilterText(newValue)}

View File

@ -257,26 +257,24 @@ function PickSubstitutions({
);
return (
<div className='flex flex-col w-full'>
<div className='flex flex-col'>
<div className='flex items-end gap-3 justify-stretch'>
<div className='flex-grow flex flex-col basis-1/2'>
<div className='flex flex-col gap-[0.125rem] border-x border-t clr-input'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== rightArgument?.id)}
value={leftArgument}
onSelectValue={setLeftArgument}
/>
<SelectConstituenta
noBorder
items={(leftArgument as IRSForm)?.items.filter(
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
)}
value={leftCst}
onSelectValue={setLeftCst}
/>
</div>
<div className='flex-grow flex flex-col basis-1/2 gap-[0.125rem] border-x border-t clr-input'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== rightArgument?.id)}
value={leftArgument}
onSelectValue={setLeftArgument}
/>
<SelectConstituenta
noBorder
items={(leftArgument as IRSForm)?.items.filter(
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
)}
value={leftCst}
onSelectValue={setLeftCst}
/>
</div>
<div className='flex flex-col gap-1'>
<MiniButton
@ -290,7 +288,6 @@ function PickSubstitutions({
)
}
/>
<MiniButton
title='Добавить в таблицу отождествлений'
className='mb-[0.375rem] grow-0'
@ -300,24 +297,22 @@ function PickSubstitutions({
/>
</div>
<div className='flex-grow basis-1/2'>
<div className='flex flex-col gap-[0.125rem] border-x border-t clr-input'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== leftArgument?.id)}
value={rightArgument}
onSelectValue={setRightArgument}
/>
<SelectConstituenta
noBorder
items={(rightArgument as IRSForm)?.items.filter(
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
)}
value={rightCst}
onSelectValue={setRightCst}
/>
</div>
<div className='flex-grow basis-1/2 flex flex-col gap-[0.125rem] border-x border-t clr-input'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== leftArgument?.id)}
value={rightArgument}
onSelectValue={setRightArgument}
/>
<SelectConstituenta
noBorder
items={(rightArgument as IRSForm)?.items.filter(
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
)}
value={rightCst}
onSelectValue={setRightCst}
/>
</div>
</div>
@ -325,7 +320,7 @@ function PickSubstitutions({
dense
noHeader
noFooter
className='w-full text-sm border select-none cc-scroll-y'
className='text-sm border select-none cc-scroll-y'
rows={rows}
contentHeight='1.3rem'
data={substitutionData}

View File

@ -52,7 +52,7 @@ function SelectLocationContext({
/>
<Dropdown
isOpen={menu.isOpen}
className={clsx('w-[20rem] h-[12.5rem] z-modalTooltip mt-0', className)}
className={clsx('w-[20rem] h-[12.5rem] z-modalTooltip mt-[-0.25rem]', className)}
style={style}
>
<SelectLocation

View File

@ -40,7 +40,7 @@ function SelectVersion({ id, className, items, value, onSelectValue, ...restProp
return (
<SelectSingle
id={id}
className={clsx('w-full min-w-[12rem] text-ellipsis', className)}
className={clsx('min-w-[12rem] text-ellipsis', className)}
options={options}
value={{ value: value, label: valueLabel }}
onChange={data => onSelectValue(data?.value)}

View File

@ -14,15 +14,19 @@ interface DropdownProps extends CProps.Styling {
/** Indicates whether the dropdown is open. */
isOpen: boolean;
/** Children to render inside the component. */
children: React.ReactNode;
}
/**
* Dropdown animated component that displays a list of children with optional positioning and visibility control.
*/
function Dropdown({ isOpen, stretchLeft, stretchTop, className, children, ...restProps }: DropdownProps) {
function Dropdown({
isOpen,
stretchLeft,
stretchTop,
className,
children,
...restProps
}: React.PropsWithChildren<DropdownProps>) {
return (
<div className='relative'>
<motion.div

View File

@ -27,8 +27,6 @@ export interface ModalProps extends CProps.Styling {
beforeSubmit?: () => boolean;
onSubmit?: () => void;
onCancel?: () => void;
children: React.ReactNode;
}
function Modal({
@ -45,7 +43,7 @@ function Modal({
overflowVisible,
submitText = 'Продолжить',
...restProps
}: ModalProps) {
}: React.PropsWithChildren<ModalProps>) {
const ref = useRef(null);
useEscapeKey(hideWindow);

View File

@ -4,12 +4,17 @@ import { CProps } from '../props';
interface OverlayProps extends CProps.Styling {
id?: string;
children: React.ReactNode;
position?: string;
layer?: string;
}
function Overlay({ children, className, position = 'top-0 right-0', layer = 'z-pop', ...restProps }: OverlayProps) {
function Overlay({
children,
className,
position = 'top-0 right-0',
layer = 'z-pop',
...restProps
}: React.PropsWithChildren<OverlayProps>) {
return (
<div className='relative'>
<div className={clsx('absolute', className, position, layer)} {...restProps}>

View File

@ -27,7 +27,7 @@ function SearchBar({ id, value, noIcon, onChange, noBorder, placeholder = 'По
noOutline
placeholder={placeholder}
type='search'
className={clsx('w-full outline-none bg-transparent', !noIcon && 'pl-10')}
className={clsx('outline-none bg-transparent', !noIcon && 'pl-10')}
noBorder={noBorder}
value={value}
onChange={event => (onChange ? onChange(event.target.value) : undefined)}

View File

@ -113,7 +113,7 @@ function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option
spacing: {
...theme.spacing, // prettier: split-lines
baseUnit: size.isSmall ? 2 : 4,
menuGutter: size.isSmall ? 4 : 8,
menuGutter: 2,
controlHeight: size.isSmall ? 28 : 38
},
colors: {

View File

@ -11,11 +11,17 @@ interface DataLoaderProps extends CProps.AnimatedDiv {
isLoading?: boolean;
error?: ErrorData;
hasNoData?: boolean;
children: React.ReactNode;
}
function DataLoader({ id, isLoading, hasNoData, error, className, children, ...restProps }: DataLoaderProps) {
function DataLoader({
id,
isLoading,
hasNoData,
error,
className,
children,
...restProps
}: React.PropsWithChildren<DataLoaderProps>) {
return (
<AnimatePresence mode='wait'>
{!isLoading && !error && !hasNoData ? (

View File

@ -8,11 +8,7 @@ import Loader from '../ui/Loader';
import TextURL from '../ui/TextURL';
import AnimateFade from './AnimateFade';
interface RequireAuthProps {
children: React.ReactNode;
}
function RequireAuth({ children }: RequireAuthProps) {
function RequireAuth({ children }: React.PropsWithChildren) {
const { user, loading } = useAuth();
return (

View File

@ -19,12 +19,7 @@ export const useAccessMode = () => {
return context;
};
interface AccessModeStateProps {
children: React.ReactNode;
}
export const AccessModeState = ({ children }: AccessModeStateProps) => {
export const AccessModeState = ({ children }: React.PropsWithChildren) => {
const [accessLevel, setAccessLevel] = useState<UserLevel>(UserLevel.READER);
return <AccessContext.Provider value={{ accessLevel, setAccessLevel }}>{children}</AccessContext.Provider>;
};

View File

@ -52,11 +52,7 @@ export const useAuth = () => {
return context;
};
interface AuthStateProps {
children: React.ReactNode;
}
export const AuthState = ({ children }: AuthStateProps) => {
export const AuthState = ({ children }: React.PropsWithChildren) => {
const { users } = useUsers();
const [user, setUser] = useState<ICurrentUser | undefined>(undefined);
const [loading, setLoading] = useState(true);

View File

@ -52,11 +52,7 @@ export const useConceptOptions = () => {
return context;
};
interface OptionsStateProps {
children: React.ReactNode;
}
export const OptionsState = ({ children }: OptionsStateProps) => {
export const OptionsState = ({ children }: React.PropsWithChildren) => {
const [darkMode, setDarkMode] = useLocalStorage(storage.themeDark, false);
const [adminMode, setAdminMode] = useLocalStorage(storage.optionsAdmin, false);
const [showHelp, setShowHelp] = useLocalStorage(storage.optionsHelp, true);

View File

@ -32,11 +32,7 @@ export const useGlobalOss = (): IGlobalOssContext => {
return context;
};
interface GlobalOssStateProps {
children: React.ReactNode;
}
export const GlobalOssState = ({ children }: GlobalOssStateProps) => {
export const GlobalOssState = ({ children }: React.PropsWithChildren) => {
const library = useLibrary();
const [isValid, setIsValid] = useState(false);
const [ossID, setIdInternal] = useState<string | undefined>(undefined);

View File

@ -61,11 +61,7 @@ export const useLibrary = (): ILibraryContext => {
return context;
};
interface LibraryStateProps {
children: React.ReactNode;
}
export const LibraryState = ({ children }: LibraryStateProps) => {
export const LibraryState = ({ children }: React.PropsWithChildren) => {
const { user, loading: userLoading } = useAuth();
const { adminMode } = useConceptOptions();

View File

@ -27,11 +27,7 @@ export const useConceptNavigation = () => {
return context;
};
interface NavigationStateProps {
children: React.ReactNode;
}
export const NavigationState = ({ children }: NavigationStateProps) => {
export const NavigationState = ({ children }: React.PropsWithChildren) => {
const router = useNavigate();
const { pathname } = useLocation();

View File

@ -78,10 +78,9 @@ export const useOSS = () => {
interface OssStateProps {
itemID: string;
children: React.ReactNode;
}
export const OssState = ({ itemID, children }: OssStateProps) => {
export const OssState = ({ itemID, children }: React.PropsWithChildren<OssStateProps>) => {
const library = useLibrary();
const oss = useGlobalOss();
const model = oss.schema;

View File

@ -107,10 +107,9 @@ export const useRSForm = () => {
interface RSFormStateProps {
itemID: string;
versionID?: string;
children: React.ReactNode;
}
export const RSFormState = ({ itemID, versionID, children }: RSFormStateProps) => {
export const RSFormState = ({ itemID, versionID, children }: React.PropsWithChildren<RSFormStateProps>) => {
const library = useLibrary();
const oss = useGlobalOss();
const { user } = useAuth();

View File

@ -30,11 +30,7 @@ export const useUserProfile = () => {
return context;
};
interface UserProfileStateProps {
children: React.ReactNode;
}
export const UserProfileState = ({ children }: UserProfileStateProps) => {
export const UserProfileState = ({ children }: React.PropsWithChildren) => {
const { users } = useUsers();
const [user, setUser] = useState<IUserProfile | undefined>(undefined);
const [loading, setLoading] = useState(true);

View File

@ -21,11 +21,7 @@ export const useUsers = (): IUsersContext => {
return context;
};
interface UsersStateProps {
children: React.ReactNode;
}
export const UsersState = ({ children }: UsersStateProps) => {
export const UsersState = ({ children }: React.PropsWithChildren) => {
const [users, setUsers] = useState<IUserInfo[]>([]);
function getUserLabel(userID: number | null) {

View File

@ -43,7 +43,7 @@ function DlgChangeLocation({ hideWindow, initial, onChangeLocation }: DlgChangeL
hideWindow={hideWindow}
canSubmit={isValid}
onSubmit={() => onChangeLocation(location)}
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3')}
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3 h-[9rem]')}
>
<div className='flex flex-col gap-2 min-w-[7rem] h-min'>
<Label className='select-none' text='Корень' />

View File

@ -53,7 +53,7 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
<SelectSingle
id='dlg_cst_type'
placeholder='Выберите тип'
className='w-[15rem]'
className='w-[16rem]'
options={SelectorCstType}
value={{ value: state.cst_type, label: labelCstType(state.cst_type) }}
onChange={data => handleTypeChange(data?.value ?? CstType.BASE)}

View File

@ -43,15 +43,7 @@ function DlgDeleteOperation({ hideWindow, target, onSubmit }: DlgDeleteOperation
/>
</Overlay>
<TextInput
disabled
dense
noBorder
id='operation_alias'
label='Операция'
className='w-full'
value={target.alias}
/>
<TextInput disabled dense noBorder id='operation_alias' label='Операция' value={target.alias} />
<Checkbox
label='Сохранить наследованные конституенты'
titleHtml='Наследованные конституенты <br/>превратятся в дописанные'

View File

@ -201,9 +201,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
onClick={handleGenerateLexeme}
/>
</div>
<div
className={clsx('mt-3 mb-2', 'w-full flex justify-center items-center', 'text-sm text-center font-semibold')}
>
<div className={clsx('mt-3 mb-2 mx-auto', 'flex items-center', 'text-sm text-center font-semibold')}>
<div>Заданные вручную словоформы [{forms.length}]</div>
<MiniButton
noHover

View File

@ -37,8 +37,8 @@ function TabSchema({ selected, receiver, setSelected }: TabSchemaProps) {
id='dlg_selected_schema_title'
disabled
noBorder
className='w-full'
placeholder='Выберите из списка ниже'
className='flex-grow'
placeholder='Схема не выбрана'
value={selectedInfo?.title ?? ''}
dense
/>

View File

@ -47,12 +47,12 @@ function DlgRenameCst({ hideWindow, initial, allowChangeType, onRename }: DlgRen
hideWindow={hideWindow}
canSubmit={validated}
onSubmit={() => onRename(cstData)}
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center')}
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center ')}
>
<SelectSingle
id='dlg_cst_type'
placeholder='Выберите тип'
className='min-w-[16rem] self-center'
className='min-w-[16rem]'
isDisabled={!allowChangeType}
options={SelectorCstType}
value={{

View File

@ -53,11 +53,19 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
const handleHoverOut = useCallback(() => setHoverID(undefined), []);
return (
<Modal readonly hideWindow={hideWindow} className='px-6'>
<Overlay position='left-[-1rem] top-[0.25rem]'>
<Modal
readonly
hideWindow={hideWindow}
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
>
<Overlay position='left-[0.5rem] top-[0.25rem]'>
<BadgeHelp topic={HelpTopic.UI_FORMULA_TREE} className={PARAMETER.TOOLTIP_WIDTH} />
</Overlay>
<div className='my-2 text-lg text-center'>
<Overlay
position='top-2 right-1/2 translate-x-1/2'
className='px-2 py-1 rounded-2xl cc-blur max-w-[60ch] text-lg text-center'
style={{ backgroundColor: colors.bgBlur }}
>
{!hoverNode ? expression : null}
{hoverNode ? (
<div>
@ -66,8 +74,8 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
<span>{expression.slice(hoverNode.finish)}</span>
</div>
) : null}
</div>
<div className='relative w-[calc(100vw-6rem-2px)] h-[calc(100svh-14rem-2px)]'>
</Overlay>
<div className='flex-grow relative'>
<GraphUI
animated={false}
nodes={nodes}

View File

@ -1,7 +1,10 @@
/**
* Module: API for miscellaneous frontend model types. Future targets for refactoring aimed at extracting modules.
*/
import { DependencyMode, GraphSizing } from './miscellaneous';
import { PARAMETER } from '@/utils/constants';
import { DependencyMode, GraphSizing, Position2D } from './miscellaneous';
import { IOperationPosition, IOperationSchema, OperationID, OperationType } from './oss';
import { IConstituenta, IRSForm } from './rsform';
/**
@ -47,3 +50,53 @@ export function applyNodeSizing(target: IConstituenta, sizing: GraphSizing): num
return target.spawner ? 1 : 2;
}
}
/**
* Calculate insert position for a new {@link IOperation}
*/
export function calculateInsertPosition(
oss: IOperationSchema,
operationType: OperationType,
argumentsOps: OperationID[],
positions: IOperationPosition[],
defaultPosition: Position2D
): Position2D {
const result = defaultPosition;
if (positions.length === 0) {
return result;
}
if (operationType === OperationType.INPUT) {
let inputsNodes = positions.filter(pos =>
oss.items.find(operation => operation.operation_type === OperationType.INPUT && operation.id === pos.id)
);
if (inputsNodes.length > 0) {
inputsNodes = positions;
}
const maxX = Math.max(...inputsNodes.map(node => node.position_x));
const minY = Math.min(...inputsNodes.map(node => node.position_y));
result.x = maxX + PARAMETER.ossDistanceX;
result.y = minY;
} else {
const argNodes = positions.filter(pos => argumentsOps.includes(pos.id));
const maxY = Math.max(...argNodes.map(node => node.position_y));
const minX = Math.min(...argNodes.map(node => node.position_x));
const maxX = Math.max(...argNodes.map(node => node.position_x));
result.x = Math.ceil((maxX + minX) / 2 / PARAMETER.ossGridSize) * PARAMETER.ossGridSize;
result.y = maxY + PARAMETER.ossDistanceY;
}
let flagIntersect = false;
do {
flagIntersect = positions.some(
position =>
Math.abs(position.position_x - result.x) < PARAMETER.ossMinDistance &&
Math.abs(position.position_y - result.y) < PARAMETER.ossMinDistance
);
if (flagIntersect) {
result.x += PARAMETER.ossMinDistance;
result.y += PARAMETER.ossMinDistance;
}
} while (flagIntersect);
return result;
}

View File

@ -241,7 +241,6 @@ export enum RSErrorType {
invalidArgsArity = 34840,
invalidArgumentType = 34841,
globalStructure = 34844,
globalExpectedFunction = 34847,
radicalUsage = 34849,
invalidFilterArgumentType = 34850,
invalidFilterArity = 34851,

View File

@ -10,6 +10,7 @@ import { CProps } from '@/components/props';
import SelectLocation from '@/components/select/SelectLocation';
import MiniButton from '@/components/ui/MiniButton';
import { useAuth } from '@/context/AuthContext';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import useWindowSize from '@/hooks/useWindowSize';
import { FolderNode, FolderTree } from '@/models/FolderTree';
@ -39,6 +40,7 @@ function ViewSideLocation({
}: ViewSideLocationProps) {
const { user } = useAuth();
const { items } = useLibrary();
const { calculateHeight } = useConceptOptions();
const windowSize = useWindowSize();
const canRename = useMemo(() => {
@ -54,6 +56,7 @@ function ViewSideLocation({
}, [active, user, items]);
const animations = useMemo(() => animateSideMinWidth(windowSize.isSmall ? '10rem' : '15rem'), [windowSize]);
const maxHeight = useMemo(() => calculateHeight('4.5rem'), [calculateHeight]);
const handleClickFolder = useCallback(
(event: CProps.EventMouse, target: FolderNode) => {
@ -105,6 +108,7 @@ function ViewSideLocation({
folderTree={folderTree}
prefix={prefixes.folders_list}
onClick={handleClickFolder}
style={{ maxHeight: maxHeight }}
/>
</motion.div>
);

View File

@ -26,7 +26,7 @@ function ManualsPage() {
);
return (
<div className='flex w-full gap-2' style={{ minHeight: mainHeight }}>
<div className='flex gap-2' style={{ minHeight: mainHeight }}>
<TopicsList activeTopic={activeTopic} onChangeTopic={topic => onSelectTopic(topic)} />
<ViewTopic topic={activeTopic} />
</div>

View File

@ -28,12 +28,10 @@ function HelpRSLang() {
<p>2. <a className='underline' href={external_urls.ponomarev}>Текст: Учебник И. Н. Пономарева</a></p>
<p>3. <a className='underline' href={external_urls.full_course}>Видео: лекции для 4 курса (второй семестр 2022-23 год)</a></p>
</div>
<div className='justify-center w-full'>
<EmbedYoutube
videoID={youtube.intro}
pxHeight={videoHeight}
/>
</div>
<EmbedYoutube
videoID={youtube.intro}
pxHeight={videoHeight}
/>
<div className='dense'>
<Subtopics headTopic={HelpTopic.RSLANG} />
</div>

View File

@ -26,7 +26,7 @@ function HelpOssGraph() {
<div className='flex flex-col'>
<h1 className='sm:pr-[6rem]'>Граф синтеза</h1>
<div className='flex flex-col sm:flex-row'>
<div className='w-full sm:w-[14rem]'>
<div className='sm:w-[14rem]'>
<h1>Настройка графа</h1>
<li>
<IconFitImage className='inline-icon' /> Вписать в экран
@ -50,7 +50,7 @@ function HelpOssGraph() {
<Divider vertical margins='mx-3 mt-3' className='hidden sm:block' />
<div className='w-full sm:w-[21rem]'>
<div className='sm:w-[21rem]'>
<h1>Изменение узлов</h1>
<li>Клик на операцию выделение</li>
<li>Esc сбросить выделение</li>
@ -72,7 +72,7 @@ function HelpOssGraph() {
<Divider margins='my-3' className='hidden sm:block' />
<div className='flex flex-col-reverse mb-3 sm:flex-row'>
<div className='w-full sm:w-[14rem]'>
<div className='sm:w-[14rem]'>
<h1>Общие</h1>
<li>
<IconReset className='inline-icon' /> Сбросить изменения

View File

@ -28,7 +28,7 @@ function HelpRSGraphTerm() {
<div className='flex flex-col'>
<h1>Граф термов</h1>
<div className='flex flex-col sm:flex-row'>
<div className='w-full sm:w-[14rem]'>
<div className='sm:w-[14rem]'>
<h1>Настройка графа</h1>
<li>Цвет покраска узлов</li>
<li>Граф расположение</li>
@ -46,7 +46,7 @@ function HelpRSGraphTerm() {
<Divider vertical margins='mx-3 mt-3' className='hidden sm:block' />
<div className='w-full sm:w-[21rem]'>
<div className='sm:w-[21rem]'>
<h1>Изменение узлов</h1>
<li>Клик на конституенту выделение</li>
<li>
@ -70,7 +70,7 @@ function HelpRSGraphTerm() {
<Divider margins='my-3' className='hidden sm:block' />
<div className='flex flex-col-reverse mb-3 sm:flex-row'>
<div className='w-full sm:w-[14rem]'>
<div className='sm:w-[14rem]'>
<h1>Общие</h1>
<li>
<IconOSS className='inline-icon' /> переход к связанной <LinkTopic text='ОСС' topic={HelpTopic.CC_OSS} />

View File

@ -95,7 +95,7 @@ function FormOSS({ id, isModified, setIsModified }: FormOSSProps) {
disabled={!controller.isMutable}
onChange={event => setTitle(event.target.value)}
/>
<div className='flex justify-between w-full gap-3 mb-3'>
<div className='flex justify-between gap-3 mb-3'>
<TextInput
id='schema_alias'
required

View File

@ -19,6 +19,7 @@ import DlgEditEditors from '@/dialogs/DlgEditEditors';
import DlgEditOperation from '@/dialogs/DlgEditOperation';
import { AccessPolicy, ILibraryItemEditor, LibraryItemID } from '@/models/library';
import { Position2D } from '@/models/miscellaneous';
import { calculateInsertPosition } from '@/models/miscellaneousAPI';
import {
IOperationCreateData,
IOperationDeleteData,
@ -85,13 +86,11 @@ export const useOssEdit = () => {
};
interface OssEditStateProps {
// isModified: boolean;
selected: OperationID[];
setSelected: React.Dispatch<React.SetStateAction<OperationID[]>>;
children: React.ReactNode;
}
export const OssEditState = ({ selected, setSelected, children }: OssEditStateProps) => {
export const OssEditState = ({ selected, setSelected, children }: React.PropsWithChildren<OssEditStateProps>) => {
const router = useConceptNavigation();
const { user } = useAuth();
const { adminMode } = useConceptOptions();
@ -234,42 +233,13 @@ export const OssEditState = ({ selected, setSelected, children }: OssEditStatePr
const handleCreateOperation = useCallback(
(data: IOperationCreateData) => {
const target = insertPosition;
if (data.item_data.operation_type === OperationType.INPUT) {
let inputsNodes = positions.filter(pos =>
model.schema!.items.find(
operation => operation.operation_type === OperationType.INPUT && operation.id === pos.id
)
);
if (inputsNodes.length > 0) {
inputsNodes = positions;
}
const maxX = Math.max(...inputsNodes.map(node => node.position_x));
const minY = Math.min(...inputsNodes.map(node => node.position_y));
target.x = maxX + PARAMETER.ossDistanceX;
target.y = minY;
} else {
const argNodes = positions.filter(pos => data.arguments!.includes(pos.id));
const maxY = Math.max(...argNodes.map(node => node.position_y));
const minX = Math.min(...argNodes.map(node => node.position_x));
const maxX = Math.max(...argNodes.map(node => node.position_x));
target.x = Math.ceil((maxX + minX) / 2 / PARAMETER.ossGridSize) * PARAMETER.ossGridSize;
target.y = maxY + PARAMETER.ossDistanceY;
}
let flagIntersect = false;
do {
flagIntersect = positions.some(
position =>
Math.abs(position.position_x - target.x) < PARAMETER.ossMinDistance &&
Math.abs(position.position_y - target.y) < PARAMETER.ossMinDistance
);
if (flagIntersect) {
target.x += PARAMETER.ossMinDistance;
target.y += PARAMETER.ossMinDistance;
}
} while (flagIntersect);
const target = calculateInsertPosition(
model.schema!,
data.item_data.operation_type,
data.arguments!,
positions,
insertPosition
);
data.positions = positions;
data.item_data.position_x = target.x;
data.item_data.position_y = target.y;

View File

@ -139,11 +139,7 @@ function FormConstituenta({
onRename={onRename}
/>
) : null}
<form
id={id}
className={clsx('cc-column', 'mt-1 w-full md:w-[48.8rem] shrink-0', 'px-6 py-1')}
onSubmit={handleSubmit}
>
<form id={id} className={clsx('cc-column', 'mt-1 md:w-[48.8rem] shrink-0', 'px-6 py-1')} onSubmit={handleSubmit}>
<RefsInput
key='cst_term'
id='cst_term'

View File

@ -166,9 +166,9 @@ function EditorRSExpression({
/>
<Overlay
position='top-[-0.5rem]'
position='top-[-0.5rem] right-1/2 translate-x-1/2'
layer='z-pop'
className='pl-[8.5rem] xs:pl-[2rem] flex justify-center w-full gap-1'
className='w-fit pl-[8.5rem] xs:pl-[2rem] flex gap-1'
>
<StatusBar
processing={parser.processing}

View File

@ -15,7 +15,7 @@ function ToolbarRSExpression({ disabled, showControls, toggleControls, showAST }
const model = useRSForm();
return (
<Overlay position='top-[-0.5rem] right-0' layer='z-sticky' className='cc-icons'>
<Overlay position='top-[-0.5rem] right-0' layer='z-pop' className='cc-icons'>
{!disabled || model.processing ? (
<MiniButton
title='Отображение специальной клавиатуры'

View File

@ -94,10 +94,10 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
</div>
{ownerSelector.isOpen ? (
<Overlay position='top-[-0.5rem] left-[2.5rem] cc-icons'>
<Overlay position='top-[-0.5rem] left-[4rem] cc-icons'>
{ownerSelector.isOpen ? (
<SelectUser
className='w-[26.5rem] sm:w-[27.5rem] text-sm'
className='w-[25rem] sm:w-[26rem] text-sm'
items={users}
value={item.owner ?? undefined}
onSelectValue={onSelectUser}

View File

@ -95,7 +95,7 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
disabled={!controller.isContentEditable}
onChange={event => setTitle(event.target.value)}
/>
<div className='flex justify-between w-full gap-3 mb-3'>
<div className='flex justify-between gap-3 mb-3'>
<TextInput
id='schema_alias'
required

View File

@ -126,7 +126,6 @@ interface RSEditStateProps {
onCreateCst?: (newCst: IConstituentaMeta) => void;
onDeleteCst?: (newActive?: ConstituentaID) => void;
children: React.ReactNode;
}
export const RSEditState = ({
@ -137,7 +136,7 @@ export const RSEditState = ({
onCreateCst,
onDeleteCst,
children
}: RSEditStateProps) => {
}: React.PropsWithChildren<RSEditStateProps>) => {
const router = useConceptNavigation();
const { user } = useAuth();
const { adminMode } = useConceptOptions();

View File

@ -12,6 +12,7 @@ import { ISyntaxTreeNode, TokenID } from '@/models/rslang';
*/
export interface IColorTheme {
bgDefault: string;
bgBlur: string;
bgInput: string;
bgControls: string;
bgDisabled: string;
@ -52,6 +53,7 @@ export interface IColorTheme {
// prettier-ignore
export const lightT: IColorTheme = {
bgDefault: 'hsl(000, 000%, 098%)', //var(--cl-bg-100)',
bgBlur: 'hsla(000, 000%, 098%, 0.8)',
bgInput: 'var(--cl-bg-120)',
bgControls: 'var(--cl-bg-80)',
bgDisabled: 'var(--cl-bg-60)',
@ -92,6 +94,7 @@ export const lightT: IColorTheme = {
// prettier-ignore
export const darkT: IColorTheme = {
bgDefault: 'hsl(000, 000%, 005%)', //'var(--cd-bg-100)',
bgBlur: 'hsla(000, 000%, 005%, 0.3)',
bgInput: 'var(--cd-bg-120)',
bgControls: 'var(--cd-bg-80)',
bgDisabled: 'var(--cd-bg-60)',

View File

@ -35,6 +35,7 @@
.cm-editor .cm-placeholder {
color: var(--cl-fg-60);
@apply font-main;
.dark & {
color: var(--cd-fg-60);
}
@ -72,7 +73,8 @@
}
}
:is(.react-flow__node-input, .react-flow__node-synthesis) {
.react-flow__node-input,
.react-flow__node-synthesis {
cursor: pointer;
border: 1px solid;

View File

@ -229,7 +229,7 @@ export function domTooltipConstituenta(cst?: IConstituenta, canClick?: boolean):
if (canClick) {
const clickTip = document.createElement('p');
clickTip.className = 'w-full text-center text-xs mt-2';
clickTip.className = 'text-center text-xs mt-1';
clickTip.innerText = 'Ctrl + клик для перехода';
dom.appendChild(clickTip);
}
@ -288,7 +288,7 @@ export function domTooltipEntityReference(
if (canClick) {
const clickTip = document.createElement('p');
clickTip.className = 'w-full text-center text-xs mt-2';
clickTip.className = 'text-center text-xs mt-1';
clickTip.innerHTML = 'Ctrl + клик для перехода</br>Ctrl + пробел для редактирования';
dom.appendChild(clickTip);
}
@ -333,7 +333,7 @@ export function domTooltipSyntacticReference(
if (canClick) {
const clickTip = document.createElement('p');
clickTip.className = 'w-full text-center text-xs mt-2';
clickTip.className = 'text-center text-xs mt-1';
clickTip.innerHTML = 'Ctrl + пробел для редактирования';
dom.appendChild(clickTip);
}

View File

@ -753,7 +753,7 @@ export function describeRSError(error: IRSErrorDescription): string {
case RSErrorType.invalidProjectionTuple:
return `Проекция не определена: ${error.params[0]} -> ${error.params[1]}`;
case RSErrorType.invalidProjectionSet:
return `τ(Pri(a)) = BCiDτ(a). Некорректная типизация аргумента: ${error.params[0]}`;
return `τ(Pri(a)) = BCiDτ(a). Некорректная типизация аргумента: ${error.params[0]} -> ${error.params[1]}`;
case RSErrorType.invalidEnumeration:
return `Типизация аргументов перечисления не совпадает: ${error.params[0]} != ${error.params[1]}`;
case RSErrorType.invalidBinding:
@ -768,8 +768,6 @@ export function describeRSError(error: IRSErrorDescription): string {
return `Типизация аргумента терм-функции не соответствует объявленной: ${error.params[0]} != ${error.params[1]}`;
case RSErrorType.globalStructure:
return `Выражение родовой структуры должно быть ступенью`;
case RSErrorType.globalExpectedFunction:
return `Ожидалось выражение объявления функции`;
case RSErrorType.radicalUsage:
return `Радикалы запрещены вне деклараций терм-функции: ${error.params[0]}`;
case RSErrorType.invalidFilterArgumentType: