diff --git a/src/main/js/frontend/package-lock.json b/src/main/js/frontend/package-lock.json index 6459c9c..a1d344b 100644 --- a/src/main/js/frontend/package-lock.json +++ b/src/main/js/frontend/package-lock.json @@ -20,9 +20,9 @@ "react-bootstrap": "^2.0.3", "react-bootstrap-icons": "^1.6.1", "react-dom": "^17.0.2", - "react-router-dom": "^6.2.1", + "react-json-view": "^1.21.3", "react-router": "^6.1.1", - "react-router-dom": "^6.1.1", + "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", "react-simple-tree-menu": "^1.1.18", "typescript": "^4.5.4", @@ -4181,6 +4181,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base16": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", + "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=" + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -4889,6 +4894,14 @@ "node": ">=10" } }, + "node_modules/cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dependencies": { + "node-fetch": "2.6.1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6712,6 +6725,41 @@ "bser": "2.1.1" } }, + "node_modules/fbemitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", + "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", + "dependencies": { + "fbjs": "^3.0.0" + } + }, + "node_modules/fbjs": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.2.tgz", + "integrity": "sha512-qv+boqYndjElAJHNN3NoM8XuwQZ1j2m3kEvTgdle8IDjr6oUbkEpvABWtj/rQl3vq4ew7dnElBxL4YJAwTVqQQ==", + "dependencies": { + "cross-fetch": "^3.0.4", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + } + }, + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, + "node_modules/fbjs/node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6906,6 +6954,18 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" }, + "node_modules/flux": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/flux/-/flux-4.0.3.tgz", + "integrity": "sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==", + "dependencies": { + "fbemitter": "^3.0.0", + "fbjs": "^3.0.1" + }, + "peerDependencies": { + "react": "^15.0.2 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/follow-redirects": { "version": "1.14.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", @@ -9252,11 +9312,21 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.curry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", + "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "node_modules/lodash.flow": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", + "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -9620,6 +9690,14 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -11469,6 +11547,11 @@ "node": ">=6" } }, + "node_modules/pure-color": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", + "integrity": "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=" + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -11615,6 +11698,17 @@ "node": ">=14" } }, + "node_modules/react-base16-styling": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", + "integrity": "sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=", + "dependencies": { + "base16": "^1.0.0", + "lodash.curry": "^4.0.1", + "lodash.flow": "^3.3.0", + "pure-color": "^1.2.0" + } + }, "node_modules/react-bootstrap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.0.3.tgz", @@ -11719,6 +11813,21 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-json-view": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/react-json-view/-/react-json-view-1.21.3.tgz", + "integrity": "sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==", + "dependencies": { + "flux": "^4.0.1", + "react-base16-styling": "^0.6.0", + "react-lifecycles-compat": "^3.0.4", + "react-textarea-autosize": "^8.3.2" + }, + "peerDependencies": { + "react": "^17.0.0 || ^16.3.0 || ^15.5.4", + "react-dom": "^17.0.0 || ^16.3.0 || ^15.5.4" + } + }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", @@ -11844,6 +11953,22 @@ "react-dom": ">=16.6.3" } }, + "node_modules/react-textarea-autosize": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", @@ -12473,6 +12598,11 @@ "node": ">= 0.8.0" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, "node_modules/setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -13357,6 +13487,11 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "node_modules/ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==" + }, "node_modules/tsconfig-paths": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", @@ -13473,6 +13608,24 @@ "node": ">=4.2.0" } }, + "node_modules/ua-parser-js": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -13600,6 +13753,46 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, + "node_modules/use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "dependencies": { + "ts-essentials": "^2.0.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -17531,6 +17724,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "base16": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", + "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=" + }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -18082,6 +18280,14 @@ "yaml": "^1.10.0" } }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -19435,6 +19641,43 @@ "bser": "2.1.1" } }, + "fbemitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", + "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", + "requires": { + "fbjs": "^3.0.0" + } + }, + "fbjs": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.2.tgz", + "integrity": "sha512-qv+boqYndjElAJHNN3NoM8XuwQZ1j2m3kEvTgdle8IDjr6oUbkEpvABWtj/rQl3vq4ew7dnElBxL4YJAwTVqQQ==", + "requires": { + "cross-fetch": "^3.0.4", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + }, + "dependencies": { + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + } + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -19578,6 +19821,15 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" }, + "flux": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/flux/-/flux-4.0.3.tgz", + "integrity": "sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==", + "requires": { + "fbemitter": "^3.0.0", + "fbjs": "^3.0.1" + } + }, "follow-redirects": { "version": "1.14.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", @@ -21273,11 +21525,21 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.curry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", + "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "lodash.flow": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", + "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -21552,6 +21814,11 @@ "tslib": "^2.0.3" } }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -22749,6 +23016,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "pure-color": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", + "integrity": "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=" + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -22848,6 +23120,17 @@ "whatwg-fetch": "^3.6.2" } }, + "react-base16-styling": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", + "integrity": "sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=", + "requires": { + "base16": "^1.0.0", + "lodash.curry": "^4.0.1", + "lodash.flow": "^3.3.0", + "pure-color": "^1.2.0" + } + }, "react-bootstrap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.0.3.tgz", @@ -22938,6 +23221,17 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-json-view": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/react-json-view/-/react-json-view-1.21.3.tgz", + "integrity": "sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==", + "requires": { + "flux": "^4.0.1", + "react-base16-styling": "^0.6.0", + "react-lifecycles-compat": "^3.0.4", + "react-textarea-autosize": "^8.3.2" + } + }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", @@ -23031,6 +23325,16 @@ "tiny-debounce": "^0.1.1" } }, + "react-textarea-autosize": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + } + }, "react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", @@ -23495,6 +23799,11 @@ "send": "0.17.1" } }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -24155,6 +24464,11 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==" + }, "tsconfig-paths": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", @@ -24241,6 +24555,11 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, + "ua-parser-js": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -24339,6 +24658,28 @@ } } }, + "use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "requires": { + "ts-essentials": "^2.0.3" + } + }, + "use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", + "requires": {} + }, + "use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "requires": { + "use-isomorphic-layout-effect": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/src/main/js/frontend/package.json b/src/main/js/frontend/package.json index 5658b28..14880e3 100644 --- a/src/main/js/frontend/package.json +++ b/src/main/js/frontend/package.json @@ -17,6 +17,7 @@ "react-bootstrap": "^2.0.3", "react-bootstrap-icons": "^1.6.1", "react-dom": "^17.0.2", + "react-json-view": "^1.21.3", "react-router": "^6.1.1", "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", diff --git a/src/main/js/frontend/src/App.css b/src/main/js/frontend/src/App.css index b81710b..db5aedf 100644 --- a/src/main/js/frontend/src/App.css +++ b/src/main/js/frontend/src/App.css @@ -48,11 +48,21 @@ body { .NLPContent { height: 100%; width: 100%; - background-color: lightgray; } .LoadingContent { height: 100%; width: 100%; - background-color: lightgoldenrodyellow; +} + +.i-misc { + color: green; +} + +.i-per { + color: red; +} + +.i-loc { + color: blue; } diff --git a/src/main/js/frontend/src/App.tsx b/src/main/js/frontend/src/App.tsx index 3186a6d..5763ae3 100644 --- a/src/main/js/frontend/src/App.tsx +++ b/src/main/js/frontend/src/App.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { HashRouter as Router, Route, Routes } from "react-router-dom"; import Layout from "./Layout"; import LoadingContent from "./LoadingContent"; +import NERContext from "./NERContext"; function App() { return ( @@ -11,6 +12,9 @@ function App() { }> + }> + + diff --git a/src/main/js/frontend/src/NERContext.tsx b/src/main/js/frontend/src/NERContext.tsx new file mode 100644 index 0000000..240c3c8 --- /dev/null +++ b/src/main/js/frontend/src/NERContext.tsx @@ -0,0 +1,125 @@ +import 'bootstrap/dist/css/bootstrap.min.css'; +import React, {useEffect, useState} from "react"; +import './App.css'; +import {Button, Col, Form, Row} from "react-bootstrap"; +import ReactJson from 'react-json-view'; + +function NERContext() { + + const [running, setRunning] = useState({ + "arabic": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "english-kbp": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "english": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "chinese": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "french": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "german": { "start": null, "end": null, "isRunning": false, isLoaded: false }, + "spanish": { "start": null, "end": null, "isRunning": false, isLoaded: false } + }) + + const [language, setLanguage] = useState("en"); + const [content, setContent] = useState(""); + const [namedEntities, setNamedEntities] = useState(""); + const [nerError, setNerError] = useState({ code: null, description: null, value: null, properties: {}}); + + useEffect(() => { + let uri = '/exist/restxq/stanford/nlp/logs'; + + fetch(uri) + .then((response) => response.json()) + .then( + (result) => { + setRunning(result.running); + }, + (error) => { + + } + ) + + }, []) + + // @ts-ignore + function handleChange(e) { + if (e.target.name === 'language') { + setLanguage(e.target.value); + } else { + setContent(e.target.value); + } + } + + function handleSubmit() { + const requestOptions = { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + language: language, + text: content + }) + }; + + fetch("/exist/restxq/Stanford/ner", requestOptions) + .then(res => res.json()) + .then( + (result) => { + if (result.text) { + setNamedEntities(result.text); + } else { + setNerError(result); + } + }, + (error) => { + + } + ) + + } + + return ( +
+
+ + + + Select language + + + + + + + + + + + + + Text to find named entities + + + + + + + +
+ +
Results
+
+
+
{ + nerError.code ? + <> +
Code {nerError.code}
+
Description {nerError.description}
+
Value {nerError.value}
+ + + : null + }
+
+
+
+ ) + +} + +export default NERContext; diff --git a/src/main/js/frontend/src/SideBarData.js b/src/main/js/frontend/src/SideBarData.js index 141058a..a4704b0 100644 --- a/src/main/js/frontend/src/SideBarData.js +++ b/src/main/js/frontend/src/SideBarData.js @@ -7,6 +7,10 @@ export const SideBarData = [ icon: , key: "/" }, + { + label: "NER", + key: "/ner" + }, { label: "Loading", icon: , diff --git a/src/main/xar-resources/modules/rest-api.xqm b/src/main/xar-resources/modules/rest-api.xqm index a252cfe..fc04fe5 100644 --- a/src/main/xar-resources/modules/rest-api.xqm +++ b/src/main/xar-resources/modules/rest-api.xqm @@ -1,6 +1,7 @@ xquery version "3.1"; module namespace api = "http://exist-db.org/xquery/stanford-nlp/api"; +import module namespace ner = "http://exist-db.org/xquery/stanford-nlp/ner"; import module namespace scheduler = "http://exist-db.org/xquery/scheduler"; import module namespace map = "http://www.w3.org/2005/xpath-functions/map"; @@ -131,3 +132,37 @@ function api:logs($timestamp as xs:string*) as map(*) } } }; + +(:~ + : This method runs the ner:clasify($text, $properties) on the text passed in for the language specified. + : @param $content the properties of the source graph in a JSON object + : @see ner:properties-from-language() + : @return A map + : @custom:openapi-tag Natural Language Processing + :) +declare + %rest:POST("{$content}") + %rest:path("/Stanford/ner") + %rest:consumes("application/json") + %rest:produces("application/json") + %output:media-type("application/json") + %output:method("json") +function api:query-text-as-json($content as xs:string) as map(*) { + let $postBody := fn:parse-json(util:base64-decode($content)) + let $properties := ner:properties-from-language($postBody?language) + let $classified := ner:classify($postBody?text, $properties) + return + try { + map { + 'text' : ner:stringify($classified) + } + } catch * { + map { + 'code': $err:code, + 'description': $err:description, + 'value': $err:value, + 'properties': $properties + } + } +}; + diff --git a/src/main/xquery/ner-module.xqm b/src/main/xquery/ner-module.xqm index 1f0b4b1..75a69cc 100644 --- a/src/main/xquery/ner-module.xqm +++ b/src/main/xquery/ner-module.xqm @@ -11,22 +11,26 @@ import module namespace functx = "http://www.functx.com"; import module namespace rest = "http://exquery.org/ns/restxq"; +declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; +declare namespace array = "http://www.w3.org/2005/xpath-functions/array"; +declare namespace map = "http://www.w3.org/2005/xpath-functions/map"; + (:~ : Generates the snippet match string to show the highlighted text for the client. : : @param $match The match text for a snippet that contains highlighted text : @return A string with highlight spans encoded within the string :) -declare function ner:stringify($match as node()) as xs:string { +declare function ner:stringify($match) as xs:string { fn:string-join( - for $text-or-highlight in $match/node() + for $text-or-highlight in $match return - if ($text-or-highlight instance of element()) + if ($text-or-highlight instance of element()) then fn:concat('', - $text-or-highlight/text(), + '">', + $text-or-highlight/text(), '') else $text-or-highlight @@ -35,7 +39,7 @@ declare function ner:stringify($match as node()) as xs:string { (:~ - : This method runs the ner:clasify($text, $properties) on the leaf nodes of the + : This method runs the ner:clasify($text, $properties) on the leaf nodes of the : document for the defaults for the English language. The english defaults are : in the file /db/apps/stanford-nlp/data/StanfordCoreNLP-english.json : @param $request-body The document to process. @@ -46,7 +50,7 @@ function ner:classify-document($request-body as document-node(element())) as nod }; (:~ - : This method runs the ner:clasify($text, $properties) on the leaf nodes of the + : This method runs the ner:clasify($text, $properties) on the leaf nodes of the : document for the language specified. : @param $request-body The document to process. : @param $language The two character string to identify the language to process. @@ -58,7 +62,7 @@ function ner:classify-document($request-body as document-node(element()), $langu }; (:~ - : This method runs the ner:clasify($text, $properties) on the leaf nodes of the + : This method runs the ner:clasify($text, $properties) on the leaf nodes of the : XML identitied by $node for the defaults for the English language. The english defaults are : in the file /db/apps/stanford-nlp/data/StanfordCoreNLP-english.json : @param $node The node to process. @@ -69,7 +73,7 @@ function ner:classify-node($node as node()) as node() { }; (:~ - : This method runs the ner:clasify($text, $properties) on the leaf nodes of the + : This method runs the ner:clasify($text, $properties) on the leaf nodes of the : node for the language specified. : @param $node The node to process. : @param $language The two character string to identify the language to process. @@ -91,20 +95,16 @@ function ner:classify-node($node as node(), $language as xs:string) as node() { : Any other value loads the english defaults. : @param $language The two character string to identify the language for the default JSON document. :) -declare +declare function ner:properties-from-language($language as xs:string) as map(*) { - try { - switch ($language) - case "en" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-english.json") - case "ar" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-arabic.json") - case "es" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-spanish.json") - case "fr" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-french.json") - case "zh" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-chinese.json") - case "de" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-german.json") - default return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-english.json") - } catch * { - fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-english.json") - } + switch ($language) + case "en" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-english.json") + case "ar" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-arabic.json") + case "es" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-spanish.json") + case "fr" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-french.json") + case "zh" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-chinese.json") + case "de" return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-german.json") + default return fn:json-doc("/db/apps/stanford-nlp/data/StanfordCoreNLP-english.json") }; (:~ @@ -113,6 +113,7 @@ function ner:properties-from-language($language as xs:string) as map(*) { : @param $language The two character string to identify the language to process. : @see ner:properties-from-language() : @return An XML node + : @custom:openapi-tag Natural Language Processing :) declare %rest:GET @@ -121,36 +122,11 @@ declare %rest:query-param("lang", "{$language}", "en") %rest:produces("application/xml") function ner:query-text-as-xml($text as xs:string*, $language as xs:string*) as node() { - element { 'ner' } { + element { 'ner' } { ner:classify( - util:unescape-uri($text[1], "UTF-8"), + util:unescape-uri($text[1], "UTF-8"), ner:properties-from-language($language[1]) - ) - } -}; - -(:~ - : This method runs the ner:clasify($text, $properties) on the text passed in for the language specified. - : @param $text The text to process. - : @param $language The two character string to identify the language to process. - : @see ner:properties-from-language() - : @return A map - :) -declare - %rest:GET - %rest:path("/StanfordNLP/NER") - %rest:query-param("text", "{$text}") - %rest:query-param("lang", "{$language}", "en") - %rest:produces("application/json") -function ner:query-text-as-json($text as xs:string*, $language as xs:string*) as map(*) { - map { - 'text' : - ner:stringify( - ner:classify( - util:unescape-uri($text[1], "UTF-8"), - ner:properties-from-language($language[1]) - ) - ) + ) } }; @@ -189,14 +165,14 @@ declare function ner:enrich($text as xs:string, $tokens as node()*) { let $ner-text := fn:substring($text, $start, $length) let $next := fn:subsequence($tokens, fn:index-of($tokens, $sibling-token) + 1) return ( - ner:enrich($before, $next), - element { $last-token/NER/text() } { $ner-text }, + ner:enrich($before, $next), + element { $last-token/NER/text() } { $ner-text }, if (fn:string-length($after) gt 0) then $after else ()) - + }; (:~ - : This method runs the ner:clasify($text, $properties) on the leaf nodes of the + : This method runs the ner:clasify($text, $properties) on the leaf nodes of the : node for the properties of the language. : @param $node The node to process. : @param $properties The map of the values for proceessing the pipeline. @@ -215,9 +191,9 @@ declare function ner:dispatch($node as node()?, $properties as map(*)) { :) declare function ner:pass-through($node as node()?, $properties as map(*)) { if ($node) - then element { $node/name() } { - $node/@*, - for $cnode in $node/* + then element { $node/name() } { + $node/@*, + for $cnode in $node/* return ner:dispatch($cnode, $properties) } else () @@ -230,5 +206,5 @@ let $tokens := for $token in nlp:parse($text, $properties)//token[fn:not(NER = " let $token-start := $token/CharacterOffsetBegin/number() order by $token-start descending return $token -return ner:enrich($text, $tokens) +return ner:enrich($text, $tokens) }; diff --git a/xar-assembly.xml b/xar-assembly.xml index f1128b6..05a983f 100644 --- a/xar-assembly.xml +++ b/xar-assembly.xml @@ -24,7 +24,7 @@ pre-install.xq post-install.xq - +