Compare commits

...

7 Commits

Author SHA1 Message Date
Ivan
2b29f0b7bf F: Add TypeGraph for RSForm
Some checks failed
Backend CI / build (3.12) (push) Has been cancelled
Frontend CI / build (22.x) (push) Has been cancelled
2024-11-20 10:38:26 +03:00
Ivan
a1782904a9 M: Add warning when deleting constituents with children 2024-11-19 22:58:28 +03:00
Ivan
d0793d0e1c F: Add TypeGraph manual page 2024-11-19 22:30:33 +03:00
Ivan
581e7caf9c M: Disable move buttons when all selected 2024-11-19 21:56:02 +03:00
Ivan
1650e81751 M: Broaden substitution suggestions
Allow constituents with no links to other constituents
2024-11-15 20:44:56 +03:00
Ivan
92822ccd8e B: Fix incorrect operation deletion consequences 2024-11-15 20:36:30 +03:00
Ivan
5dc62bef4c Update dependencies 2024-11-14 22:20:00 +03:00
34 changed files with 412 additions and 251 deletions

View File

@ -169,6 +169,7 @@
"Биективная", "Биективная",
"биективной", "биективной",
"Булеан", "Булеан",
"булеана",
"Бурбаки", "Бурбаки",
"Бурбакизатор", "Бурбакизатор",
"Версионирование", "Версионирование",
@ -186,12 +187,14 @@
"конституент", "конституент",
"Конституента", "Конституента",
"конституентами", "конституентами",
"конституентах",
"конституенте", "конституенте",
"конституенту", "конституенту",
"конституенты", "конституенты",
"Крайнев", "Крайнев",
"Кучкаров", "Кучкаров",
"Кучкарова", "Кучкарова",
"мультиграфа",
"неинтерпретируемый", "неинтерпретируемый",
"неитерируемого", "неитерируемого",
"Никанорова", "Никанорова",

View File

@ -97,11 +97,29 @@ class OperationSchema:
def delete_operation(self, target: int, keep_constituents: bool = False): def delete_operation(self, target: int, keep_constituents: bool = False):
''' Delete operation. ''' ''' Delete operation. '''
self.cache.ensure_loaded()
operation = self.cache.operation_by_id[target] operation = self.cache.operation_by_id[target]
if not keep_constituents: schema = self.cache.get_schema(operation)
schema = self.cache.get_schema(operation) children = self.cache.graph.outputs[target]
if schema is not None: if schema is not None and len(children) > 0:
if not keep_constituents:
self.before_delete_cst(schema, schema.cache.constituents) self.before_delete_cst(schema, schema.cache.constituents)
else:
items = schema.cache.constituents
ids = [cst.pk for cst in items]
inheritance_to_delete: list[Inheritance] = []
for child_id in children:
child_operation = self.cache.operation_by_id[child_id]
child_schema = self.cache.get_schema(child_operation)
if child_schema is None:
continue
self._undo_substitutions_cst(items, child_operation, child_schema)
for item in self.cache.inheritance[child_id]:
if item.parent_id in ids:
inheritance_to_delete.append(item)
for item in inheritance_to_delete:
self.cache.remove_inheritance(item)
Inheritance.objects.filter(pk__in=[item.pk for item in inheritance_to_delete]).delete()
self.cache.remove_operation(target) self.cache.remove_operation(target)
operation.delete() operation.delete()
self.save(update_fields=['time_update']) self.save(update_fields=['time_update'])

View File

@ -250,6 +250,30 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 D1') self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3') self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
def test_delete_operation_keep_schema(self):
data = {
'positions': [],
'target': self.operation1.pk,
'keep_constituents': True,
'delete_schema': False
}
self.executeOK(data=data, item=self.owned_id)
self.ks1.refresh_from_db()
self.ks4D2.refresh_from_db()
self.ks5D4.refresh_from_db()
subs1_2 = self.operation4.getQ_substitutions()
self.assertEqual(subs1_2.count(), 0)
subs3_4 = self.operation5.getQ_substitutions()
self.assertEqual(subs3_4.count(), 1)
self.assertEqual(self.ks1.constituents().count(), 3)
self.assertEqual(self.ks4.constituents().count(), 6)
self.assertEqual(self.ks5.constituents().count(), 8)
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
self.assertFalse(Constituenta.objects.filter(as_child__parent_id=self.ks1D1.pk).exists())
@decl_endpoint('/api/oss/{item}/update-operation', method='patch') @decl_endpoint('/api/oss/{item}/update-operation', method='patch')
def test_change_substitutions(self): def test_change_substitutions(self):
data = { data = {

View File

@ -1,12 +1,12 @@
tzdata==2024.2 tzdata==2024.2
Django==5.1.2 Django==5.1.3
djangorestframework==3.15.2 djangorestframework==3.15.2
django-cors-headers==4.5.0 django-cors-headers==4.6.0
django-filter==24.3 django-filter==24.3
drf-spectacular==0.27.2 drf-spectacular==0.27.2
drf-spectacular-sidecar==2024.7.1 drf-spectacular-sidecar==2024.11.1
coreapi==2.3.3 coreapi==2.3.3
django-rest-passwordreset==1.4.2 django-rest-passwordreset==1.5.0
cctext==0.1.4 cctext==0.1.4
pyconcept==0.1.11 pyconcept==0.1.11
@ -16,4 +16,4 @@ djangorestframework-stubs==3.15.1
django-extensions==3.2.3 django-extensions==3.2.3
mypy==1.11.2 mypy==1.11.2
pylint==3.3.1 pylint==3.3.1
coverage==7.6.4 coverage==7.6.5

View File

@ -1,12 +1,12 @@
tzdata==2024.2 tzdata==2024.2
Django==5.1.2 Django==5.1.3
djangorestframework==3.15.2 djangorestframework==3.15.2
django-cors-headers==4.5.0 django-cors-headers==4.6.0
django-filter==24.3 django-filter==24.3
drf-spectacular==0.27.2 drf-spectacular==0.27.2
drf-spectacular-sidecar==2024.7.1 drf-spectacular-sidecar==2024.11.1
coreapi==2.3.3 coreapi==2.3.3
django-rest-passwordreset==1.4.2 django-rest-passwordreset==1.5.0
cctext==0.1.4 cctext==0.1.4
pyconcept==0.1.11 pyconcept==0.1.11

View File

@ -15,7 +15,7 @@
"axios": "^1.7.7", "axios": "^1.7.7",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-hooks": "^5.0.0",
"framer-motion": "^11.11.11", "framer-motion": "^11.11.17",
"html-to-image": "^1.11.11", "html-to-image": "^1.11.11",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"react": "^18.3.1", "react": "^18.3.1",
@ -25,13 +25,13 @@
"react-intl": "^6.8.7", "react-intl": "^6.8.7",
"react-loader-spinner": "^6.1.6", "react-loader-spinner": "^6.1.6",
"react-router-dom": "^6.28.0", "react-router-dom": "^6.28.0",
"react-select": "^5.8.2", "react-select": "^5.8.3",
"react-tabs": "^6.0.2", "react-tabs": "^6.0.2",
"react-toastify": "^10.0.6", "react-toastify": "^10.0.6",
"react-tooltip": "^5.28.0", "react-tooltip": "^5.28.0",
"react-zoom-pan-pinch": "^3.6.1", "react-zoom-pan-pinch": "^3.6.1",
"reactflow": "^11.11.4", "reactflow": "^11.11.4",
"reagraph": "^4.19.5", "reagraph": "^4.20.1",
"use-debounce": "^10.0.4" "use-debounce": "^10.0.4"
}, },
"devDependencies": { "devDependencies": {
@ -49,12 +49,12 @@
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^15.12.0", "globals": "^15.12.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"postcss": "^8.4.47", "postcss": "^8.4.49",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.15",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"typescript-eslint": "^8.13.0", "typescript-eslint": "^8.14.0",
"vite": "^5.4.10" "vite": "^5.4.11"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@ -635,9 +635,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@codemirror/autocomplete": { "node_modules/@codemirror/autocomplete": {
"version": "6.18.2", "version": "6.18.3",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.2.tgz", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.3.tgz",
"integrity": "sha512-wJGylKtMFR/Ds6Gh01+OovXE/pncPiKZNNBKuC39pKnH+XK5d9+WsNqcrdxPjFPFTigRBqse0rfxw9UxrfyhPg==", "integrity": "sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@codemirror/language": "^6.0.0", "@codemirror/language": "^6.0.0",
@ -1412,9 +1412,9 @@
} }
}, },
"node_modules/@eslint/plugin-kit": { "node_modules/@eslint/plugin-kit": {
"version": "0.2.2", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz",
"integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"levn": "^0.4.1" "levn": "^0.4.1"
@ -2511,9 +2511,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz",
"integrity": "sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==", "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2525,9 +2525,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz",
"integrity": "sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==", "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2539,9 +2539,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz",
"integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==", "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2553,9 +2553,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz",
"integrity": "sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==", "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2567,9 +2567,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz",
"integrity": "sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==", "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2581,9 +2581,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz",
"integrity": "sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==", "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2595,9 +2595,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz",
"integrity": "sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==", "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2609,9 +2609,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz",
"integrity": "sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==", "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2623,9 +2623,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz",
"integrity": "sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==", "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2637,9 +2637,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz",
"integrity": "sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==", "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2651,9 +2651,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz",
"integrity": "sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==", "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -2665,9 +2665,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz",
"integrity": "sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==", "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -2679,9 +2679,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz",
"integrity": "sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==", "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -2693,9 +2693,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz",
"integrity": "sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==", "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2707,9 +2707,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz",
"integrity": "sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==", "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2721,9 +2721,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz",
"integrity": "sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==", "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2735,9 +2735,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz",
"integrity": "sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==", "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -2749,9 +2749,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz",
"integrity": "sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==", "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -3294,9 +3294,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/three": { "node_modules/@types/three": {
"version": "0.169.0", "version": "0.170.0",
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.169.0.tgz", "resolved": "https://registry.npmjs.org/@types/three/-/three-0.170.0.tgz",
"integrity": "sha512-oan7qCgJBt03wIaK+4xPWclYRPG9wzcg7Z2f5T8xYTNEF95kh0t0lklxLLYBDo7gQiGLYzE6iF4ta7nXF2bcsw==", "integrity": "sha512-CUm2uckq+zkCY7ZbFpviRttY+6f9fvwm6YqSqPfA5K22s9w7R4VnA3rzJse8kHVvuzLcTx+CjNCs2NYe0QFAyg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tweenjs/tween.js": "~23.1.3", "@tweenjs/tween.js": "~23.1.3",
@ -3331,17 +3331,17 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz",
"integrity": "sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==", "integrity": "sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.13.0", "@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/type-utils": "8.13.0", "@typescript-eslint/type-utils": "8.14.0",
"@typescript-eslint/utils": "8.13.0", "@typescript-eslint/utils": "8.14.0",
"@typescript-eslint/visitor-keys": "8.13.0", "@typescript-eslint/visitor-keys": "8.14.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -3365,16 +3365,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz",
"integrity": "sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==", "integrity": "sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.13.0", "@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/types": "8.13.0", "@typescript-eslint/types": "8.14.0",
"@typescript-eslint/typescript-estree": "8.13.0", "@typescript-eslint/typescript-estree": "8.14.0",
"@typescript-eslint/visitor-keys": "8.13.0", "@typescript-eslint/visitor-keys": "8.14.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -3394,14 +3394,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz",
"integrity": "sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==", "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.13.0", "@typescript-eslint/types": "8.14.0",
"@typescript-eslint/visitor-keys": "8.13.0" "@typescript-eslint/visitor-keys": "8.14.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3412,14 +3412,14 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz",
"integrity": "sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==", "integrity": "sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.13.0", "@typescript-eslint/typescript-estree": "8.14.0",
"@typescript-eslint/utils": "8.13.0", "@typescript-eslint/utils": "8.14.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^1.3.0" "ts-api-utils": "^1.3.0"
}, },
@ -3437,9 +3437,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz",
"integrity": "sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==", "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -3451,14 +3451,14 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz",
"integrity": "sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==", "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.13.0", "@typescript-eslint/types": "8.14.0",
"@typescript-eslint/visitor-keys": "8.13.0", "@typescript-eslint/visitor-keys": "8.14.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -3480,16 +3480,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz",
"integrity": "sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==", "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.13.0", "@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/types": "8.13.0", "@typescript-eslint/types": "8.14.0",
"@typescript-eslint/typescript-estree": "8.13.0" "@typescript-eslint/typescript-estree": "8.14.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3503,13 +3503,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz",
"integrity": "sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==", "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.13.0", "@typescript-eslint/types": "8.14.0",
"eslint-visitor-keys": "^3.4.3" "eslint-visitor-keys": "^3.4.3"
}, },
"engines": { "engines": {
@ -4309,9 +4309,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001678", "version": "1.0.30001680",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001678.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz",
"integrity": "sha512-RR+4U/05gNtps58PEBDZcPWTgEO2MBeoPZ96aQcjmfkBWRIDfN451fW2qyDA9/+HohLLIL5GqiMwA+IB1pWarw==", "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -5028,9 +5028,9 @@
} }
}, },
"node_modules/detect-gpu": { "node_modules/detect-gpu": {
"version": "5.0.55", "version": "5.0.56",
"resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.55.tgz", "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.56.tgz",
"integrity": "sha512-muXhz2twvGiyatqK3VTy//Jb/MmHXExEaOPEMyLpVb9BSzTUgimFwbHKPBIfjEyQV0P+Y1mEjVSyPrlqPzUPQQ==", "integrity": "sha512-HYcx/cCiOQ9o4kImrvUMKwb4fyvgCYUeHnYUqbWOldI9NACLOClAyvnhG63YpbjCo6oHEjWI3MmPrhGQl96FVA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"webgl-constants": "^1.1.1" "webgl-constants": "^1.1.1"
@ -5123,9 +5123,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.53", "version": "1.5.58",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.53.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.58.tgz",
"integrity": "sha512-7F6qFMWzBArEFK4PLE+c+nWzhS1kIoNkQvGnNDogofxQAym+roQ0GUIdw6C/4YdJ6JKGp19c2a/DLcfKTi4wRQ==", "integrity": "sha512-al2l4r+24ZFL7WzyPTlyD0fC33LLzvxqLCwurtBibVPghRGO9hSTl+tis8t1kD7biPiH/en4U0I7o/nQbYeoVA==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@ -5165,9 +5165,9 @@
} }
}, },
"node_modules/es-abstract": { "node_modules/es-abstract": {
"version": "1.23.3", "version": "1.23.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz",
"integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5186,7 +5186,7 @@
"function.prototype.name": "^1.1.6", "function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.4", "get-intrinsic": "^1.2.4",
"get-symbol-description": "^1.0.2", "get-symbol-description": "^1.0.2",
"globalthis": "^1.0.3", "globalthis": "^1.0.4",
"gopd": "^1.0.1", "gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2", "has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3", "has-proto": "^1.0.3",
@ -5202,10 +5202,10 @@
"is-string": "^1.0.7", "is-string": "^1.0.7",
"is-typed-array": "^1.1.13", "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2", "is-weakref": "^1.0.2",
"object-inspect": "^1.13.1", "object-inspect": "^1.13.3",
"object-keys": "^1.1.1", "object-keys": "^1.1.1",
"object.assign": "^4.1.5", "object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.2", "regexp.prototype.flags": "^1.5.3",
"safe-array-concat": "^1.1.2", "safe-array-concat": "^1.1.2",
"safe-regex-test": "^1.0.3", "safe-regex-test": "^1.0.3",
"string.prototype.trim": "^1.2.9", "string.prototype.trim": "^1.2.9",
@ -5999,9 +5999,9 @@
} }
}, },
"node_modules/framer-motion": { "node_modules/framer-motion": {
"version": "11.11.11", "version": "11.11.17",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.17.tgz",
"integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", "integrity": "sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tslib": "^2.4.0" "tslib": "^2.4.0"
@ -8364,9 +8364,9 @@
} }
}, },
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.13.2", "version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -8778,9 +8778,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.47", "version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -8799,7 +8799,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"nanoid": "^3.3.7", "nanoid": "^3.3.7",
"picocolors": "^1.1.0", "picocolors": "^1.1.1",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
}, },
"engines": { "engines": {
@ -9283,9 +9283,9 @@
} }
}, },
"node_modules/react-select": { "node_modules/react-select": {
"version": "5.8.2", "version": "5.8.3",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.2.tgz", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.3.tgz",
"integrity": "sha512-a/LkOckoI62710gGPQSQqUp7A10fGbH/ya3/IR49qaq3XoBvwymgD5mJgtiHxBDsutyEQfdKNycWVh8Cg8UCjw==", "integrity": "sha512-lVswnIq8/iTj1db7XCG74M/3fbGB6ZaluCzvwPGT5ZOjCdL/k0CLWhEK0vCBLuU5bHTEf6Gj8jtSvi+3v+tO1w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.0", "@babel/runtime": "^7.12.0",
@ -9428,9 +9428,9 @@
} }
}, },
"node_modules/reagraph": { "node_modules/reagraph": {
"version": "4.19.5", "version": "4.20.1",
"resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.19.5.tgz", "resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.20.1.tgz",
"integrity": "sha512-4EzHbF1XHpXV7IHdWUNzA3m1cKTmVJNnjJ7e0IhgdATekSmcB+xhUwCHFb9eVEPa/x+buq2gtP4w4Bj2A5cyjQ==", "integrity": "sha512-1STKs/5pZrIDA3yC7SVbl+vzHvNqxWPVUa/6E2GABn93oVpoFMezk9SyZ3W7KnJzKhfSxFDf+C5frjvU+/wCoA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@react-spring/three": "9.6.1", "@react-spring/three": "9.6.1",
@ -9645,9 +9645,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.24.4", "version": "4.26.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz",
"integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==", "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -9661,24 +9661,24 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.24.4", "@rollup/rollup-android-arm-eabi": "4.26.0",
"@rollup/rollup-android-arm64": "4.24.4", "@rollup/rollup-android-arm64": "4.26.0",
"@rollup/rollup-darwin-arm64": "4.24.4", "@rollup/rollup-darwin-arm64": "4.26.0",
"@rollup/rollup-darwin-x64": "4.24.4", "@rollup/rollup-darwin-x64": "4.26.0",
"@rollup/rollup-freebsd-arm64": "4.24.4", "@rollup/rollup-freebsd-arm64": "4.26.0",
"@rollup/rollup-freebsd-x64": "4.24.4", "@rollup/rollup-freebsd-x64": "4.26.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.24.4", "@rollup/rollup-linux-arm-gnueabihf": "4.26.0",
"@rollup/rollup-linux-arm-musleabihf": "4.24.4", "@rollup/rollup-linux-arm-musleabihf": "4.26.0",
"@rollup/rollup-linux-arm64-gnu": "4.24.4", "@rollup/rollup-linux-arm64-gnu": "4.26.0",
"@rollup/rollup-linux-arm64-musl": "4.24.4", "@rollup/rollup-linux-arm64-musl": "4.26.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.4", "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0",
"@rollup/rollup-linux-riscv64-gnu": "4.24.4", "@rollup/rollup-linux-riscv64-gnu": "4.26.0",
"@rollup/rollup-linux-s390x-gnu": "4.24.4", "@rollup/rollup-linux-s390x-gnu": "4.26.0",
"@rollup/rollup-linux-x64-gnu": "4.24.4", "@rollup/rollup-linux-x64-gnu": "4.26.0",
"@rollup/rollup-linux-x64-musl": "4.24.4", "@rollup/rollup-linux-x64-musl": "4.26.0",
"@rollup/rollup-win32-arm64-msvc": "4.24.4", "@rollup/rollup-win32-arm64-msvc": "4.26.0",
"@rollup/rollup-win32-ia32-msvc": "4.24.4", "@rollup/rollup-win32-ia32-msvc": "4.26.0",
"@rollup/rollup-win32-x64-msvc": "4.24.4", "@rollup/rollup-win32-x64-msvc": "4.26.0",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@ -10313,34 +10313,34 @@
} }
}, },
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "3.4.14", "version": "3.4.15",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz",
"integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alloc/quick-lru": "^5.2.0", "@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2", "arg": "^5.0.2",
"chokidar": "^3.5.3", "chokidar": "^3.6.0",
"didyoumean": "^1.2.2", "didyoumean": "^1.2.2",
"dlv": "^1.1.3", "dlv": "^1.1.3",
"fast-glob": "^3.3.0", "fast-glob": "^3.3.2",
"glob-parent": "^6.0.2", "glob-parent": "^6.0.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
"jiti": "^1.21.0", "jiti": "^1.21.6",
"lilconfig": "^2.1.0", "lilconfig": "^2.1.0",
"micromatch": "^4.0.5", "micromatch": "^4.0.8",
"normalize-path": "^3.0.0", "normalize-path": "^3.0.0",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
"picocolors": "^1.0.0", "picocolors": "^1.1.1",
"postcss": "^8.4.23", "postcss": "^8.4.47",
"postcss-import": "^15.1.0", "postcss-import": "^15.1.0",
"postcss-js": "^4.0.1", "postcss-js": "^4.0.1",
"postcss-load-config": "^4.0.1", "postcss-load-config": "^4.0.2",
"postcss-nested": "^6.0.1", "postcss-nested": "^6.2.0",
"postcss-selector-parser": "^6.0.11", "postcss-selector-parser": "^6.1.2",
"resolve": "^1.22.2", "resolve": "^1.22.8",
"sucrase": "^3.32.0" "sucrase": "^3.35.0"
}, },
"bin": { "bin": {
"tailwind": "lib/cli.js", "tailwind": "lib/cli.js",
@ -10735,15 +10735,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.13.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.13.0.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.14.0.tgz",
"integrity": "sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==", "integrity": "sha512-K8fBJHxVL3kxMmwByvz8hNdBJ8a0YqKzKDX6jRlrjMuNXyd5T2V02HIq37+OiWXvUUOXgOOGiSSOh26Mh8pC3w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.13.0", "@typescript-eslint/eslint-plugin": "8.14.0",
"@typescript-eslint/parser": "8.13.0", "@typescript-eslint/parser": "8.14.0",
"@typescript-eslint/utils": "8.13.0" "@typescript-eslint/utils": "8.14.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -10901,9 +10901,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.4.10", "version": "5.4.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
"integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@ -19,7 +19,7 @@
"axios": "^1.7.7", "axios": "^1.7.7",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-hooks": "^5.0.0",
"framer-motion": "^11.11.11", "framer-motion": "^11.11.17",
"html-to-image": "^1.11.11", "html-to-image": "^1.11.11",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"react": "^18.3.1", "react": "^18.3.1",
@ -29,13 +29,13 @@
"react-intl": "^6.8.7", "react-intl": "^6.8.7",
"react-loader-spinner": "^6.1.6", "react-loader-spinner": "^6.1.6",
"react-router-dom": "^6.28.0", "react-router-dom": "^6.28.0",
"react-select": "^5.8.2", "react-select": "^5.8.3",
"react-tabs": "^6.0.2", "react-tabs": "^6.0.2",
"react-toastify": "^10.0.6", "react-toastify": "^10.0.6",
"react-tooltip": "^5.28.0", "react-tooltip": "^5.28.0",
"react-zoom-pan-pinch": "^3.6.1", "react-zoom-pan-pinch": "^3.6.1",
"reactflow": "^11.11.4", "reactflow": "^11.11.4",
"reagraph": "^4.19.5", "reagraph": "^4.20.1",
"use-debounce": "^10.0.4" "use-debounce": "^10.0.4"
}, },
"devDependencies": { "devDependencies": {
@ -53,12 +53,12 @@
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^15.12.0", "globals": "^15.12.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"postcss": "^8.4.47", "postcss": "^8.4.49",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.15",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"typescript-eslint": "^8.13.0", "typescript-eslint": "^8.14.0",
"vite": "^5.4.10" "vite": "^5.4.11"
}, },
"jest": { "jest": {
"preset": "ts-jest", "preset": "ts-jest",

View File

@ -100,6 +100,7 @@ export { LuSubscript as IconAlias } from 'react-icons/lu';
export { TbMathFunction as IconFormula } from 'react-icons/tb'; export { TbMathFunction as IconFormula } from 'react-icons/tb';
export { BiFontFamily as IconText } from 'react-icons/bi'; export { BiFontFamily as IconText } from 'react-icons/bi';
export { BiFont as IconTextOff } from 'react-icons/bi'; export { BiFont as IconTextOff } from 'react-icons/bi';
export { TbCar4Wd as IconTypeGraph } from 'react-icons/tb';
export { RiTreeLine as IconTree } from 'react-icons/ri'; export { RiTreeLine as IconTree } from 'react-icons/ri';
export { FaRegKeyboard as IconControls } from 'react-icons/fa6'; export { FaRegKeyboard as IconControls } from 'react-icons/fa6';
export { RiLockLine as IconImmutable } from 'react-icons/ri'; export { RiLockLine as IconImmutable } from 'react-icons/ri';

View File

@ -22,6 +22,10 @@ function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstPr
() => schema.graph.expandAllOutputs(selected), // prettier: split-lines () => schema.graph.expandAllOutputs(selected), // prettier: split-lines
[selected, schema.graph] [selected, schema.graph]
); );
const hasInherited = useMemo(
() => selected.some(id => schema.inheritance.find(item => item.parent === id), [selected, schema.inheritance]),
[selected, schema.inheritance]
);
function handleSubmit() { function handleSubmit() {
hideWindow(); hideWindow();
@ -50,10 +54,13 @@ function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstPr
/> />
<Checkbox <Checkbox
label='Удалить зависимые конституенты' label='Удалить зависимые конституенты'
className='my-2' className='mb-2'
value={expandOut} value={expandOut}
setValue={value => setExpandOut(value)} setValue={value => setExpandOut(value)}
/> />
{hasInherited ? (
<p className='text-sm clr-text-red'>Внимание! Выбранные конституенты имеют наследников в ОСС</p>
) : null}
</Modal> </Modal>
); );
} }

View File

@ -5,24 +5,23 @@ import { toast } from 'react-toastify';
import { ReactFlowProvider } from 'reactflow'; import { ReactFlowProvider } from 'reactflow';
import Modal, { ModalProps } from '@/components/ui/Modal'; import Modal, { ModalProps } from '@/components/ui/Modal';
import { IArgumentInfo } from '@/models/rslang'; import { HelpTopic } from '@/models/miscellaneous';
import { ITypeInfo } from '@/models/rslang';
import { TMGraph } from '@/models/TMGraph'; import { TMGraph } from '@/models/TMGraph';
import { errors } from '@/utils/labels'; import { errors } from '@/utils/labels';
import MGraphFlow from './MGraphFlow'; import MGraphFlow from './MGraphFlow';
interface DlgShowTypificationProps extends Pick<ModalProps, 'hideWindow'> { interface DlgShowTypeGraphProps extends Pick<ModalProps, 'hideWindow'> {
alias: string; items: ITypeInfo[];
resultTypification: string;
args: IArgumentInfo[];
} }
function DlgShowTypification({ hideWindow, alias, resultTypification, args }: DlgShowTypificationProps) { function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
const graph = useMemo(() => { const graph = useMemo(() => {
const result = new TMGraph(); const result = new TMGraph();
result.addConstituenta(alias, resultTypification, args); items.forEach(item => result.addConstituenta(item.alias, item.result, item.args));
return result; return result;
}, [alias, resultTypification, args]); }, [items]);
if (graph.nodes.length === 0) { if (graph.nodes.length === 0) {
toast.error(errors.typeStructureFailed); toast.error(errors.typeStructureFailed);
@ -32,10 +31,11 @@ function DlgShowTypification({ hideWindow, alias, resultTypification, args }: Dl
return ( return (
<Modal <Modal
header='Структура типизации' header='Граф ступеней'
readonly readonly
hideWindow={hideWindow} hideWindow={hideWindow}
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]' className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
helpTopic={HelpTopic.UI_TYPE_GRAPH}
> >
<ReactFlowProvider> <ReactFlowProvider>
<MGraphFlow data={graph} /> <MGraphFlow data={graph} />
@ -44,4 +44,4 @@ function DlgShowTypification({ hideWindow, alias, resultTypification, args }: Dl
); );
} }
export default DlgShowTypification; export default DlgShowTypeGraph;

View File

@ -1,3 +1,6 @@
'use client';
import { useMemo } from 'react';
import { Handle, Position } from 'reactflow'; import { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { useConceptOptions } from '@/context/ConceptOptionsContext';
@ -8,16 +11,23 @@ import { globals } from '@/utils/constants';
function MGraphNode(node: MGraphNodeInternal) { function MGraphNode(node: MGraphNodeInternal) {
const { colors } = useConceptOptions(); const { colors } = useConceptOptions();
const tooltipText = useMemo(
() =>
(node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) +
node.data.text,
[node.data]
);
return ( return (
<> <>
<Handle type='source' position={Position.Top} style={{ opacity: 0 }} /> <Handle type='source' position={Position.Top} style={{ opacity: 0 }} />
<div <div
className='w-full h-full cursor-default flex items-center justify-center rounded-full' className='w-full h-full cursor-default flex items-center justify-center rounded-full'
data-tooltip-id={globals.tooltip} data-tooltip-id={globals.tooltip}
data-tooltip-content={node.data.text} data-tooltip-html={tooltipText}
style={{ backgroundColor: colorBgTMGraphNode(node.data, colors) }} style={{ backgroundColor: colorBgTMGraphNode(node.data, colors) }}
> >
{node.data.rank === 0 ? node.data.text : ''} {node.data.rank === 0 ? node.data.text : node.data.annotations.length > 0 ? node.data.annotations.length : ''}
</div> </div>
<Handle type='target' position={Position.Bottom} style={{ opacity: 0 }} /> <Handle type='target' position={Position.Bottom} style={{ opacity: 0 }} />
</> </>

View File

@ -0,0 +1 @@
export { default } from './DlgShowTypeGraph';

View File

@ -1 +0,0 @@
export { default } from './DlgShowTypification';

View File

@ -90,6 +90,7 @@ export enum HelpTopic {
UI_RS_EDITOR = 'ui-rsform-editor', UI_RS_EDITOR = 'ui-rsform-editor',
UI_GRAPH_TERM = 'ui-graph-term', UI_GRAPH_TERM = 'ui-graph-term',
UI_FORMULA_TREE = 'ui-formula-tree', UI_FORMULA_TREE = 'ui-formula-tree',
UI_TYPE_GRAPH = 'ui-type-graph',
UI_CST_STATUS = 'ui-rsform-cst-status', UI_CST_STATUS = 'ui-rsform-cst-status',
UI_CST_CLASS = 'ui-rsform-cst-class', UI_CST_CLASS = 'ui-rsform-cst-class',
UI_OSS_GRAPH = 'ui-oss-graph', UI_OSS_GRAPH = 'ui-oss-graph',
@ -140,6 +141,7 @@ export const topicParent = new Map<HelpTopic, HelpTopic>([
[HelpTopic.UI_RS_EDITOR, HelpTopic.INTERFACE], [HelpTopic.UI_RS_EDITOR, HelpTopic.INTERFACE],
[HelpTopic.UI_GRAPH_TERM, HelpTopic.INTERFACE], [HelpTopic.UI_GRAPH_TERM, HelpTopic.INTERFACE],
[HelpTopic.UI_FORMULA_TREE, HelpTopic.INTERFACE], [HelpTopic.UI_FORMULA_TREE, HelpTopic.INTERFACE],
[HelpTopic.UI_TYPE_GRAPH, HelpTopic.INTERFACE],
[HelpTopic.UI_CST_STATUS, HelpTopic.INTERFACE], [HelpTopic.UI_CST_STATUS, HelpTopic.INTERFACE],
[HelpTopic.UI_CST_CLASS, HelpTopic.INTERFACE], [HelpTopic.UI_CST_CLASS, HelpTopic.INTERFACE],
[HelpTopic.UI_OSS_GRAPH, HelpTopic.INTERFACE], [HelpTopic.UI_OSS_GRAPH, HelpTopic.INTERFACE],

View File

@ -125,11 +125,11 @@ export class SubstitutionValidator {
if (this.originals.has(cst.id)) { if (this.originals.has(cst.id)) {
continue; continue;
} }
if (cst.cst_class === CstClass.BASIC) { if (cst.cst_class === CstClass.BASIC || cst.definition_formal.length === 0) {
continue; continue;
} }
const inputs = schema.graph.at(cst.id)!.inputs; const inputs = schema.graph.at(cst.id)!.inputs;
if (inputs.length === 0 || inputs.some(id => !this.constituents.has(id))) { if (inputs.some(id => !this.constituents.has(id))) {
continue; continue;
} }
if (inputs.some(id => this.originals.has(id))) { if (inputs.some(id => this.originals.has(id))) {

View File

@ -72,6 +72,13 @@ export interface IArgumentInfo {
typification: string; typification: string;
} }
/** Represents global identifier type info. */
export interface ITypeInfo {
alias: string;
result: string;
args: IArgumentInfo[];
}
/** /**
* Represents function argument value. * Represents function argument value.
*/ */

View File

@ -38,6 +38,7 @@ import HelpRSGraphTerm from './items/ui/HelpRSGraphTerm';
import HelpRSList from './items/ui/HelpRSList'; import HelpRSList from './items/ui/HelpRSList';
import HelpRSMenu from './items/ui/HelpRSMenu'; import HelpRSMenu from './items/ui/HelpRSMenu';
import HelpSubstitutions from './items/ui/HelpSubstitutions'; import HelpSubstitutions from './items/ui/HelpSubstitutions';
import HelpTypeGraph from './items/ui/HelpTypeGraph';
// PDF Viewer setup // PDF Viewer setup
const OFFSET_X_SMALL = 32; const OFFSET_X_SMALL = 32;
@ -64,6 +65,7 @@ function TopicPage({ topic }: TopicPageProps) {
if (topic === HelpTopic.UI_RS_EDITOR) return <HelpRSEditor />; if (topic === HelpTopic.UI_RS_EDITOR) return <HelpRSEditor />;
if (topic === HelpTopic.UI_GRAPH_TERM) return <HelpRSGraphTerm />; if (topic === HelpTopic.UI_GRAPH_TERM) return <HelpRSGraphTerm />;
if (topic === HelpTopic.UI_FORMULA_TREE) return <HelpFormulaTree />; if (topic === HelpTopic.UI_FORMULA_TREE) return <HelpFormulaTree />;
if (topic === HelpTopic.UI_TYPE_GRAPH) return <HelpTypeGraph />;
if (topic === HelpTopic.UI_CST_STATUS) return <HelpCstStatus />; if (topic === HelpTopic.UI_CST_STATUS) return <HelpCstStatus />;
if (topic === HelpTopic.UI_CST_CLASS) return <HelpCstClass />; if (topic === HelpTopic.UI_CST_CLASS) return <HelpCstClass />;
if (topic === HelpTopic.UI_OSS_GRAPH) return <HelpOssGraph />; if (topic === HelpTopic.UI_OSS_GRAPH) return <HelpOssGraph />;

View File

@ -20,6 +20,10 @@ function HelpConceptPropagation() {
созданию / удаление / обновлению наследованных конституент. Если удаляемые конституенты находятся в таблице созданию / удаление / обновлению наследованных конституент. Если удаляемые конституенты находятся в таблице
отождествлений одной из операций, то такие отождествления <u>будут автоматические отменены</u>. отождествлений одной из операций, то такие отождествления <u>будут автоматические отменены</u>.
</p> </p>
<p>
После отмены отождествления на заново восстановленную конституенту не обновляются ссылки в собственных
конституентах синтезированный схемы.
</p>
<p> <p>
Удаление концептуальной схемы, привязанной к операции приводит к автоматическому удалению всех наследованных Удаление концептуальной схемы, привязанной к операции приводит к автоматическому удалению всех наследованных
конституент. В дальнейшем можно повторно выполнить как операцию загрузки, так и синтез. Однако дописанные конституент. В дальнейшем можно повторно выполнить как операцию загрузки, так и синтез. Однако дописанные

View File

@ -15,7 +15,8 @@ import {
IconOSS, IconOSS,
IconReset, IconReset,
IconRotate3D, IconRotate3D,
IconText IconText,
IconTypeGraph
} from '@/components/Icons'; } from '@/components/Icons';
import Divider from '@/components/ui/Divider'; import Divider from '@/components/ui/Divider';
import LinkTopic from '@/components/ui/LinkTopic'; import LinkTopic from '@/components/ui/LinkTopic';
@ -81,6 +82,10 @@ function HelpRSGraphTerm() {
<li> <li>
<IconFitImage className='inline-icon' /> Вписать в экран <IconFitImage className='inline-icon' /> Вписать в экран
</li> </li>
<li>
<IconTypeGraph className='inline-icon' /> Открыть{' '}
<LinkTopic text='граф ступеней' topic={HelpTopic.UI_TYPE_GRAPH} />
</li>
<li> <li>
<IconImage className='inline-icon' /> Сохранить в формат PNG <IconImage className='inline-icon' /> Сохранить в формат PNG
</li> </li>

View File

@ -1,4 +1,4 @@
import { IconMoveDown, IconMoveUp, IconPredecessor } from '@/components/Icons'; import { IconMoveDown, IconMoveUp, IconOSS, IconPredecessor } from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic'; import LinkTopic from '@/components/ui/LinkTopic';
import { HelpTopic } from '@/models/miscellaneous'; import { HelpTopic } from '@/models/miscellaneous';
@ -7,24 +7,27 @@ function HelpRelocateCst() {
<div className='text-justify'> <div className='text-justify'>
<h1>Перенос конституент</h1> <h1>Перенос конституент</h1>
<p> <p>
Перенос конституент операция, при которой выбранные конституенты переносятся в другую КС в рамках одной Перенос конституент операция, при которой выбранные конституенты переносятся из текущей КС (источника) в
другую КС (целевую) в рамках одной <IconOSS size='1rem' className='inline-icon' />{' '}
<LinkTopic text='операционной схемы синтеза' topic={HelpTopic.CC_OSS} />. <LinkTopic text='операционной схемы синтеза' topic={HelpTopic.CC_OSS} />.
</p> </p>
<li> <li>
только для <IconPredecessor size='1rem' className='inline-icon' /> собственных конституент схемы-источника только для <IconPredecessor size='1rem' className='inline-icon' /> собственных конституент источника
</li> </li>
<li> <li>
<IconMoveUp size='1rem' className='inline-icon' /> <IconMoveUp size='1rem' className='inline-icon' />
<IconMoveDown size='1rem' className='inline-icon' /> направление переноса - вверх или вниз по дереву синтеза <IconMoveDown size='1rem' className='inline-icon' /> направление переноса - вверх или вниз по дереву синтеза
</li> </li>
<h2>Перенос вверх</h2>
<li>выбранные конституенты становятся наследованными, а их копии добавляются в целевую КС</li>
<li>нельзя выбирать конституенты, зависящие от конституент других концептуальных схем</li>
<h2>Перенос вниз</h2>
<li> <li>
при переносе вверх собственные конституенты становятся наследованными, а их копии добавляются в целевую КС выбранные конституенты становятся собственными конституентами целевой КС, удаляются из исходной КС и ее
наследников
</li> </li>
<li>
при переносе вниз собственные конституенты становятся собственными конституентами целевой КС и удаляются из
исходной КС
</li>
<li>при переносе вверх нельзя выбирать конституенты, зависящие от конституент КС, отличных от целевой</li>
</div> </div>
); );
} }

View File

@ -0,0 +1,36 @@
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
function HelpTypeGraph() {
const { colors } = useConceptOptions();
return (
<div>
<h1>Граф ступеней</h1>
<p>
Граф связей между ступенями, используемыми в данном выражении или{' '}
<LinkTopic text='КС' topic={HelpTopic.CC_OSS} />. Исторически отображался в форме мультиграфа (М-граф). В
Портале кратные ребра представлены перечислением индексов компонент произведения.
</p>
<li>ребра без надписей означают взятие булеана</li>
<li>цифры на ребрах означают номера компонент декартова произведения</li>
<li>цифры на узлах означают количество конституент в данной ступени</li>
<li>основаниями дерева являются ступени базисных, константных множеств</li>
<li>ступень терм-функции - произведение ступеней результата и аргументов</li>
<li>ступень предикат-функции - произведение ступеней аргументов</li>
<h2>Виды узлов</h2>
<li>
<span style={{ backgroundColor: colors.bgControls }}>ступень-основание</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgTeal }}>ступень-булеан</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgOrange }}>ступень декартова произведения</span>
</li>
</div>
);
}
export default HelpTypeGraph;

View File

@ -14,7 +14,7 @@ import SubmitButton from '@/components/ui/SubmitButton';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
import AnimateFade from '@/components/wrap/AnimateFade'; import AnimateFade from '@/components/wrap/AnimateFade';
import { useRSForm } from '@/context/RSFormContext'; import { useRSForm } from '@/context/RSFormContext';
import DlgShowTypification from '@/dialogs/DlgShowTypification'; import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform'; import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI'; import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
import { IExpressionParse, ParsingStatus } from '@/models/rslang'; import { IExpressionParse, ParsingStatus } from '@/models/rslang';
@ -60,6 +60,17 @@ function FormConstituenta({
const [typification, setTypification] = useState('N/A'); const [typification, setTypification] = useState('N/A');
const [showTypification, setShowTypification] = useState(false); const [showTypification, setShowTypification] = useState(false);
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined); const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
const typeInfo = useMemo(
() =>
state
? {
alias: state.alias,
result: localParse ? localParse.typification : state.parse.typification,
args: localParse ? localParse.args : state.parse.args
}
: undefined,
[state, localParse]
);
const [forceComment, setForceComment] = useState(false); const [forceComment, setForceComment] = useState(false);
@ -147,12 +158,7 @@ function FormConstituenta({
<AnimateFade className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'> <AnimateFade className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
<AnimatePresence> <AnimatePresence>
{showTypification && state ? ( {showTypification && state ? (
<DlgShowTypification <DlgShowTypeGraph items={typeInfo ? [typeInfo] : []} hideWindow={() => setShowTypification(false)} />
alias={state.alias}
resultTypification={localParse ? localParse.typification : state.parse.typification}
args={localParse ? localParse.args : state.parse.args}
hideWindow={() => setShowTypification(false)}
/>
) : null} ) : null}
</AnimatePresence> </AnimatePresence>
{state ? ( {state ? (

View File

@ -112,13 +112,13 @@ function ToolbarConstituenta({
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')} titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
icon={<IconMoveUp size='1.25rem' className='icon-primary' />} icon={<IconMoveUp size='1.25rem' className='icon-primary' />}
disabled={disabled || modified} disabled={disabled || modified || (controller.schema && controller.schema?.items.length < 2)}
onClick={controller.moveUp} onClick={controller.moveUp}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')} titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
icon={<IconMoveDown size='1.25rem' className='icon-primary' />} icon={<IconMoveDown size='1.25rem' className='icon-primary' />}
disabled={disabled || modified} disabled={disabled || modified || (controller.schema && controller.schema?.items.length < 2)}
onClick={controller.moveDown} onClick={controller.moveDown}
/> />
</> </>

View File

@ -46,13 +46,21 @@ function ToolbarRSList() {
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')} titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
icon={<IconMoveUp size='1.25rem' className='icon-primary' />} icon={<IconMoveUp size='1.25rem' className='icon-primary' />}
disabled={controller.isProcessing || controller.nothingSelected} disabled={
controller.isProcessing ||
controller.selected.length === 0 ||
(controller.schema && controller.selected.length === controller.schema.items.length)
}
onClick={controller.moveUp} onClick={controller.moveUp}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')} titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
icon={<IconMoveDown size='1.25rem' className='icon-primary' />} icon={<IconMoveDown size='1.25rem' className='icon-primary' />}
disabled={controller.isProcessing || controller.nothingSelected} disabled={
controller.isProcessing ||
controller.selected.length === 0 ||
(controller.schema && controller.selected.length === controller.schema.items.length)
}
onClick={controller.moveDown} onClick={controller.moveDown}
/> />
<div ref={insertMenu.ref}> <div ref={insertMenu.ref}>

View File

@ -137,7 +137,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
return; return;
} }
const definition = controller.selected.map(id => controller.schema!.cstByID.get(id)!.alias).join(' '); const definition = controller.selected.map(id => controller.schema!.cstByID.get(id)!.alias).join(' ');
controller.createCst(controller.nothingSelected ? CstType.BASE : CstType.TERM, false, definition); controller.createCst(controller.selected.length === 0 ? CstType.BASE : CstType.TERM, false, definition);
} }
function handleDeleteCst() { function handleDeleteCst() {

View File

@ -10,7 +10,8 @@ import {
IconNewItem, IconNewItem,
IconRotate3D, IconRotate3D,
IconText, IconText,
IconTextOff IconTextOff,
IconTypeGraph
} from '@/components/Icons'; } from '@/components/Icons';
import BadgeHelp from '@/components/info/BadgeHelp'; import BadgeHelp from '@/components/info/BadgeHelp';
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS'; import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
@ -116,6 +117,11 @@ function ToolbarTermGraph({
onClick={onDelete} onClick={onDelete}
/> />
) : null} ) : null}
<MiniButton
icon={<IconTypeGraph size='1.25rem' className='icon-primary' />}
title='Граф ступеней'
onClick={() => controller.showTypeGraph()}
/>
<MiniButton <MiniButton
icon={<IconImage size='1.25rem' className='icon-primary' />} icon={<IconImage size='1.25rem' className='icon-primary' />}
title='Сохранить изображение' title='Сохранить изображение'

View File

@ -22,6 +22,7 @@ import DlgEditVersions from '@/dialogs/DlgEditVersions';
import DlgEditWordForms from '@/dialogs/DlgEditWordForms'; import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis'; import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
import DlgRenameCst from '@/dialogs/DlgRenameCst'; import DlgRenameCst from '@/dialogs/DlgRenameCst';
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst'; import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm'; import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
import { import {
@ -65,7 +66,6 @@ export interface IRSEditContext extends ILibraryItemEditor {
isProcessing: boolean; isProcessing: boolean;
isAttachedToOSS: boolean; isAttachedToOSS: boolean;
canProduceStructure: boolean; canProduceStructure: boolean;
nothingSelected: boolean;
canDeleteSelected: boolean; canDeleteSelected: boolean;
updateSchema: (data: ILibraryUpdateData) => void; updateSchema: (data: ILibraryUpdateData) => void;
@ -107,6 +107,8 @@ export interface IRSEditContext extends ILibraryItemEditor {
produceStructure: () => void; produceStructure: () => void;
inlineSynthesis: () => void; inlineSynthesis: () => void;
substitute: () => void; substitute: () => void;
showTypeGraph: () => void;
} }
const RSEditContext = createContext<IRSEditContext | null>(null); const RSEditContext = createContext<IRSEditContext | null>(null);
@ -148,10 +150,9 @@ export const RSEditState = ({
[accessLevel, model.schema?.read_only] [accessLevel, model.schema?.read_only]
); );
const isContentEditable = useMemo(() => isMutable && !model.isArchive, [isMutable, model.isArchive]); const isContentEditable = useMemo(() => isMutable && !model.isArchive, [isMutable, model.isArchive]);
const nothingSelected = useMemo(() => selected.length === 0, [selected]);
const canDeleteSelected = useMemo( const canDeleteSelected = useMemo(
() => !nothingSelected && selected.every(id => !model.schema?.cstByID.get(id)?.is_inherited), () => selected.length > 0 && selected.every(id => !model.schema?.cstByID.get(id)?.is_inherited),
[selected, nothingSelected, model.schema] [selected, model.schema]
); );
const isAttachedToOSS = useMemo( const isAttachedToOSS = useMemo(
() => () =>
@ -171,6 +172,7 @@ export const RSEditState = ({
const [showCreateVersion, setShowCreateVersion] = useState(false); const [showCreateVersion, setShowCreateVersion] = useState(false);
const [showEditVersions, setShowEditVersions] = useState(false); const [showEditVersions, setShowEditVersions] = useState(false);
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false); const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
const [showTypeGraph, setShowTypeGraph] = useState(false);
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>(); const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
const [showCreateCst, setShowCreateCst] = useState(false); const [showCreateCst, setShowCreateCst] = useState(false);
@ -181,6 +183,18 @@ export const RSEditState = ({
const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined); const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined);
const [showTemplates, setShowTemplates] = useState(false); const [showTemplates, setShowTemplates] = useState(false);
const typeInfo = useMemo(
() =>
model.schema
? model.schema.items.map(item => ({
alias: item.alias,
result: item.parse.typification,
args: item.parse.args
}))
: [],
[model.schema]
);
useLayoutEffect( useLayoutEffect(
() => () =>
setAccessLevel(prev => { setAccessLevel(prev => {
@ -625,7 +639,6 @@ export const RSEditState = ({
isProcessing: model.processing, isProcessing: model.processing,
isAttachedToOSS, isAttachedToOSS,
canProduceStructure, canProduceStructure,
nothingSelected,
canDeleteSelected, canDeleteSelected,
setOwner, setOwner,
@ -665,7 +678,9 @@ export const RSEditState = ({
reorder, reorder,
inlineSynthesis, inlineSynthesis,
produceStructure, produceStructure,
substitute substitute,
showTypeGraph: () => setShowTypeGraph(true)
}} }}
> >
{model.schema ? ( {model.schema ? (
@ -765,6 +780,8 @@ export const RSEditState = ({
onInlineSynthesis={handleInlineSynthesis} onInlineSynthesis={handleInlineSynthesis}
/> />
) : null} ) : null}
{showTypeGraph ? <DlgShowTypeGraph items={typeInfo} hideWindow={() => setShowTypeGraph(false)} /> : null}
</AnimatePresence> </AnimatePresence>
) : null} ) : null}

View File

@ -376,6 +376,7 @@ export function labelHelpTopic(topic: HelpTopic): string {
case HelpTopic.UI_RS_EDITOR: return 'Редактор конституенты'; case HelpTopic.UI_RS_EDITOR: return 'Редактор конституенты';
case HelpTopic.UI_GRAPH_TERM: return 'Граф термов'; case HelpTopic.UI_GRAPH_TERM: return 'Граф термов';
case HelpTopic.UI_FORMULA_TREE: return 'Дерево разбора'; case HelpTopic.UI_FORMULA_TREE: return 'Дерево разбора';
case HelpTopic.UI_TYPE_GRAPH: return 'Граф ступеней';
case HelpTopic.UI_CST_STATUS: return 'Статус конституенты'; case HelpTopic.UI_CST_STATUS: return 'Статус конституенты';
case HelpTopic.UI_CST_CLASS: return 'Класс конституенты'; case HelpTopic.UI_CST_CLASS: return 'Класс конституенты';
case HelpTopic.UI_OSS_GRAPH: return 'Граф синтеза'; case HelpTopic.UI_OSS_GRAPH: return 'Граф синтеза';
@ -429,6 +430,7 @@ export function describeHelpTopic(topic: HelpTopic): string {
case HelpTopic.UI_RS_EDITOR: return 'редактирование конституенты'; case HelpTopic.UI_RS_EDITOR: return 'редактирование конституенты';
case HelpTopic.UI_GRAPH_TERM: return 'интерфейс графа термов'; case HelpTopic.UI_GRAPH_TERM: return 'интерфейс графа термов';
case HelpTopic.UI_FORMULA_TREE: return 'просмотр дерева разбора <br/>родоструктурного выражения'; case HelpTopic.UI_FORMULA_TREE: return 'просмотр дерева разбора <br/>родоструктурного выражения';
case HelpTopic.UI_TYPE_GRAPH: return 'просмотр графа ступеней';
case HelpTopic.UI_CST_STATUS: return 'нотация статуса конституенты'; case HelpTopic.UI_CST_STATUS: return 'нотация статуса конституенты';
case HelpTopic.UI_CST_CLASS: return 'нотация класса конституенты'; case HelpTopic.UI_CST_CLASS: return 'нотация класса конституенты';
case HelpTopic.UI_OSS_GRAPH: return 'графическая форма <br/>операционной схемы синтеза'; case HelpTopic.UI_OSS_GRAPH: return 'графическая форма <br/>операционной схемы синтеза';