diff --git a/stopes/ui/seamlisten/backend/app/fileviewer.py b/stopes/ui/seamlisten/backend/app/fileviewer.py index 8a69eb8..4c2bbdf 100644 --- a/stopes/ui/seamlisten/backend/app/fileviewer.py +++ b/stopes/ui/seamlisten/backend/app/fileviewer.py @@ -9,12 +9,11 @@ import typing as tp import zipfile from pathlib import Path - +import os import torchaudio from fastapi import APIRouter from fastapi.exceptions import HTTPException from fastapi.responses import JSONResponse, Response - import stopes.core.utils as stutils import stopes.modules.speech.utils as stopes_speech from stopes.modules.speech.utils import LineResult, auto_parse_line @@ -47,7 +46,6 @@ def _read_audio(path: str, frame_offset: int, num_frames: int) -> tp.Any: return torchaudio.load( f, frame_offset=frame_offset, num_frames=num_frames ) - return torchaudio.load(path, frame_offset=frame_offset, num_frames=num_frames) @@ -105,52 +103,56 @@ def open_zip_file(file: str, start_idx: int, end_idx: int) -> tp.List[LineResult @router.post("/annotations/") -def get_annotations( - query: AnnotationQuery, -) -> tp.List[LineResult]: +def get_annotations(query: AnnotationQuery) -> tp.List[LineResult]: path = query.gz_path.strip() - print(path, query.start_idx, query.end_idx) - if path.endswith(".tsv.gz") or path.endswith(".tsv"): + resolved_path = Path(path).expanduser().resolve() + + if resolved_path.suffixes in ([".gz"], [".tsv"]): try: - return open_segment_tsv(path, query.start_idx, query.end_idx) + return open_segment_tsv(str(resolved_path), query.start_idx, query.end_idx) except FileNotFoundError: raise HTTPException( status_code=404, - detail=""" - File not found - """, + detail="File not found", ) - elif path.endswith(".zip"): - if not Path(path).exists(): + elif resolved_path.suffixes[-1] == ".zip": + if not resolved_path.exists(): raise HTTPException(status_code=404, detail="File not found") - return open_zip_file(path, query.start_idx, query.end_idx) + return open_zip_file(str(resolved_path), query.start_idx, query.end_idx) else: raise ValueError("Unknown format") @router.post("/general/") async def general_query(query: DefaultQuery) -> Response: - query_path = query.gz_path.strip() - print(query_path.split(" ")) - if query_path.endswith(".tsv.gz") or query_path.endswith(".zip"): + query_path_str = query.gz_path.strip() + query_path = Path(query_path_str).expanduser().resolve() + + if not query_path.exists(): + raise HTTPException(status_code=400, detail="Path does not exist") + + if query_path.is_dir(): + result_data = gather_folder_contents(query_path) + return result_data + + if query_path.suffixes[-1] in (".gz", ".tsv", ".zip"): return get_annotations( AnnotationQuery( gz_path=query.gz_path, start_idx=query.start_idx, end_idx=query.end_idx ) ) - elif len(query_path.split(" ")) == 3: + elif len(query_path_str.split(" ")) == 3: path, start, end = query.gz_path.split(" ") result = await serve_file( AudioQuery(sampling="wav", path=path, start=int(start), end=int(end)) ) return result - elif len(query_path.split("|")) == 3: + elif len(query_path_str.split("|")) == 3: path, start, end = query.gz_path.split("|") result = await serve_file( AudioQuery(sampling="ms", path=path, start=int(start), end=int(end)) ) return result - else: raise HTTPException( status_code=500, @@ -161,3 +163,32 @@ async def general_query(query: DefaultQuery) -> Response: a line with audio file, start and end timestamps """, ) + + +def gather_folder_contents(folder_path, max_depth=5): + def gather_contents_recursive(folder_path, current_depth): + if current_depth > max_depth: + return { + "folder": str(folder_path), + "subfolders": None, + "audio_files": None, + "unexplored": True, + } + + subfolders = [] + audio_files = [] + + for entry in folder_path.iterdir(): + if entry.is_dir(): + subfolders.append(gather_contents_recursive(entry, current_depth + 1)) + elif entry.suffix in {".wav", ".ms"}: + audio_files.append(entry.name) + + return { + "folder": str(folder_path), + "subfolders": subfolders if subfolders else None, + "audio_files": audio_files if audio_files else None, + "unexplored": False, + } + + return gather_contents_recursive(Path(folder_path), 1) diff --git a/stopes/ui/seamlisten/react_app/package-lock.json b/stopes/ui/seamlisten/react_app/package-lock.json index 2549572..df4ec55 100644 --- a/stopes/ui/seamlisten/react_app/package-lock.json +++ b/stopes/ui/seamlisten/react_app/package-lock.json @@ -8,7 +8,14 @@ "name": "react_app", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", + "@mui/icons-material": "^5.14.7", + "@mui/lab": "^5.0.0-alpha.142", + "@mui/material": "^5.14.7", + "@mui/x-tree-view": "^6.0.0-alpha.1", + "@react-spring/web": "^9.7.3", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -18,6 +25,7 @@ "@types/react-dom": "^18.0.9", "bootstrap": "^5.2.2", "crypto-hash": "^2.0.1", + "font-awesome": "^4.7.0", "puppeteer": "^18.1.0", "react": "^18.2.0", "react-bootstrap": "^2.5.0", @@ -1807,11 +1815,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1829,6 +1837,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", @@ -2151,18 +2164,139 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "dependencies": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } }, "node_modules/@emotion/stylis": { "version": "0.8.5", @@ -2174,6 +2308,24 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -2237,6 +2389,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", + "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "dependencies": { + "@floating-ui/utils": "^0.1.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz", + "integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==", + "dependencies": { + "@floating-ui/core": "^1.4.1", + "@floating-ui/utils": "^0.1.1" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", + "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", @@ -3039,6 +3225,338 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.13.tgz", + "integrity": "sha512-uC0l97pBspfDAp+iz2cJq8YZ8Sd9i73V77+WzUiOAckIVEyCm5dyVDZCCO2/phmzckVEeZCGcytybkjMQuhPQw==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@emotion/is-prop-valid": "^1.2.1", + "@floating-ui/react-dom": "^2.0.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/base/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.7.tgz", + "integrity": "sha512-sCWTUNElBPgB30iLvWe3PU7SIlTKZNf6/E/sko85iHVeHCM6WPkDw+y89CrZYjhFNmPqt2fIQM/pZu+rP2lFLA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.7.tgz", + "integrity": "sha512-mWp4DwMa8c1Gx9yOEtPgxM4b+e6hAbtZyzfSubdBwrnEE6G5D2rbAJ5MB+If6kfI48JaYaJ5j8+zAdmZLuZc0A==", + "dependencies": { + "@babel/runtime": "^7.22.10" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.142", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.142.tgz", + "integrity": "sha512-JDrT5G3QBZ0nzkKMFWzJY5KN8WcyDx4p7qOjg6hs7yKLq90VSdsqIOmyhvWDxJR7zPNQjo0WRYBAaRaQ5FlGxg==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.13", + "@mui/system": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/material": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.7.tgz", + "integrity": "sha512-jIZj9F7zMv6IlyaYDVv5M2Kp20jIX8c0kzuwteySHS/A0IvPVyomQEPtWc51MCbpDNCqzwoZUp3rQtA2lI8k7A==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.13", + "@mui/core-downloads-tracker": "^5.14.7", + "@mui/system": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.7.tgz", + "integrity": "sha512-Y86+hmDnJab2Ka42PgxKpK3oL7EiacbeeX3X/lG9LGO0wSc45wZjHeTfIlVSkkUCkexiMKEJp5NlSjZhr27NRQ==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/utils": "^5.14.7", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.7.tgz", + "integrity": "sha512-hKBETEDsIAkL8/mBwPiQj/vw28OeIhMXC3Tvj4J2bb9snxAKpiZioR1PwqP+6P41twsC/GKBd0Vr9oaWYaHuMg==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.7.tgz", + "integrity": "sha512-jeZtHglc+Pi6qjGoopT6O4RqYXVBMqHVOsjMGP0hxGSSPm1T4gsAu7jU8eqGx9YwwjvvJ0eotTjFqw7iJ6qE2Q==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/private-theming": "^5.14.7", + "@mui/styled-engine": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.7.tgz", + "integrity": "sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/x-tree-view": { + "version": "6.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-6.0.0-alpha.1.tgz", + "integrity": "sha512-JUG3HmBrmGEALbCFg1b+i7h726e1dWYZs4db3syO1j+Q++E3nbvE4Lehp5yGTFm+8esH0Tny50tuJaa4WX6VSA==", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/utils": "^5.14.3", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/base": "^5.0.0-alpha.87", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3149,9 +3667,9 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3168,6 +3686,66 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-spring/animated": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", + "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", + "dependencies": { + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", + "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/shared": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", + "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "dependencies": { + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", + "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", + "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@remix-run/router": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz", @@ -4214,10 +4792,18 @@ "@types/react": "*" } }, + "node_modules/@types/react-is": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "dependencies": { "@types/react": "*" } @@ -5899,6 +6485,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6574,9 +7168,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -8305,6 +8899,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -8356,6 +8955,14 @@ } } }, + "node_modules/font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", + "engines": { + "node": ">=0.10.3" + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -16033,6 +16640,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -18953,11 +19565,18 @@ } }, "@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -19137,18 +19756,117 @@ "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", "requires": {} }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "requires": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "requires": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + }, + "dependencies": { + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + } + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + } }, "@emotion/stylis": { "version": "0.8.5", @@ -19160,6 +19878,22 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -19204,6 +19938,36 @@ } } }, + "@floating-ui/core": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", + "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "requires": { + "@floating-ui/utils": "^0.1.1" + } + }, + "@floating-ui/dom": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz", + "integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==", + "requires": { + "@floating-ui/core": "^1.4.1", + "@floating-ui/utils": "^0.1.1" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "requires": { + "@floating-ui/dom": "^1.5.1" + } + }, + "@floating-ui/utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", + "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" + }, "@fortawesome/fontawesome-common-types": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", @@ -19798,6 +20562,164 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "@mui/base": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.13.tgz", + "integrity": "sha512-uC0l97pBspfDAp+iz2cJq8YZ8Sd9i73V77+WzUiOAckIVEyCm5dyVDZCCO2/phmzckVEeZCGcytybkjMQuhPQw==", + "requires": { + "@babel/runtime": "^7.22.10", + "@emotion/is-prop-valid": "^1.2.1", + "@floating-ui/react-dom": "^2.0.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.7.tgz", + "integrity": "sha512-sCWTUNElBPgB30iLvWe3PU7SIlTKZNf6/E/sko85iHVeHCM6WPkDw+y89CrZYjhFNmPqt2fIQM/pZu+rP2lFLA==" + }, + "@mui/icons-material": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.7.tgz", + "integrity": "sha512-mWp4DwMa8c1Gx9yOEtPgxM4b+e6hAbtZyzfSubdBwrnEE6G5D2rbAJ5MB+If6kfI48JaYaJ5j8+zAdmZLuZc0A==", + "requires": { + "@babel/runtime": "^7.22.10" + } + }, + "@mui/lab": { + "version": "5.0.0-alpha.142", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.142.tgz", + "integrity": "sha512-JDrT5G3QBZ0nzkKMFWzJY5KN8WcyDx4p7qOjg6hs7yKLq90VSdsqIOmyhvWDxJR7zPNQjo0WRYBAaRaQ5FlGxg==", + "requires": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.13", + "@mui/system": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/material": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.7.tgz", + "integrity": "sha512-jIZj9F7zMv6IlyaYDVv5M2Kp20jIX8c0kzuwteySHS/A0IvPVyomQEPtWc51MCbpDNCqzwoZUp3rQtA2lI8k7A==", + "requires": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.13", + "@mui/core-downloads-tracker": "^5.14.7", + "@mui/system": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.7.tgz", + "integrity": "sha512-Y86+hmDnJab2Ka42PgxKpK3oL7EiacbeeX3X/lG9LGO0wSc45wZjHeTfIlVSkkUCkexiMKEJp5NlSjZhr27NRQ==", + "requires": { + "@babel/runtime": "^7.22.10", + "@mui/utils": "^5.14.7", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.7.tgz", + "integrity": "sha512-hKBETEDsIAkL8/mBwPiQj/vw28OeIhMXC3Tvj4J2bb9snxAKpiZioR1PwqP+6P41twsC/GKBd0Vr9oaWYaHuMg==", + "requires": { + "@babel/runtime": "^7.22.10", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.7.tgz", + "integrity": "sha512-jeZtHglc+Pi6qjGoopT6O4RqYXVBMqHVOsjMGP0hxGSSPm1T4gsAu7jU8eqGx9YwwjvvJ0eotTjFqw7iJ6qE2Q==", + "requires": { + "@babel/runtime": "^7.22.10", + "@mui/private-theming": "^5.14.7", + "@mui/styled-engine": "^5.14.7", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.7", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "requires": {} + }, + "@mui/utils": { + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.7.tgz", + "integrity": "sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw==", + "requires": { + "@babel/runtime": "^7.22.10", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/x-tree-view": { + "version": "6.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-6.0.0-alpha.1.tgz", + "integrity": "sha512-JUG3HmBrmGEALbCFg1b+i7h726e1dWYZs4db3syO1j+Q++E3nbvE4Lehp5yGTFm+8esH0Tny50tuJaa4WX6VSA==", + "requires": { + "@babel/runtime": "^7.22.6", + "@mui/utils": "^5.14.3", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + } + }, "@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -19862,9 +20784,9 @@ } }, "@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@react-aria/ssr": { "version": "3.3.0", @@ -19874,6 +20796,49 @@ "@babel/runtime": "^7.6.2" } }, + "@react-spring/animated": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", + "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", + "requires": { + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } + }, + "@react-spring/core": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", + "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", + "requires": { + "@react-spring/animated": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } + }, + "@react-spring/shared": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", + "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "requires": { + "@react-spring/types": "~9.7.3" + } + }, + "@react-spring/types": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", + "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" + }, + "@react-spring/web": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", + "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", + "requires": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } + }, "@remix-run/router": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz", @@ -20670,10 +21635,18 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", + "requires": { + "@types/react": "*" + } + }, "@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "requires": { "@types/react": "*" } @@ -21906,6 +22879,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -22385,9 +23363,9 @@ } }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -23689,6 +24667,11 @@ "pkg-dir": "^4.1.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -23717,6 +24700,11 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==" + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -29070,6 +30058,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/stopes/ui/seamlisten/react_app/package.json b/stopes/ui/seamlisten/react_app/package.json index b3c7304..7f3725b 100644 --- a/stopes/ui/seamlisten/react_app/package.json +++ b/stopes/ui/seamlisten/react_app/package.json @@ -3,7 +3,14 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", + "@mui/icons-material": "^5.14.7", + "@mui/lab": "^5.0.0-alpha.142", + "@mui/material": "^5.14.7", + "@mui/x-tree-view": "^6.0.0-alpha.1", + "@react-spring/web": "^9.7.3", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -13,6 +20,7 @@ "@types/react-dom": "^18.0.9", "bootstrap": "^5.2.2", "crypto-hash": "^2.0.1", + "font-awesome": "^4.7.0", "puppeteer": "^18.1.0", "react": "^18.2.0", "react-bootstrap": "^2.5.0", diff --git a/stopes/ui/seamlisten/react_app/src/App.tsx b/stopes/ui/seamlisten/react_app/src/App.tsx index 5054857..5e44a55 100644 --- a/stopes/ui/seamlisten/react_app/src/App.tsx +++ b/stopes/ui/seamlisten/react_app/src/App.tsx @@ -12,6 +12,7 @@ import { Outlet, NavLink } from "react-router-dom"; import "bootstrap/dist/css/bootstrap.min.css"; export function App(): JSX.Element { + return (
diff --git a/stopes/ui/seamlisten/react_app/src/common/components/audio/WaveSurfer.css b/stopes/ui/seamlisten/react_app/src/common/components/audio/WaveSurfer.css index e14f5f8..294687b 100644 --- a/stopes/ui/seamlisten/react_app/src/common/components/audio/WaveSurfer.css +++ b/stopes/ui/seamlisten/react_app/src/common/components/audio/WaveSurfer.css @@ -12,4 +12,5 @@ .playPauseIcon :hover { color: #2bad60; + cursor: pointer; } diff --git a/stopes/ui/seamlisten/react_app/src/common/constants/config.js b/stopes/ui/seamlisten/react_app/src/common/constants/config.js index 7158d14..b246a7e 100644 --- a/stopes/ui/seamlisten/react_app/src/common/constants/config.js +++ b/stopes/ui/seamlisten/react_app/src/common/constants/config.js @@ -4,7 +4,7 @@ // This source code is licensed under the license found in the // LICENSE file in the root directory of this source tree. -const BACKEND_PORT = process.env.NODE_ENV === "development" ? "8000" : "8800"; +const BACKEND_PORT = process.env.NODE_ENV === "development" ? "8080" : "8800"; export const config = { host: "http://localhost", diff --git a/stopes/ui/seamlisten/react_app/src/common/fetchers/mining_result.ts b/stopes/ui/seamlisten/react_app/src/common/fetchers/mining_result.ts index afd775e..d9ba68a 100644 --- a/stopes/ui/seamlisten/react_app/src/common/fetchers/mining_result.ts +++ b/stopes/ui/seamlisten/react_app/src/common/fetchers/mining_result.ts @@ -7,10 +7,11 @@ import { config } from "../constants/config"; import { AnnotationQuery, LineResult } from "../types/api"; -const url = config.host + ":" + config.port + config.annotations_route; +const processFilesUrl = config.host + ":" + config.port + config.annotations_route; +const processFoldersUrl = config.host + ":" + config.port + config.general_route; async function fetchFiles(data: AnnotationQuery): Promise { - let response = await fetch(url, { + let response = await fetch(processFilesUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), @@ -21,4 +22,25 @@ async function fetchFiles(data: AnnotationQuery): Promise { return response.json(); } -export default fetchFiles; +async function processFolder(folderPath: string): Promise { + const folderQuery = { + gz_path: folderPath, + start_idx: 0, // Provide appropriate values + end_idx: 0, // Provide appropriate values + }; + + const response = await fetch(processFoldersUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(folderQuery), + }); + + if (!response.ok) { + throw response; + } + + return response.json(); +} + +export { fetchFiles, processFolder }; + diff --git a/stopes/ui/seamlisten/react_app/src/components/FileExplorer.tsx b/stopes/ui/seamlisten/react_app/src/components/FileExplorer.tsx index 54ba208..66b7ed1 100644 --- a/stopes/ui/seamlisten/react_app/src/components/FileExplorer.tsx +++ b/stopes/ui/seamlisten/react_app/src/components/FileExplorer.tsx @@ -20,12 +20,13 @@ import { import WaveSurferComponent from "../common/components/audio/WaveSurfer"; import InnerScale from "../common/components/spinners/spinner"; import { config } from "../common/constants/config"; -import fetchFiles from "../common/fetchers/mining_result"; +import {fetchFiles , processFolder} from "../common/fetchers/mining_result"; import { LineResult } from "../common/types/api"; import Help from "./fileviewer/FileExplorerHelp"; import Table from "./fileviewer/Table"; import { text_to_audio } from "../common/components/audio/audioquery_constructor"; +import FolderTreeView from "./FolderTreeView"; const FILENAME_PARAM = "file"; const PAGENUMBER_PARAM = "page"; @@ -38,6 +39,7 @@ type LoaderReturn = { files: LineResult[]; audioBlob: Blob; error: any; + folderContents: any; }; function parseParams(searchParams) { @@ -59,7 +61,6 @@ function parseLocation(location: Location) { export async function loader({ request }): Promise { const url = new URL(request.url); - const { filename, numberLines, pageNumber } = parseParams(url.searchParams); const toRet = { filename, @@ -68,6 +69,7 @@ export async function loader({ request }): Promise { files: [], audioBlob: undefined, error: null, + folderContents: [], // Add folderContents field }; try { @@ -84,7 +86,11 @@ export async function loader({ request }): Promise { toRet.files = files; return toRet; } - + else if (isDirectoryPath(filename)){ + const folderContents = await processFolder(filename); + toRet.folderContents = folderContents; + return toRet; + } const audioResult = await text_to_audio(filename, 1); if (audioResult) { toRet.audioBlob = audioResult; @@ -98,6 +104,14 @@ export async function loader({ request }): Promise { return toRet; } +// todo: needs to be enhanced +function isDirectoryPath(path) { + // Implement a logic to check if the provided path is a directory + // You might use regular expressions or other methods to check. + // For example, if the path ends with "/", it's likely a directory. + return path.endsWith("/"); +} + function Error({ error }) { const msg = error.data ? error.data.detail @@ -123,7 +137,7 @@ function useFileNavigate() { const Files = (): JSX.Element => { const [displayHelper, setDisplayHelper] = useState(false); const navigate = useFileNavigate(); - let { filename, pageNumber, numberLines, files, audioBlob, error } = + let { filename, pageNumber, numberLines, files, audioBlob, error, folderContents } = useLoaderData() as LoaderReturn; const [newFilename, setNewFilename] = useState( filename || config.default_path @@ -219,6 +233,7 @@ const Files = (): JSX.Element => { + {loading ? ( ) : error ? ( @@ -247,6 +262,9 @@ const Files = (): JSX.Element => { )} )} +
); }; diff --git a/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.css b/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.css new file mode 100644 index 0000000..b3b684f --- /dev/null +++ b/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.css @@ -0,0 +1,19 @@ +/* Style the button container */ +.download-button { + background-color: #7a26c1;; /* Set the background color */ + color: #ffffff; /* Set the text color */ + border: none; /* Remove the default button border */ + border-radius: 4px; /* Add some border radius for rounded corners */ + padding: 10px 20px; /* Add padding to make the button larger */ + cursor: pointer; /* Show a pointer cursor on hover */ + transition: background-color 0.3s ease; /* Add a smooth background color transition on hover */ + margin-top: 1rem; + /* Center the icon and text vertically and horizontally */ + + } + + /* Style the button on hover */ + .download-button:hover { + background-color: #2bad60; /* Change the background color on hover */ + } + diff --git a/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.tsx b/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.tsx new file mode 100644 index 0000000..a625fd5 --- /dev/null +++ b/stopes/ui/seamlisten/react_app/src/components/FolderTreeView.tsx @@ -0,0 +1,215 @@ +import { useState } from "react"; +import { text_to_audio } from "../common/components/audio/audioquery_constructor"; +import WaveSurferComponent from "../common/components/audio/WaveSurfer"; +import { useSpring, animated } from '@react-spring/web'; +import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon'; +import { TransitionProps } from '@mui/material/transitions'; +import Collapse from '@mui/material/Collapse'; +import { alpha, styled } from '@mui/material/styles'; +import { TreeView } from '@mui/x-tree-view/TreeView'; +import { TreeItem, TreeItemProps, treeItemClasses } from '@mui/x-tree-view/TreeItem'; +import React from 'react'; +import 'font-awesome/css/font-awesome.min.css'; +import "./FolderTreeView.css" + + + +function MinusSquare(props: SvgIconProps) { + return ( + + {/* tslint:disable-next-line: max-line-length */} + + + ); +} + +function PlusSquare(props: SvgIconProps) { + return ( + + {/* tslint:disable-next-line: max-line-length */} + + + ); +} + +function CloseSquare(props: SvgIconProps) { + return ( + + {/* tslint:disable-next-line: max-line-length */} + + + ); +} + +function TransitionComponent(props: TransitionProps) { + const style = useSpring({ + from: { + opacity: 0, + transform: 'translate3d(20px,0,0)', + }, + to: { + opacity: props.in ? 1 : 0, + transform: `translate3d(${props.in ? 0 : 20}px,0,0)`, + }, + }); + + return ( + + + + ); +} + +const CustomTreeItem = React.forwardRef( + (props: TreeItemProps, ref: React.Ref) => ( + + ), +); + +const StyledTreeItem = styled(CustomTreeItem)(({ theme }) => ({ + [`& .${treeItemClasses.iconContainer}`]: { + '& .close': { + opacity: 0.3, + }, + }, + [`& .${treeItemClasses.group}`]: { + marginLeft: 15, + paddingLeft: 18, + borderLeft: `1px dashed ${alpha(theme.palette.text.primary, 0.4)}`, + }, +})); + +const FolderTreeView = ({ folderContents }) => { + const [expandedFolders, setExpandedFolders] = useState(new Set()); + const [selectedAudioFile, setSelectedAudioFile] = useState(null); + const [audioBlob, setAudioBlob] = useState(null); + + const handleNodeToggle = (event, nodeIds) => { + const clickedNodeId = nodeIds[0]; + + if (expandedFolders.has(clickedNodeId)) { + // Node is expanded, collapse it + expandedFolders.delete(clickedNodeId); + } else { + // Node is collapsed, expand it and fetch its contents + expandedFolders.add(clickedNodeId); + } + + setExpandedFolders(new Set(expandedFolders)); + }; + + const handleAudioFileClick = async(audioFile) => { + setSelectedAudioFile(audioFile); + const audioResult = await text_to_audio(audioFile, 1); + if (audioResult) { + setAudioBlob(audioResult); + } + }; + + + + const DownloadButton = ({ blob, filename }) => { + const download = () => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + a.remove(); + }; + + return ( + + ); + }; + + + + + const renderFolderTree = (folderData) => { + if (!folderData) { + return null; + } + + return ( + } + defaultExpandIcon={} + defaultEndIcon={} + sx={{ height: 264, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }} + > + handleNodeToggle(event, [folderData.folder])} + > + {folderData.subfolders && folderData.subfolders.length > 0 && ( + folderData.subfolders.map((subfolder) => ( + + handleNodeToggle(event, [subfolder.folder])} + > + {renderFolderTree(subfolder)} + + + )) + )} + {folderData.audio_files && folderData.audio_files.length > 0 && ( + folderData.audio_files.map((audioFile) => ( + handleAudioFileClick( + `${folderData.folder}/${audioFile}` + )} + /> + )) + )} + + + ); + + }; + + return ( +
+ {renderFolderTree(folderContents)} + {!!audioBlob && ( + <> + {}} + focusedRowID={""} + currentRowID={""} + currentPlayingID={""} + currentPlayingIDHandler={() => {}} + /> + + + )} +
+ ); +}; + +export default FolderTreeView; + + diff --git a/stopes/ui/seamlisten/react_app/src/components/Notebook.css b/stopes/ui/seamlisten/react_app/src/components/Notebook.css new file mode 100644 index 0000000..bca5b90 --- /dev/null +++ b/stopes/ui/seamlisten/react_app/src/components/Notebook.css @@ -0,0 +1,67 @@ +/* Notebook container */ +.notebook-container { + display: flex; + border: 1px solid #ccc; + border-radius: 5px; + overflow: hidden; + } + + /* Folder navigation panel */ + .folder-navigation { + flex: 1; + padding: 10px; + background-color: #f5f5f5; + } + + /* Folder item */ + .folder-item { + padding: 8px; + cursor: pointer; + border-radius: 3px; + margin-bottom: 5px; + transition: background-color 0.2s; + } + + .folder-item:hover { + background-color: #e0e0e0; + } + + .selected { + background-color: #2196f3; + color: white; + font-weight: bold; + } + + /* Notebook content panel */ + .notebook-content { + flex: 3; + padding: 10px; + border-left: 1px solid #ccc; + } + + /* File viewer */ + .file-viewer { + padding: 10px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 5px; + min-height: 200px; + overflow: auto; + } + + /* File content */ + pre { + white-space: pre-wrap; + font-family: monospace; + } + + /* Default text style */ + div { + font-family: Arial, sans-serif; + } + + /* Centered text */ + .text-center { + text-align: center; + } + \ No newline at end of file diff --git a/stopes/ui/seamlisten/react_app/src/components/Notebook.tsx b/stopes/ui/seamlisten/react_app/src/components/Notebook.tsx new file mode 100644 index 0000000..f35765b --- /dev/null +++ b/stopes/ui/seamlisten/react_app/src/components/Notebook.tsx @@ -0,0 +1,109 @@ +import { useState } from 'react'; +import './Notebook.css'; // Import your custom styling + +export interface Folder { + name: string; + type: 'folder'; + content: File[]; +} + +interface File { + name: string; + type: 'file'; + content: string; +} + +interface Props { + folders: Folder[]; +} + +const Notebook: React.FC = ({ folders }) => { + const [currentFolder, setCurrentFolder] = useState(null); + const [selectedFile, setSelectedFile] = useState(null); + + const handleFolderClick = (folder: Folder) => { + setCurrentFolder(folder); + setSelectedFile(null); + }; + + const handleFileClick = (file: File) => { + setSelectedFile(file); + }; + + return ( +
+ +
+ {currentFolder ? ( + + ) : ( +
Select a folder to view its contents
+ )} + +
+
+ ); +}; + +interface FolderNavigationProps { + folders: Folder[]; + currentFolder: Folder | null; + onSelectFolder: (folder: Folder) => void; +} + +const FolderNavigation: React.FC = ({ + folders, + currentFolder, + onSelectFolder, +}) => ( +
+ {folders.map((folder) => ( +
onSelectFolder(folder)} + className={`folder-item ${currentFolder === folder ? 'selected' : ''}`} + > + {folder.name} +
+ ))} +
+); + +interface FileViewerProps { + file: File | null; +} + +const FileViewer: React.FC = ({ file }) => ( +
+ {file ? ( +
{file.content}
+ ) : ( +
Select a file to view its content
+ )} +
+); + +interface FolderViewProps { + folder: Folder; + onSelectFile: (file: File) => void; +} + +const FolderView: React.FC = ({ folder, onSelectFile }) => ( +
+ {folder.content.map((file) => ( +
onSelectFile(file)} + className="file-item" + > + {file.name} +
+ ))} +
+); + +export default Notebook; diff --git a/stopes/ui/seamlisten/react_app/src/components/fileviewer/table/Row.tsx b/stopes/ui/seamlisten/react_app/src/components/fileviewer/table/Row.tsx index c297fec..5f7ee57 100644 --- a/stopes/ui/seamlisten/react_app/src/components/fileviewer/table/Row.tsx +++ b/stopes/ui/seamlisten/react_app/src/components/fileviewer/table/Row.tsx @@ -47,6 +47,8 @@ function CellRender({ ); case "text": return {object.content}; + default: + return {object}; } } diff --git a/stopes/ui/seamlisten/react_app/tsconfig.json b/stopes/ui/seamlisten/react_app/tsconfig.json index ffa3aa7..c2fa1a1 100644 --- a/stopes/ui/seamlisten/react_app/tsconfig.json +++ b/stopes/ui/seamlisten/react_app/tsconfig.json @@ -4,7 +4,8 @@ "allowJs": true, "target": "es5", "jsx": "react-jsx", - "moduleResolution": "node" + "moduleResolution": "node", + "esModuleInterop": true, }, "include": ["./src/**/*", "./src/**/**/*"] }