From c41254313327ef184fb77b4b5a46acf02dc2780f Mon Sep 17 00:00:00 2001 From: Martin Stefcek Date: Fri, 8 Mar 2024 13:26:52 +0400 Subject: [PATCH] feat: add template web --- Common/config.py | 6 +- commands.py | 6 + main.py | 11 +- process_type.py | 4 + template-web/.editorconfig | 11 + template-web/.eslintignore | 2 + template-web/.eslintrc.cjs | 18 + template-web/.gitattributes | 1 + template-web/.gitignore | 24 + template-web/LICENSE | 13 + template-web/README.md | 21 + template-web/index.html | 16 + template-web/package-lock.json | 3836 +++++++++++++++++ template-web/package.json | 39 + .../public/favicon/android-icon-192x192.png | Bin 0 -> 13704 bytes template-web/public/favicon/favicon-16x16.png | Bin 0 -> 1540 bytes template-web/public/favicon/favicon-32x32.png | Bin 0 -> 2103 bytes template-web/public/favicon/favicon-96x96.png | Bin 0 -> 6117 bytes template-web/src/App.css | 42 + template-web/src/App.tsx | 60 + template-web/src/assets/Logo.tsx | 33 + template-web/src/assets/react.svg | 1 + template-web/src/components/AlertDialog.tsx | 85 + template-web/src/components/Breadcrumbs.tsx | 67 + .../src/components/CallTemplateForm.tsx | 175 + .../src/components/CopyToClipboard.tsx | 66 + template-web/src/components/Copyright.tsx | 38 + template-web/src/components/JsonTooltip.tsx | 36 + template-web/src/components/MenuItems.tsx | 96 + template-web/src/components/PageHeading.tsx | 51 + .../src/components/SecondaryHeading.tsx | 51 + .../src/components/StyledComponents.ts | 79 + template-web/src/components/Title.tsx | 36 + .../src/connect/TariConnectButton.tsx | 46 + .../TariWalletDaemonConnectDialog.module.css | 196 + .../connect/TariWalletDaemonConnectDialog.tsx | 130 + .../src/connect/TariWalletSelectionDialog.tsx | 146 + .../src/connect/content/metamask-logo.svg | 31 + .../src/connect/content/tari-logo-white.svg | 18 + .../src/connect/content/tari-logo.svg | 18 + template-web/src/index.css | 68 + template-web/src/main.tsx | 39 + template-web/src/routes/ErrorPage.tsx | 59 + template-web/src/routes/home/Home.css | 169 + template-web/src/routes/home/Home.tsx | 272 ++ template-web/src/routes/home/SettingsForm.tsx | 76 + template-web/src/routes/home/index.ts | 3 + .../src/routes/substates/Substates.css | 169 + .../src/routes/substates/Substates.tsx | 125 + template-web/src/routes/substates/index.ts | 3 + template-web/src/store/provider.ts | 43 + template-web/src/store/settings.ts | 48 + template-web/src/theme/LayoutMain.tsx | 195 + .../src/theme/fonts/AvenirLTStd-Book.otf | Bin 0 -> 28288 bytes .../src/theme/fonts/AvenirLTStd-Heavy.otf | Bin 0 -> 28508 bytes .../src/theme/fonts/AvenirLTStd-Medium.otf | Bin 0 -> 28132 bytes template-web/src/theme/theme.css | 64 + template-web/src/theme/theme.ts | 102 + template-web/src/vite-env.d.ts | 1 + template-web/src/wallet.ts | 238 + template-web/tsconfig.json | 25 + template-web/tsconfig.node.json | 11 + template-web/vite.config.ts | 7 + template_web.py | 23 + webui/src/App.css | 7 +- webui/src/routes/Main.tsx | 13 + 66 files changed, 7261 insertions(+), 8 deletions(-) create mode 100644 template-web/.editorconfig create mode 100644 template-web/.eslintignore create mode 100644 template-web/.eslintrc.cjs create mode 100644 template-web/.gitattributes create mode 100644 template-web/.gitignore create mode 100644 template-web/LICENSE create mode 100644 template-web/README.md create mode 100644 template-web/index.html create mode 100644 template-web/package-lock.json create mode 100644 template-web/package.json create mode 100644 template-web/public/favicon/android-icon-192x192.png create mode 100644 template-web/public/favicon/favicon-16x16.png create mode 100644 template-web/public/favicon/favicon-32x32.png create mode 100644 template-web/public/favicon/favicon-96x96.png create mode 100644 template-web/src/App.css create mode 100644 template-web/src/App.tsx create mode 100644 template-web/src/assets/Logo.tsx create mode 100644 template-web/src/assets/react.svg create mode 100644 template-web/src/components/AlertDialog.tsx create mode 100644 template-web/src/components/Breadcrumbs.tsx create mode 100644 template-web/src/components/CallTemplateForm.tsx create mode 100644 template-web/src/components/CopyToClipboard.tsx create mode 100644 template-web/src/components/Copyright.tsx create mode 100644 template-web/src/components/JsonTooltip.tsx create mode 100644 template-web/src/components/MenuItems.tsx create mode 100644 template-web/src/components/PageHeading.tsx create mode 100644 template-web/src/components/SecondaryHeading.tsx create mode 100644 template-web/src/components/StyledComponents.ts create mode 100644 template-web/src/components/Title.tsx create mode 100644 template-web/src/connect/TariConnectButton.tsx create mode 100644 template-web/src/connect/TariWalletDaemonConnectDialog.module.css create mode 100644 template-web/src/connect/TariWalletDaemonConnectDialog.tsx create mode 100644 template-web/src/connect/TariWalletSelectionDialog.tsx create mode 100644 template-web/src/connect/content/metamask-logo.svg create mode 100644 template-web/src/connect/content/tari-logo-white.svg create mode 100644 template-web/src/connect/content/tari-logo.svg create mode 100644 template-web/src/index.css create mode 100644 template-web/src/main.tsx create mode 100644 template-web/src/routes/ErrorPage.tsx create mode 100644 template-web/src/routes/home/Home.css create mode 100644 template-web/src/routes/home/Home.tsx create mode 100644 template-web/src/routes/home/SettingsForm.tsx create mode 100644 template-web/src/routes/home/index.ts create mode 100644 template-web/src/routes/substates/Substates.css create mode 100644 template-web/src/routes/substates/Substates.tsx create mode 100644 template-web/src/routes/substates/index.ts create mode 100644 template-web/src/store/provider.ts create mode 100644 template-web/src/store/settings.ts create mode 100644 template-web/src/theme/LayoutMain.tsx create mode 100644 template-web/src/theme/fonts/AvenirLTStd-Book.otf create mode 100644 template-web/src/theme/fonts/AvenirLTStd-Heavy.otf create mode 100644 template-web/src/theme/fonts/AvenirLTStd-Medium.otf create mode 100644 template-web/src/theme/theme.css create mode 100644 template-web/src/theme/theme.ts create mode 100644 template-web/src/vite-env.d.ts create mode 100644 template-web/src/wallet.ts create mode 100644 template-web/tsconfig.json create mode 100644 template-web/tsconfig.node.json create mode 100644 template-web/vite.config.ts create mode 100644 template_web.py diff --git a/Common/config.py b/Common/config.py index 14fdd5c..96d43e8 100644 --- a/Common/config.py +++ b/Common/config.py @@ -42,6 +42,7 @@ def get_env_or_default(env_name: str, default: Any, validation: Any = None) -> A WEBUI_PORT = get_env_or_default("DAN_TESTING_WEBUI_PORT", "auto") +TEMPLATE_WEB_PORT = get_env_or_default("DAN_TESTING_TEMPLATE_WEB_PORT", "auto") DATA_FOLDER = get_env_or_default("DAN_TESTING_DATA_FOLDER", "Data") TARI_BINS_FOLDER = get_env_or_default("TARI_BINS_FOLDER", "bins") TARI_DAN_BINS_FOLDER = get_env_or_default("TARI_DAN_BINS_FOLDER", "bins") @@ -62,10 +63,7 @@ def get_env_or_default(env_name: str, default: Any, validation: Any = None) -> A # Specify args e.g. mint=10000,10001,1. Start the value with "w:" to choose Workspace arg, specify multiples with | e.g. fungible::mint=w:0|fungible::mint=10000,10001,1 # use ! to dump the buckets into the account # DEFAULT_TEMPLATE_FUNCTION = "mint" -DEFAULT_TEMPLATE_FUNCTION = get_env_or_default( - "DAN_TESTING_DEFAULT_TEMPLATE_FUNCTION", - "" -) +DEFAULT_TEMPLATE_FUNCTION = get_env_or_default("DAN_TESTING_DEFAULT_TEMPLATE_FUNCTION", "") BURN_AMOUNT = int(get_env_or_default("DAN_TESTING_BURN_AMOUNT", 1000000)) NO_FEES = is_boolstring_true(get_env_or_default("DAN_TESTING_NO_FEES", "false", is_boolstring)) diff --git a/commands.py b/commands.py index be6b0b6..52006c7 100644 --- a/commands.py +++ b/commands.py @@ -10,6 +10,7 @@ from Collections.dan_wallet_daemons import dan_wallets from Collections.base_nodes import base_nodes from Common.local_ip import local_ip +from template_web import TemplateWebServer import os import base64 import json @@ -20,11 +21,13 @@ class Commands: def __init__( self, tari_connector_sample: Optional[TariConnectorSample], + template_web_server: Optional[TemplateWebServer], server: Server, signaling_server: SignalingServer, ) -> None: self.miner = miner self.tari_connector_sample = tari_connector_sample + self.template_web_server = template_web_server self.server = server self.signaling_server = signaling_server self.indexers = indexers @@ -106,4 +109,7 @@ def http(self, what: str) -> Optional[str]: if process_type.is_connector(what): if self.tari_connector_sample: return f"http://{local_ip}:{self.tari_connector_sample.http_port}" + if process_type.is_template_web(what): + if self.template_web_server: + return f"http://{local_ip}:{self.template_web_server.http_port}" return None diff --git a/main.py b/main.py index 32ec8ad..fde6347 100644 --- a/main.py +++ b/main.py @@ -34,6 +34,7 @@ from Common.local_ip import local_ip from commands import Commands from webui import JrpcWebuiServer +from template_web import TemplateWebServer import os import re import shutil @@ -45,8 +46,7 @@ from Collections.validator_nodes import validator_nodes from Collections.indexers import indexers from Collections.dan_wallet_daemons import dan_wallets -from typing import Any, Optional -import signal +from typing import Any accounts: dict[str, Any] = {} @@ -228,6 +228,7 @@ def check_executable(bins_folder: str, file_name: str): server = None tari_connector_sample = None webui_server = None +template_web_server = None commands = None try: @@ -279,9 +280,12 @@ def check_executable(bins_folder: str, file_name: str): print_step("Starting tari-connector test website") tari_connector_sample = TariConnectorSample(signaling_server_address=signaling_server.address) - commands = Commands(tari_connector_sample, server, signaling_server) + if signaling_server.address: + template_web_server = TemplateWebServer(signaling_server.address) + commands = Commands(tari_connector_sample, template_web_server, server, signaling_server) webui_server = JrpcWebuiServer(commands) + templates: dict[str, Template] = {} if STEPS_CREATE_TEMPLATE: print_step("GENERATING TEMPLATE") @@ -484,6 +488,7 @@ def create_account(i: int, amount: int): print("ctrl-c pressed during setup") del webui_server +del template_web_server del commands del tari_connector_sample del signaling_server diff --git a/process_type.py b/process_type.py index 66674ce..7359c9f 100644 --- a/process_type.py +++ b/process_type.py @@ -33,6 +33,10 @@ def is_connector(what: str) -> bool: return what.startswith("TariConnector") +def is_template_web(what: str) -> bool: + return what.startswith("TemplateWeb") + + def get_index(what: str) -> Optional[int]: try: _, id = what.split("_") diff --git a/template-web/.editorconfig b/template-web/.editorconfig new file mode 100644 index 0000000..beffa30 --- /dev/null +++ b/template-web/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/template-web/.eslintignore b/template-web/.eslintignore new file mode 100644 index 0000000..515dfdf --- /dev/null +++ b/template-web/.eslintignore @@ -0,0 +1,2 @@ +coverage +**/templates diff --git a/template-web/.eslintrc.cjs b/template-web/.eslintrc.cjs new file mode 100644 index 0000000..d6c9537 --- /dev/null +++ b/template-web/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} diff --git a/template-web/.gitattributes b/template-web/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/template-web/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/template-web/.gitignore b/template-web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/template-web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/template-web/LICENSE b/template-web/LICENSE new file mode 100644 index 0000000..ba4de2d --- /dev/null +++ b/template-web/LICENSE @@ -0,0 +1,13 @@ +Copyright 2024 Stan Bondi + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/template-web/README.md b/template-web/README.md new file mode 100644 index 0000000..ffa5dc1 --- /dev/null +++ b/template-web/README.md @@ -0,0 +1,21 @@ +# Tari Template Website + +UNDER DEVELOPMENT + +Provides a basic Vite + React interface to construct and submit transactions from a given WASM template address. + +Currently, only the wallet JSON-RPC interface is supported. + +### TODO + +- [x] Add support for [Tari snap](https://github.com/tari-project/tari-snap) +- [ ] Support for dry-runs +- [ ] Support for transaction fee estimation +- [ ] Improved handling of argument and return types (e.g. Proof, Bucket etc) +- [ ] Improved badge usage +- [ ] Dashboard that displays well-formatted data from managed components +- [ ] Previous transactions list +- [ ] Customization of transactions before submitting +- [ ] UX + + diff --git a/template-web/index.html b/template-web/index.html new file mode 100644 index 0000000..ded3964 --- /dev/null +++ b/template-web/index.html @@ -0,0 +1,16 @@ + + + + + + + + + + Tari Template Explorer + + +
+ + + diff --git a/template-web/package-lock.json b/template-web/package-lock.json new file mode 100644 index 0000000..33e5e93 --- /dev/null +++ b/template-web/package-lock.json @@ -0,0 +1,3836 @@ +{ + "name": "@tariproject/template-web", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@tariproject/template-web", + "version": "0.0.0", + "dependencies": { + "@mui/icons-material": "^5.11.0", + "@mui/material": "^5.11.3", + "@mui/x-data-grid": "^5.17.17", + "@tariproject/tarijs": "^0.1.14", + "@tariproject/wallet_jrpc_client": "^1.0.2", + "qrcode.react": "3.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-icons": "^4.9.0", + "react-router-dom": "^6.4.3", + "use-react-router-breadcrumbs": "^4.0.1", + "zustand": "4.5.1" + }, + "devDependencies": { + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^8.56.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "vite": "^5.1.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "devOptional": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "devOptional": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "devOptional": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "devOptional": true, + "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/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==", + "devOptional": true + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "devOptional": true, + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "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.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "devOptional": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@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.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "devOptional": true, + "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/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==", + "devOptional": true, + "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/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "devOptional": true + }, + "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==", + "devOptional": true, + "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/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz", + "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "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/core-downloads-tracker": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz", + "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz", + "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "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/material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz", + "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.38", + "@mui/core-downloads-tracker": "^5.15.12", + "@mui/system": "^5.15.12", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "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-org" + }, + "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/private-theming": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz", + "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.12", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "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.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "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.15.12", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz", + "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.12", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "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.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz", + "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-data-grid": { + "version": "5.17.26", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.26.tgz", + "integrity": "sha512-eGJq9J0g9cDGLFfMmugOadZx0mJeOd/yQpHwEa5gUXyONS6qF0OhXSWyDOhDdA3l2TOoQzotMN5dY/T4Wl1KYA==", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@mui/utils": "^5.10.3", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "reselect": "^4.1.6" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.2 || ^18.0.0", + "react-dom": "^17.0.2 || ^18.0.0" + } + }, + "node_modules/@mui/x-data-grid/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "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" + } + }, + "node_modules/@remix-run/router": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", + "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", + "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", + "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", + "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", + "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", + "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", + "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", + "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", + "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", + "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", + "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", + "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", + "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.5.tgz", + "integrity": "sha512-4/JGkG4b1Z/QwCGgx+Ub46MlzrsZvBk5JSkxm9PcZ4bSX81c+4Y94Xm3iLp5Ka8NxzS5rD4mJSpcYuN3Tw0ceg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.2", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.4.5", + "@swc/core-darwin-x64": "1.4.5", + "@swc/core-linux-arm-gnueabihf": "1.4.5", + "@swc/core-linux-arm64-gnu": "1.4.5", + "@swc/core-linux-arm64-musl": "1.4.5", + "@swc/core-linux-x64-gnu": "1.4.5", + "@swc/core-linux-x64-musl": "1.4.5", + "@swc/core-win32-arm64-msvc": "1.4.5", + "@swc/core-win32-ia32-msvc": "1.4.5", + "@swc/core-win32-x64-msvc": "1.4.5" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.5.tgz", + "integrity": "sha512-toMSkbByHNfGXESyY1aiq5L3KutgijrNWB/THgdHIA1aIbwtrgMdFQfxpSE+INuuvWYi/Fxarv86EnU7ewbI0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.5.tgz", + "integrity": "sha512-LN8cbnmb4Gav8UcbBc+L/DEthmzCWZz22rQr6fIEHMN+f0d71fuKnV0ca0hoKbpZn33dlzUmXQE53HRjlRUQbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.5.tgz", + "integrity": "sha512-suRFkhBWmOQxlM4frpos1uqjmHfaEI8FuJ0LL5+yRE7IunNDeQJBKujGZt6taeuxo1KqC0N0Ajr8IluN2wrKpA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.5.tgz", + "integrity": "sha512-mLKxasQArDGmR6k9c0tkPVUdoo8VfUecocMG1Mx9NYvpidJNaZ3xq9nYM77v7uq1fQqrs/59DM1fJTNRWvv/UQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.5.tgz", + "integrity": "sha512-pgKuyRP7S29U/HMDTx+x8dFcklWxwB9cHFNCNWSE6bS4vHR93jc4quwPX9OEQX5CVHxm+c8+xof043I4OGkAXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.5.tgz", + "integrity": "sha512-srR+YN86Oerzoghd0DPCzTbTp08feeJPSr9kkNdmtQWENOa4l/9cJV3+XY6vviw0sEjezPmYnc3SwRxJRaxvEw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.5.tgz", + "integrity": "sha512-aSf41LZtDeG5VXI4RCnzcu0UInPyNm3ip8Kw+sCK+sSqW9o7DgBkyqqbip3RZq84fNUHBQQQQdKXetltsyRRqw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.5.tgz", + "integrity": "sha512-vU3k8JwRUlTkJMfJQY9E4VvLrsIFOpfhnvbuXB84Amo1cJsz+bYQcC6RSvY7qpaDzDKFdUGbJco4uZTRoRf7Mg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.5.tgz", + "integrity": "sha512-856YRh3frRK2XbrSjDOFBgoAqWJLNRkaEtfGzXfeEoyJlOz0BFsSJHxKlHAFkxRfHe2li9DJRUQFTEhXn4OUWw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.5.tgz", + "integrity": "sha512-j1+kV7jmWY1+NbXAvxAEW165781yLXVZKLcoXIZKmw18EatqMF6w8acg1gDG8C+Iw5aWLkRZVS4pijSh7+DtCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, + "node_modules/@swc/types": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", + "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", + "dev": true + }, + "node_modules/@tariproject/tarijs": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@tariproject/tarijs/-/tarijs-0.1.14.tgz", + "integrity": "sha512-8ggUSMtBP9tjirjbZx65u69feGX+1+MnkkVRbH1vtyP5zvhwrRHjKu/vFZTdXHwBwLu0YMQBKZUG90pzqW0oRA==", + "peerDependencies": { + "qrcode.react": "^3.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/@tariproject/typescript-bindings": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@tariproject/typescript-bindings/-/typescript-bindings-0.1.0.tgz", + "integrity": "sha512-wFX4ngXxYYbIm3VT3GnKUVv7ji8SoGfzzDVEdTR6TnJ+JZE62jIocG/z+SB+wLqcihNieVURwAOMwsYjxHrvvA==" + }, + "node_modules/@tariproject/wallet_jrpc_client": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tariproject/wallet_jrpc_client/-/wallet_jrpc_client-1.0.2.tgz", + "integrity": "sha512-mQk2hACkfNzGSI0pd9VcQFkBtAKpnbNPPHwCH/nfY9xgXD5mpTctz/CNvxvsXkgfHuGJm74ZgUUBcHDWbQ6K2g==", + "dependencies": { + "@tariproject/typescript-bindings": "0.1.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "devOptional": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "18.2.64", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.64.tgz", + "integrity": "sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.21.tgz", + "integrity": "sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.6.0.tgz", + "integrity": "sha512-XFRbsGgpGxGzEV5i5+vRiro1bwcIaZDIdBRP16qwm+jP68ue/S8FJTBEgOeojtVDYrbSua3XFp71kC8VJE6v+g==", + "dev": true, + "dependencies": { + "@swc/core": "^1.3.107" + }, + "peerDependencies": { + "vite": "^4 || ^5" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "devOptional": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "devOptional": true + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "devOptional": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "devOptional": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "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==", + "devOptional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.5.tgz", + "integrity": "sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==", + "dev": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "devOptional": true + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "devOptional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "devOptional": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "devOptional": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "devOptional": true + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "devOptional": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "devOptional": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "devOptional": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "devOptional": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "devOptional": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "devOptional": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "devOptional": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "devOptional": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "peerDependencies": { + "react": "*" + } + }, + "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/react-router": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "dependencies": { + "@remix-run/router": "1.15.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "dependencies": { + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "devOptional": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", + "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.12.1", + "@rollup/rollup-android-arm64": "4.12.1", + "@rollup/rollup-darwin-arm64": "4.12.1", + "@rollup/rollup-darwin-x64": "4.12.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", + "@rollup/rollup-linux-arm64-gnu": "4.12.1", + "@rollup/rollup-linux-arm64-musl": "4.12.1", + "@rollup/rollup-linux-riscv64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-musl": "4.12.1", + "@rollup/rollup-win32-arm64-msvc": "4.12.1", + "@rollup/rollup-win32-ia32-msvc": "4.12.1", + "@rollup/rollup-win32-x64-msvc": "4.12.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "devOptional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-react-router-breadcrumbs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/use-react-router-breadcrumbs/-/use-react-router-breadcrumbs-4.0.1.tgz", + "integrity": "sha512-Zbcy0KvWt1JePFcUHJAnTr7Z+AeO9WxmPs6A5Q/xqOVoi8edPKzpqHF87WB2opXwie/QjCxrEyTB7kFg7fgXvQ==", + "peerDependencies": { + "react": ">=16.8", + "react-router-dom": ">=6.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/vite": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz", + "integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "devOptional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.1.tgz", + "integrity": "sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + } + } +} diff --git a/template-web/package.json b/template-web/package.json new file mode 100644 index 0000000..3ecec62 --- /dev/null +++ b/template-web/package.json @@ -0,0 +1,39 @@ +{ + "name": "@tariproject/template-web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@mui/icons-material": "^5.11.0", + "@mui/material": "^5.11.3", + "@mui/x-data-grid": "^5.17.17", + "@tariproject/tarijs": "^0.1.14", + "@tariproject/wallet_jrpc_client": "^1.0.2", + "qrcode.react": "3.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-icons": "^4.9.0", + "react-router-dom": "^6.4.3", + "use-react-router-breadcrumbs": "^4.0.1", + "zustand": "4.5.1" + }, + "devDependencies": { + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^8.56.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "vite": "^5.1.0" + } +} diff --git a/template-web/public/favicon/android-icon-192x192.png b/template-web/public/favicon/android-icon-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..19a7b783c0da2bc0ff6fa457168947cc4d6936b7 GIT binary patch literal 13704 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 Q!wN=DN=dR#+&JWa03vF2@&Et; literal 0 HcmV?d00001 diff --git a/template-web/public/favicon/favicon-16x16.png b/template-web/public/favicon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..223883aaccea619d6eeceb17233121b1a3d21e8e GIT binary patch literal 1540 zcmaiz3rtgI6vsbN1T;<)7lp-{vSBHd`)Y4r*H=nFs9FNGbDBlvw!JMC3JqM=;V={D z3!D>`DNIDf7fxj`@d2XZ%zRBW4AJorahNGi$9zo#&Tpr6Ze+=_CSSkT|NPGXoUhGK zOo$sb;;j(~p;3nT7!%B6yd!WZe9MT@b6^_g&>Qs#)vO=+g7=60kStSNG^)Bhp%*q1 zYrM&b&=M&^%T^%N4@b-HB9u)dbT1hpt{9>5?$Y|CDG>K4ake=Y1j!suRpS&L7IfI6 z!>g1yO^u7_m$@viARpUwcoY3{57C#V!3X8NIV!xI#m6GLKULx_)Iei+TY&;2CoUtO z*2%gqNLx11_)PfqD`8DvQvGM8t$T?+98!5C;#PCmrE}7&RviW)&tX{DwHTNm`G5d{ z)Ntj{;>B7ls_`c*UZcRDGk7D7zo1|8K5wrCPOVqDT8Y;&c!T%$k7BBS8~OV#;vt;B z!g^E~90GPd1OD+w2Hd_VC7hcR3|=e<}40npPWmyDs8pgRHYLydC-m1SqHEbva=5gsih(*5wQT@jK}?XvKE& z>2Bh;{ZaR-jX$R!J;0F#*hkM1ahCslcm0pGBg9c;VR?u4yufAI} zC3t^M|Nj{uJlu4#c}bXG*w&xci5H=WVF8P-ozwfhx$s0+`E-BP{eep>5<&w;7;0}u zOzpPk9_j6_TQMtSau+?dQx^F1ksV8i4Xw!!nCN-ZH1UI;#r`$z{k;c18J(86L^a)@PCT+D8=ZYBkr zAb0%yESTecW5$KlX|QNA#OTezE!O15;lU;5*5dhNa_44`G7_%07pN=Q<7FrFc5JB0 z-&djwh;RS)hl}lJH@95wI^BGsZROg$j@G6dXIj4RSbgsLmFbegEqRno8^%UWc}Ee+ zN!4W8cD*E&G0?h6Dq`xpO8MltHF~XvI#pg>Id9jl+5-(0rXv09hOg@P9I0AZv7=^R zU971fPhWrd;EA1w_8;GS^y@`4#@!xM7c@59Sfna5E{eB%&QI8-&c;c8eP6gEkWohRCOQQ)kZ0!&CjD`%#OM^GQRYg}j331LOY^?dCZ>2LEeApaK@u`Z zVsyF$F~=<+pDW6p?wJ0~+=PE|jAl?FMx|A2HA-5euun@(0?Ft>oH@=V0-~d%iz=qw zhpV}RuHG{lklmRkK>3s_T};bxP~7T&_r fc3x207`w(oLIer^$|7B%kO3KD6Jn~Olb8PqR*-pU literal 0 HcmV?d00001 diff --git a/template-web/public/favicon/favicon-32x32.png b/template-web/public/favicon/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..bbe1e1bb6be10d52a1ca7fe1db2b6aa86bc0c305 GIT binary patch literal 2103 zcmZ{l2~d;C632%Hxs|sSA&4S~NE9LY0x^(ag4{#|B@#h_Ckgp-2q7HdbX|}mf`CGh zOOBO8Q9**RD(H&ILQo=dNGXS_Ai7UMKwU(X#pQiiTlK81dNtM4HPgTTcTY{#Ox8Xh zkJZ{n+5mvnG*4GL;!RgfQyrOOl9E0kPL1p2?F7Kp(>hDcRmfT;hVJ1E8hbZPu8^Ug zbZ-EXEC5JJ2VfD|N_h=HECj$*2ms^~0ML=;H+^>^0d03NnyLlV$P{f*w z-sS1}&yelRKJl8lTD>olg7TQ=j|cC3nYlJJ@~-i(yUlVnX$eMccA`eTc*7~}iT9MW z#h!5$>YZJLv!;gJribI%G(tA7jvSr^>T6(btDhszt%4993I!5n~ zxGYh#53}DptTPTf+!~ix@BWOmw*-7@k{?NfvF;e2#ryi*U3wIbKS=ZWYix<4kq z$m}ghzGa`zI1wI_qCcmmVpwooYGf6Mx01i1g-0cP(tq_@LzOsf`}o0H#U}j-&!(-} z4!Ts9nL~ONx?*_tVc!Fu>cngZV;N9dHmd(1AHT2uA~5Pu~4{fiGM#3a#7zA9H1~L@9C2iBeo_-~JQs zmam=XDq~uMRBbihvE!xHv*OMkHQV5jNO@-z>h6Xw^8=IcjT$t*ce7~dxo&@3qH-iy zW>`S2*cx5i-gsN9-|Sy`H&t#1h3nV{$eYZ&FnE$Y-HHlB@=nbYBVvxjuWMiF8ppc@ z(toCq<|k%rqj!4D?c~^`)m6>x$T&jK^H+p``~!_38^a8@w!Q%1!Hwym+P>&5&J#@a5&SuCB?{*_n(gFY!i^ zNV%^bb%h4gEh1=^D2ehYDk_ZLw&PMB!Fz;<|B^OKQg(?!|U#UDk(D zZpyYKugQt0$^7YKNmHM1b4r|RBrFLERiJ#idw%9195gG=Lk&n(wep5b6|-t{l2*r@ zPVKc52kjEwp0{LBrxGmgdla`(88$7#~&7+Q8z=>FYX ztx?;C?upEfNR*zM)uh$Cd%F3Wzr0dvHy>$M!bP(s2@>e2BhRIJsfkXxPCsV({ep$U z&U0>63HxPa^_4u6D;a_h5`$LVOLu315j?2qv zbAcI(Q?zAp25#@scdYlrgX07`?D)r>|VEZ%z6QGelQJg|S(NMSgK`;ovE1nV--4#o_+f1Q$IEh2UVUPba>(o#9)#Eui!XwKV>r zL#07w$*2=vdYSj5wQqaHTI;OWdn{cf%2M%^$(F*tEiCr~S86}y)?D-U@(^F{Zuq!O zw^pUkr>w5rZMeT-@px@3#+Tl=XxB2;*bp6jLDV|od%{Ggw3c>}Hv>tcH zM&g^FRb>D=R1$+wmcr5fDGg?XaN`<7!DtJ|(sofRLke3ZPW^I_Zk z{k`_OcNB2EkaorJ>FLtbsLMdTJBVlzcBIW!tZ9I%0GAZv(VjVJiw31o;swzb&~L1YN} z6FY$X6yGEWgls-1@&6~BjN#iO3GOQuVuTz~JTn>wGy#(fdo#KG&@fXX)(&fLO)|BC z@C0jUhc({D)E7@Q<%vX*WE?I&J|4?op%Fu9tT3AUn|KBh1cob$e!N%#i%fPEhQfG64Lf#?i`L4Tw3H{;J|i+C%@V8bR&1X=eD z;>{PpqQpoTeC-Ms8NqdIKH&2Y9dAE`0{9*FM0-11$j*jC4f911y>E2(^OIlzIXj=J zrcNWF1K)%gbQ<9B!(rt3I6;IcT*$?7m~s42VMGk>e;0$ZWfD0oB8ka{?ASyio)rqS km@ERsVZyd-JjafOMKZ8Rf0dSkO-KbmbMtX+bPh@VF9dal?EnA( literal 0 HcmV?d00001 diff --git a/template-web/public/favicon/favicon-96x96.png b/template-web/public/favicon/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..6cbdcfe045d1f965a79cc8a26ef3e9abcc7c6a1c GIT binary patch literal 6117 zcmZ{oc{J4T`~P3|v1G_HLX5pEv&cFa`&JCuN%l3{WXaB$OhlF}pNdUkl0>J+1 z749bhgdqUnmkR)(@&EvWEo`}}ei~qOyJDyZocyzj+sm>}Z+CDR%keY6)BrwL26|2lsUhq}$m%)xUt zPi){G3Qy+bl(>*854s`9#A&E4GSbz2hQA+!H~u27ou@^u$*qhc?mf*pu54*(MXjtW zc<-y0jqF%kFCTo{h+J>qXy1vIK_rT>xq@{0x;XCq|IZVtpXT6VwIQM(hwqR|{%oXA zKQOnuRxEU@4sn6#K~n#r&cT-y38n;+gz0yT4&#DSX2rHB!-kBDlxTwX4*k|LKlIGd zdq?&*dxRq+S%L(o-=W_ee9wKYfip1j94pet03Dxx6)=Ofa=>mL`XB zR~ttx>mmAoH+?IhkYTCJ_%3;QRPm0%kN`t2T@bedZQuFZ+#D%HLRVy!OBl;KD@6-o z#viPF7-z0-b6urW?6Kx(=_BY|*JfU7!VVo*%Zq(Hu+AYWVxZK?MY9fG>d1~@8(#t@ z<<5U~6RaQOaX-QqC_`%ElrniA*L3K`6hDWEzs_qv4+v@1UeY;Gr9&+}6(?*8b!?sqNfS+O)jgBgW{#{SKQ|pU>{dSSZJ5 zeSY~0-Q@=|UoP%m#r4v)DdtTw@Ks2|LB^xTF}b_d`Y#;bF{?=w$uArqb42UC{T547 z&l=W6VH1a=6Toy*ELMhn{Y-WucH)~^RlP5FrUUNTE|`)Eg~_3$W>|H{qr-&*e}n+- zSNNuwi`;#sN8~@cneVAH=i!C!;{5(g7I_{g7KrN5aR+-0ekhkdm7z&7St|HWK~72) zMsbR<&qLM33v)I3Er+0(`GcPiAYoz#-2SvVpg3qmXm=D9Q^+QKzLWB4Iots;x;jJG zZTN?!08Gn@bC>BdnS2v#L(#<7G46tO2cPi!E-Yi@8l^4Ra(#0mZ4p6Sf_0T9l{uZ( z;6NVwc)n&s%I`a!jfL}1W%iwu(e1ipzY6?E=+W$LPMH^H%b!n#XKp*<)EL5H4g*Vr zUfsiC3zW$b1>Q5HLbf(bZ2Hhe8u{yq#TYP=ZxTjs!V4Q6MjLJ7#Wux`F6a>*Baa=k zd=sfQ7=$Bj8<@|zY@&(fxWQ-pE%Fr{h5NpedMOR+xqB(U2{ghp^x)i>++J;zv&t%@ zn)U?IX?8o}edfW30Yo$X?yhtGY^z8z=U7`Beq!_qH)FAvVgZQBj3touMMQiK#89cr z7F<6O^FuZZQ{tcg)MKQlP)bD?(Wv%aMjyM9$Djm?6Fn3&_H+NX_9Me|QyKg>%~p_N zy)>%Gl9=ax7JCsZgn0f0Uvqy3A{QToV@f$UBCmVAgdWl29aa$IcQunqa$llZW*(uH z>?16%CmeqFX3T>4KR7J@(B4@e8*O=DkT!60Y~W4;kITG($raYpalycl!25@m7kI3m zu}-q9B0Ev!B|vk?@Rm~P{PQ?Rmp73){Y~0FE-D1n!gX#bf9OR1F73+V(^OIJjs~(m zr5hie7(Yv1r51jawVVBPLYvJZ?ecuM7Z(nQMc41URnLhuD|b#>B!rDci~-BD&IN%u z#%{g*hJ+BDaaTS@^ozBdRTR^UOJu{uc<63MCGcp~GTukLYdmEm>?5WJdc`0^Rw6Un83B$qf!H{U&*}f++PG;$jUuI0aC8W)?S}hB@s=plD$s#}y6TW8 za*6{~Rwc;b2@j18V{I5|%$|rmw7Crw(ID#wC=ff*~|%3*U>BvG7`)XlN7K zo#XhDvFR;z-cFmh)`$k%TYZ?`xK^V%D44UyKxHckVF=WEKK@5nP_R#ByBIxx>4>Da90FJs7y0 z?xp3CC^fL@KeY@pgCbdSCS7)zoney%v#9$L=7eEn~L8*WywI(L zUke8;W`6cmS3dABI>#F!`G_fjv*bf~ekmS0PFE;sf2)ht4a;X@H-jy>Z*Jb?JN5BMjh}wPdNTGk0_MK(Ny+H zo7UcaZF|l~kcJp%$N7bBb?;C%h<;u99!HxFLtP%T33$naG=_JrbQt@k7o+?nyTB`x z7fq`|tIpaCe9``UsdL(Y2$p3RVib1o+;zikwhxGO*@A93%hxB|Bn=JYL%wW~~c&MrQo4~K_pvP)?@8U2H zSaEDArJ|GJiyE$s;PKEpo>xe|$EcqNL`ywqK%v^Ep!cvpA1 ze$1u=33IO)PJcneMEM&16`@SczI$dcg~Ar7aIrqcn#510r*M-@7JTKUxTWSzk|uJG zuQS>62#r018Z=+U-lHJvo#9`l+pb4=tOV(tfnOM++0J*16)Bfyx8-tf{H)iGH5dIP ziT0gU?H&mQ4K@Ts=adQDfitq_stARou>AgLNpKe9lTougFOO0lla4yPeiV>JL6Tl~ znVFb${p}WaL~T?)u@*VJhqeR%{M+%~!u2JzrS$3dVVY|jMPnUdhX~F6vLlCk=WeSy zMO0E`=P!2E@e0YbmiSebS!CB+OG!;9F1Bt(9(mdYF_bqR@<+$O>}gpKN+~8@+&ruc zJQdz&h3&2eKJiR|oOtdZL!8x=+W&6WylF+cC)lz+XYt}qM>|EBBta+A6vNM!D{a1% z7OT|gpo0{@|CV3bVQS!Iz;SZxNY;V<4pm3#Y0nV~o;g{y5pBzE#!|mnM{zD5{e;U6VhiF0E`-s2I`2AxQPtn+&-?cp$vMmXh4GU5g7Drk(X+{(e{@$C zdsO2t_ayOK4p1wA6@at~!iFJsAn~+T_n9Rmmu+dBeU!Z`I0Jt@16>cylonQ#e|X$E zDyeA*(>EH&qNq(C&VrO=_ImgGs}J}%Ik#v|s$Vo^y9H;(YfRb@u?DS zJW4h`9@m<RJhC5Ii?b4L$#$vBc~k7d4d;q+g9Vx#)ukdgne!14pIK( zz1PkQkhuo+q!~m8Q(Vv@cGns_%@@qEj7$5kR7jkGHM)rd`0{!Ox%*eomcS_=N|%kE zT`IP^M6KzvO;#~@{5|?3>yz6*g6|R@@Y1M_M!1Pe!3w5-AM8Z={!HP~@l8&c1ECqz zuXCoOCfVXWn_&`8oMK;ZMwy9P)uALZWTqRs*W4R+noNZ%zw1zO*P!(|wdge*%r@u$k*nxyd;H_T|wVT!zow zOgnIX>#||r%BSdy4hsq2%f_21A9}nw?~ytjsd6-CV7p2X^1MztnPvtbtBbqx^7Fzq z(U8eW;f(_m0GCn6F~FruMw9tTjU!n%RkKS8a3EfuU^w@=aKlSWvOJ{ExHO6(sJv<3 zi9j@sOn>fO)GgBXIbGQ;-X=olVo#!8%hdhNJo7I*k#Bm!^5nLZFdpms{Y?7D+ROlU zilxK|mK?-d3t6q5NP<7VpGF3si#Pd0nJEZStgE0WJrpVX8`qaH*)c z&io(+Z#8gv{fm{K?ae6qZ453+GJrOke(!6{R5*ypiT&B^JoZbb-NmePF1uNLWwq`v?v@$3@?wK_x4 z6jev%&*Vm_F;`{KoWS~WFJN02HDUv{k3<3Pcn-E}^hC}$E%Gm{mE^gTduK4FJ@5G%2QY40bCK4t3m8?8fju|EqVGllTCH;Zlg6Nmc(SHao8tO9~_Gu zyOo4y)|PO5CH-z~I1-9xZDCR8kFZ=`6Z7;#8)J{AYw~BOs&nJYB85eWGV7pUZF~>D z?u_#Yse5t_&@F)kHSfjxb{gKAyPQscC`#Fe&gS%9vt9c#P>3${Z`C25{E3*aix;&rI;l1hj8w>Yk8QY} zN4063aa*NL&x8H~P$t@Kd_?)jt{mqamteub{2d*|Yc03NK=m{y3Y`S8q!p)yMpc1* ztTcDAUEo$NVV6o zfZMnZMi8XTC9^PlEm*%!0fJffEcXo->%dxj0P&nm)s2dwpRE#LykbFPqgXUesc9b^{3nebgG5} zRZUMcU{w#cC|da$^NK%Jd4@Cx^0~h#xA$elm(I#=n>VS44v72M_K?~rD8hru`61U8 z^vkQse(mAQ(#7!70s(qwt*@-FhNiFsB}>iM1m$UfIQ2z|zV+Lo<0h)#qz^th3^%8@ zAH5vVl~$Lm>xwT84MQc)Ev-dNL;HfGxsa+r5`Jku! z!gf~;FHo;~gv>%VOo9Uk;q#fS0Abc=Y6$B&P3^Fz4tMp+jA_Yu=$^mUS=Hv!Kpxco z8t^4{8VXjO;NzwRWb+SYF$9kKy)FH=m#@w>3cz1bEJza%j=9v7qkjyh#_$ziZWcP+ zZgDsE4nZahGafv`H8JG&!8S;;)~{>2<{(9y2ZzWjrMXgjh-CHR#3U&+vqhF$n@Kv6 zSIGKdTnGJe3;DB8qt{2b&%#bc3*As|fNU!jRQjR5@8mY6_qIm03Z$CHQDztUfg1dJ zU!3t70K8RQ0R!&(Z3a{(y2B>Q#F-vXRlM1(%Az^=r5VD90oa{2{*4e6JCG&8-R>1w ztaMhuv$#Y4OTPRcB{OsW1dwo8fsPp#)}4y25~2Ebp&qWGo+$TV&r=7;Bjgcs2n9K$ zf)!E$g-}3Ul9xdsPzb~UZ0uCm{Z~RjkcY2VO0z3mlQ7H3MGz37FowUOLi}_Da6w1fb*V`u)K&r}v zfndTZ1Nm2-|6y!>Jwko{LB^{^K&QyLe<7y60iL0eSWnMRtCE+SlB%l*LfJz}3F+qU>E`ODfbeqlyySuOQg(x#X24G8 UE0PWnIqd)#>tpn4bzJcO54>Ruq5uE@ literal 0 HcmV?d00001 diff --git a/template-web/src/App.css b/template-web/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/template-web/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/template-web/src/App.tsx b/template-web/src/App.tsx new file mode 100644 index 0000000..d739858 --- /dev/null +++ b/template-web/src/App.tsx @@ -0,0 +1,60 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import "./App.css"; + +import { Routes, Route } from "react-router-dom"; +import ErrorPage from "./routes/ErrorPage"; +import Layout from "./theme/LayoutMain"; +import Home from "./routes/home"; +import Substates from "./routes/substates"; + +export const breadcrumbRoutes = [ + { + label: "Home", + path: "/", + dynamic: false + }, + { + label: "Substates", + path: "/substates", + dynamic: false, + }, + { + label: "Error", + path: "*", + dynamic: false + } +]; +export default function App() { + return ( + <> + + }> + } /> + } /> + } /> + + + + ); +} diff --git a/template-web/src/assets/Logo.tsx b/template-web/src/assets/Logo.tsx new file mode 100644 index 0000000..4905b5c --- /dev/null +++ b/template-web/src/assets/Logo.tsx @@ -0,0 +1,33 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +interface LogoProps { + width?: string; + height?: string; + fill?: string; +} + +const Logo: React.FC = () => ( +

YOUR LOGO

+); + +export default Logo; diff --git a/template-web/src/assets/react.svg b/template-web/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/template-web/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/template-web/src/components/AlertDialog.tsx b/template-web/src/components/AlertDialog.tsx new file mode 100644 index 0000000..1f87832 --- /dev/null +++ b/template-web/src/components/AlertDialog.tsx @@ -0,0 +1,85 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { useState } from "react"; +import Button from "@mui/material/Button"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import DialogContentText from "@mui/material/DialogContentText"; +import DialogTitle from "@mui/material/DialogTitle"; + +interface AlertDialogProps { + buttonTitle?: string; + dialogTitle?: string; + dialogDescription?: string; + confirmTitle?: string; + confirmFunction?: any; + cancelTitle?: string; +} + +export function ConfirmDialog({ + buttonTitle, + dialogTitle, + dialogDescription, + confirmTitle, + confirmFunction, + cancelTitle, +}: AlertDialogProps) { + const [open, setOpen] = useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + confirmFunction(); + }; + + return ( +
+ + + {dialogTitle} + + {dialogDescription} + + + + + + +
+ ); +} diff --git a/template-web/src/components/Breadcrumbs.tsx b/template-web/src/components/Breadcrumbs.tsx new file mode 100644 index 0000000..51f5362 --- /dev/null +++ b/template-web/src/components/Breadcrumbs.tsx @@ -0,0 +1,67 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import React from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { Breadcrumbs, Link } from "@mui/material"; +import useBreadcrumbs from "use-react-router-breadcrumbs"; + +interface BreadcrumbsItem { + label: string; + path: string; + dynamic: boolean; +} + +interface BreadcrumbsProps { + items: BreadcrumbsItem[]; +} + +const BreadcrumbsComponent: React.FC = ({ items }) => { + const breadcrumbs = useBreadcrumbs(items); + + const links = breadcrumbs.map(({ match, breadcrumb }: any) => { + const breadcrumbLabel = breadcrumb.props.children; + const { label, path, dynamic } = match.route; + return ( + + {dynamic ? breadcrumbLabel.toLowerCase() : label} + + ); + }); + + return ( + <> + + {links} + + + ); +}; + +export default BreadcrumbsComponent; diff --git a/template-web/src/components/CallTemplateForm.tsx b/template-web/src/components/CallTemplateForm.tsx new file mode 100644 index 0000000..5a0b63f --- /dev/null +++ b/template-web/src/components/CallTemplateForm.tsx @@ -0,0 +1,175 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// import { useEffect, useState } from "react"; +import Button from "@mui/material/Button"; +import { FormLabel, TextField, Select, MenuItem } from "@mui/material"; +import { useState } from "react"; +import Grid from "@mui/material/Grid"; +import SecondaryHeading from "./SecondaryHeading.tsx"; +import { FunctionDef } from "@tariproject/wallet_jrpc_client"; + +interface Props { + func: FunctionDef; + onCall: (data: object) => void; + + badges: string[]; + selectedBadge: string | null; + onBadgeChange: (badge: string | null) => void; + components: string[]; + selectedComponent: string | null; + onComponentChange: (component: string | null) => void; +} + +function CallTemplateForm(props: Props) { + const { + func, + onCall, + badges, + selectedBadge, + onBadgeChange, + components, + selectedComponent, + onComponentChange + } = props; + const [data, setData] = useState({}); + + const isMethod = func.arguments[0]?.name == "self"; + const args = func.arguments.slice(isMethod ? 1 : 0); + + const hasComponents = components.length > 0; + + return ( + <> + +
{func.name} {isMethod ? "method" : "function"}
+
+
{ + evt.preventDefault(); + onCall(data); + }} + > + + {isMethod ? ( + <> + + + + + ) : ( + + )} + + {args.map((arg, i) => ( + setData({ ...data, [arg.name]: value })} + /> + ))} + + + + +
+ + ); +} + +const TemplateTextField = ({ + argName, + onChange, + disabled +}: { + argName: string; + onChange: (value: string) => void; + disabled?: boolean; +}) => { + return ( + <> + + {argName} + + + onChange(evt.target.value)} + /> + + + ); +}; + +const SelectField = ({ + name, + enableSelectNone, + value, + items, + onChange +}: { + name: string; + enableSelectNone?: boolean; + value: string | null; + items: string[]; + onChange: (value: string | null) => void; +}) => { + return ( + <> + + {name} + + + + + + ); +}; + +export default CallTemplateForm; diff --git a/template-web/src/components/CopyToClipboard.tsx b/template-web/src/components/CopyToClipboard.tsx new file mode 100644 index 0000000..611dcaf --- /dev/null +++ b/template-web/src/components/CopyToClipboard.tsx @@ -0,0 +1,66 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { useState } from "react"; +import Snackbar from "@mui/material/Snackbar"; +import IconButton from "@mui/material/IconButton"; +import ContentCopyIcon from "@mui/icons-material/ContentCopy"; +import Tooltip from "@mui/material/Tooltip"; + +interface CopyProps { + copy: string; +} + +const CopyToClipboard = ({ copy }: CopyProps) => { + const [open, setOpen] = useState(false); + const handleClick = (copyThis: string) => { + setOpen(true); + navigator.clipboard.writeText(copyThis); + }; + + return ( + <> + handleClick(copy)} + size="small" + aria-label="copy to clipboard" + style={{ + // float: 'right', + marginLeft: "10px", + }} + > + + + + + setOpen(false)} autoHideDuration={2000} message="Copied to clipboard" /> + + ); +}; + +export default CopyToClipboard; diff --git a/template-web/src/components/Copyright.tsx b/template-web/src/components/Copyright.tsx new file mode 100644 index 0000000..13e355d --- /dev/null +++ b/template-web/src/components/Copyright.tsx @@ -0,0 +1,38 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { Typography, Link } from "@mui/material"; + +const Copyright = () => { + return ( + + {"Copyright © "} + + Tari Labs + {" "} + {new Date().getFullYear()} + {"."} + + ); +}; + +export default Copyright; diff --git a/template-web/src/components/JsonTooltip.tsx b/template-web/src/components/JsonTooltip.tsx new file mode 100644 index 0000000..1c1a67c --- /dev/null +++ b/template-web/src/components/JsonTooltip.tsx @@ -0,0 +1,36 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import React from "react"; +import { renderJson } from "../utils/helpers"; + +export default function JsonTooltip({ jsonText, children }: { jsonText: string; children: string }) { + if (jsonText === null) { + return <>No data; + } + return ( +
+ {children} + {renderJson(JSON.parse(jsonText))} +
+ ); +} diff --git a/template-web/src/components/MenuItems.tsx b/template-web/src/components/MenuItems.tsx new file mode 100644 index 0000000..11884b8 --- /dev/null +++ b/template-web/src/components/MenuItems.tsx @@ -0,0 +1,96 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { NavLink } from "react-router-dom"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import { + IoHomeOutline, + IoHome, + IoBarChartOutline, + IoBarChart, + IoGitNetworkOutline, + IoGitNetwork, + IoImageOutline, + IoImage, + IoExtensionPuzzleOutline, + IoExtensionPuzzle +} from "react-icons/io5"; +import Tooltip from "@mui/material/Tooltip"; +import Fade from "@mui/material/Fade"; +import theme from "../theme/theme"; + +const iconStyle = { + height: 22, + width: 22 +}; + +const activeIconStyle = { + height: 22, + width: 22, + color: theme.palette.primary.main +}; + +const mainItems = [ + { + title: "Home", + icon: , + activeIcon: , + link: "/" + }, + { + title: "Substates", + icon: , + activeIcon: , + link: "/substates" + } +]; + +const MainMenu = mainItems.map(({ title, icon, activeIcon, link }) => { + return ( + + {({ isActive }) => ( + + + {isActive ? activeIcon : icon} + + + + )} + + ); +}); + +export const mainListItems = <>{MainMenu}; diff --git a/template-web/src/components/PageHeading.tsx b/template-web/src/components/PageHeading.tsx new file mode 100644 index 0000000..b448916 --- /dev/null +++ b/template-web/src/components/PageHeading.tsx @@ -0,0 +1,51 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import theme from "../theme/theme"; + +interface Props { + children: string; +} + +function PageHeading({ children }: Props) { + return ( +
+

{children}

+
+
+ ); +} + +export default PageHeading; diff --git a/template-web/src/components/SecondaryHeading.tsx b/template-web/src/components/SecondaryHeading.tsx new file mode 100644 index 0000000..ab6ac41 --- /dev/null +++ b/template-web/src/components/SecondaryHeading.tsx @@ -0,0 +1,51 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import theme from "../theme/theme"; + +interface Props { + children: React.ReactNode; +} + +function SecondaryHeading({ children }: Props) { + return ( +
+

{children}

+
+
+ ); +} + +export default SecondaryHeading; diff --git a/template-web/src/components/StyledComponents.ts b/template-web/src/components/StyledComponents.ts new file mode 100644 index 0000000..b32db65 --- /dev/null +++ b/template-web/src/components/StyledComponents.ts @@ -0,0 +1,79 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Paper from "@mui/material/Paper"; +import TableCell from "@mui/material/TableCell"; +import { styled } from "@mui/material/styles"; +import Box from "@mui/material/Box"; +import IconButton from "@mui/material/IconButton"; +import theme from "../theme/theme"; +import Typography from "@mui/material/Typography"; + +interface IAccordionIconButton { + open: boolean; +} + +export const AccordionIconButton = styled(IconButton)` + background-color: ${({ open }) => (open ? theme.palette.primary.main : "#fff")}; + color: ${({ open }) => (open ? "#fff" : theme.palette.primary.main)}; + &:hover { + background-color: ${theme.palette.primary.main}; + color: #fff; + } +`; + +export const StyledPaper = styled(Paper)(({ theme }) => ({ + padding: theme.spacing(3), + boxShadow: "10px 14px 28px rgba(35, 11, 73, 0.05)", +})); + +export const DataTableCell = styled(TableCell)(({ theme }) => ({ + fontFamily: "'Courier New', Courier, monospace", +})); + +export const CodeBlock = styled(Box)(({ theme }) => ({ + backgroundColor: "#F5F5F7", + borderRadius: theme.shape.borderRadius, + padding: theme.spacing(3), + maxHeight: "400px", + overflowY: "scroll", +})); + +export const BoxHeading = styled(Box)(({ theme }) => ({ + backgroundColor: "#fafafa", + borderRadius: theme.shape.borderRadius, + padding: theme.spacing(3), + fontFamily: "'Courier New', Courier, monospace", + boxShadow: "0px 5px 5px rgba(35, 11, 73, 0.10)", + margin: "10px 5px", +})); + +export const BoxHeading2 = styled(Box)(({ theme }) => ({ + padding: theme.spacing(2), + borderBottom: "1px solid #f5f5f5", +})); + +export const SubHeading = styled(Typography)(() => ({ + marginTop: "20px", + marginBottom: "20px", + textAlign: "center", +})); diff --git a/template-web/src/components/Title.tsx b/template-web/src/components/Title.tsx new file mode 100644 index 0000000..ae8f3b2 --- /dev/null +++ b/template-web/src/components/Title.tsx @@ -0,0 +1,36 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import * as React from "react"; +import Typography from "@mui/material/Typography"; + +interface TitleProps { + children?: React.ReactNode; +} + +export default function Title(props: TitleProps) { + return ( + + {props.children} + + ); +} diff --git a/template-web/src/connect/TariConnectButton.tsx b/template-web/src/connect/TariConnectButton.tsx new file mode 100644 index 0000000..af6d3b4 --- /dev/null +++ b/template-web/src/connect/TariConnectButton.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; + +import Button from "@mui/material/Button"; +import TariLogoWhite from './content/tari-logo-white.svg'; +import {TariWalletSelectionDialog} from './TariWalletSelectionDialog'; +import {useEffect} from "react"; +import {providers} from "@tariproject/tarijs"; +import useTariProvider from "../store/provider.ts"; +const {TariProvider} = providers; + +interface Props { + onConnected?: (provider: TariProvider) => void; +} + +export function TariConnectButton(props: Props) { + const {provider, setProvider} = useTariProvider(); + const {onConnected} = props; + const [walletSelectionOpen, setWalletSelectionOpen] = React.useState(false); + + const handleConnectClick = () => { + setWalletSelectionOpen(true); + }; + + const onWalletSelectionClose = () => { + setWalletSelectionOpen(false); + }; + + const handleOnConnected = (provider: TariProvider) => { + setProvider(provider); + onConnected?.(provider); + }; + + return ( + <> + + + + ); +} diff --git a/template-web/src/connect/TariWalletDaemonConnectDialog.module.css b/template-web/src/connect/TariWalletDaemonConnectDialog.module.css new file mode 100644 index 0000000..26671c0 --- /dev/null +++ b/template-web/src/connect/TariWalletDaemonConnectDialog.module.css @@ -0,0 +1,196 @@ +@font-face { + src: url('./assets/fonts/AvenirLTStd-Book.otf'); + font-family: 'AvenirRegular' +} + +@font-face { + src: url('./assets/fonts/AvenirLTStd-Medium.otf'); + font-family: 'AvenirMedium' +} + +@font-face { + src: url('./assets/fonts/AvenirLTStd-Heavy.otf'); + font-family: 'AvenirHeavy' +} + +@keyframes fadeIn { + 0% { opacity: 0; } + 100% { opacity: 1; } +} + +@keyframes fadeOut { + 0% { opacity: 1; } + 100% { opacity: 0; } +} + +.tariText { + font-family: 'AvenirMedium', sans-serif; + font-size: 14px; + color: #716A78; + line-height: 1.5; + text-align: center; +} + +.tariBtnContainer { + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + width: 100%; + flex-direction: column; +} + +.tariBtnContainer .tariBtn { + width: 100%; +} + +.tariBtn { + border: none; + padding: 10px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 14px; + cursor: pointer; + border-radius: 10px; + font-family: 'AvenirMedium', sans-serif; + height: 50px; +} + +.tariBtn:hover { + filter: brightness(90%); +} + +.tariPrimaryBtn { + background: #9330FF; + color: white; +} + +.tariSecondaryBtn { + background-color: #EDECEE; + color: #000000; +} + +.tariPopupBox { + position: fixed; + background: #00000050; + width: 100%; + height: 100vh; + top: 0; + left: 0; +} + +.tariBox { + position: relative; + width: 80%; + margin: 0 auto; + height: auto; + margin-top: calc(100vh - 85vh - 20px); + background: #fff; + border-radius: 10px; + padding: 10px; + border: 1px solid #EDECEE; + overflow: auto; + box-shadow: 0px 0px 40px rgba(0, 0, 0, 0.04); +} + +@media screen and (min-width: 400px) { + .tariBox { + width: 350px; + } + + .tariBtnContainer { + flex-direction: row; + } +} + +.tariFadeIn { + animation: fadeIn 0.5s; +} + +.tariFadeOut { + animation: fadeOut 0.5s; +} + +.tariPopupContainer { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 20px; + padding: 20px; +} + +.tariQr { + width: 100%; + height: auto; + box-shadow: 4px 4px 13px rgba(0, 0, 0, 0.097547); + border-radius: 10px; +} + +.tariLogo { + width: 95%; + height: auto; +} + +/* Checkmark */ + +.tariCheckmarkCircle { + stroke-dasharray: 166; + stroke-dashoffset: 166; + stroke-width: 2; + stroke-miterlimit: 10; + stroke: #FFFFFF; + fill: none; + animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards; +} + +.tariCheckmark { + width: 24px; + height: 24px; + border-radius: 50%; + display: block; + stroke-width: 4; + stroke: #9330FF; + stroke-miterlimit: 10; + box-shadow: inset 0px 0px 0px #FFFFFF; + animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both; + margin: 0 auto; +} + +.tariCheckmarkCheck { + transform-origin: 50% 50%; + stroke-dasharray: 48; + stroke-dashoffset: 48; + animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards; +} + +.tariCheckmarkContainer { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + gap: 10px; +} + +@keyframes stroke { + 100% { + stroke-dashoffset: 0 + } +} + +@keyframes scale { + 0%, + 100% { + transform: none + } + 50% { + transform: scale3d(1.1, 1.1, 1) + } +} + +@keyframes fill { + 100% { + box-shadow: inset 0px 0px 0px 30px #FFFFFF + } +} \ No newline at end of file diff --git a/template-web/src/connect/TariWalletDaemonConnectDialog.tsx b/template-web/src/connect/TariWalletDaemonConnectDialog.tsx new file mode 100644 index 0000000..2a6bbb8 --- /dev/null +++ b/template-web/src/connect/TariWalletDaemonConnectDialog.tsx @@ -0,0 +1,130 @@ +import Box from "@mui/material/Box"; +import Dialog from "@mui/material/Dialog"; +import Divider from "@mui/material/Divider"; +import Stack from "@mui/material/Stack"; +import CloseIcon from '@mui/icons-material/Close'; +import IconButton from "@mui/material/IconButton"; +import Typography from "@mui/material/Typography"; +import { QRCodeSVG } from "qrcode.react"; +import { useState, useEffect } from "react"; +import styles from './TariWalletDaemonConnectDialog.module.css'; +import {providers} from "@tariproject/tarijs"; + +const { WalletDaemonParameters, WalletDaemonTariProvider, TariPermissions } = providers.walletDaemon; + +export interface TariWalletDaemonConnectDialog { + open: boolean; + onClose: () => void; + onConnected: (provider: WalletDaemonTariProvider) => void; + signalingServerUrl: string; + permissions: TariPermissions; + optionalPermissions: TariPermissions; +} + +// TODO: hack, onConnection should ideally return the provider once it has connected +const providerHack = {provider: null as any}; + +export function TariWalletDaemonConnectDialog(props: TariWalletDaemonConnectDialog) { + const { onClose, open, onConnected } = props; + + const [isCopied, setIsCopied] = useState(false); + const [fadeClass, setFadeClass] = useState('tariFadeIn'); + const [tokenUrl, setTokenUrl] = useState(""); + + const onConnection = () => { + console.log("wallet daemon connected"); + onConnected(providerHack.provider); + handleClose(); + }; + + useEffect(() => { + if (open) { + setFadeClass('tariFadeIn'); + const params: WalletDaemonParameters = { + signalingServerUrl: props.signalingServerUrl, + permissions: props.permissions, + optionalPermissions: props.optionalPermissions, + onConnection, + }; + WalletDaemonTariProvider.build(params) + .then((provider) => { + if (provider.tokenUrl) { + setTokenUrl(provider.tokenUrl); + } + providerHack.provider = provider; + }); + } + }, [open]); + + const handleClose = () => { + onClose(); + }; + + const handleCopy = () => { + navigator.clipboard.writeText(tokenUrl); + setIsCopied(true); + setFadeClass(''); + setTimeout(() => { + setIsCopied(false); + }, 2000); + }; + + return ( + + + + Connect to your Tari Wallet Daemon + + + + + +
+

+ Scan the QR code or copy the link below to connect your wallet +

+ +
+ + +
+
+
+
+ ); +} + +const CheckMark = () => { + return ( + + + + + ); +}; diff --git a/template-web/src/connect/TariWalletSelectionDialog.tsx b/template-web/src/connect/TariWalletSelectionDialog.tsx new file mode 100644 index 0000000..13e99ae --- /dev/null +++ b/template-web/src/connect/TariWalletSelectionDialog.tsx @@ -0,0 +1,146 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import Dialog from "@mui/material/Dialog"; +import Divider from "@mui/material/Divider"; +import Stack from "@mui/material/Stack"; +import CloseIcon from "@mui/icons-material/Close"; +import IconButton from "@mui/material/IconButton"; +import Typography from "@mui/material/Typography"; +import TariLogo from "./content/tari-logo.svg"; +import MetamaskLogo from "./content/metamask-logo.svg"; +import Grid from "@mui/material/Grid"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { providers } from "@tariproject/tarijs"; +import { TariWalletDaemonConnectDialog } from "./TariWalletDaemonConnectDialog"; + +const { + walletDaemon: { + TariPermissionAccountInfo, + TariPermissionKeyList, + TariPermissionTransactionSend, + TariPermissions, + TariPermissionTransactionsGet, + TariPermissionSubstatesRead, + TariPermissionTemplatesRead, + }, + metamask: { MetamaskTariProvider }, + TariProvider, +} = providers; + +const SIGNALING_SERVER_URL = + import.meta.env.VITE_SIGNALING_SERVER_ADDRESS || "http://localhost:18005"; +const SNAP_ID = + import.meta.env.VITE_SNAP_ORIGIN || "local:http://localhost:8080"; + +// Minimal permissions for the example site +// But each application will have different permission needs +let walletDaemonPermissions = new TariPermissions(); +walletDaemonPermissions + // Required for createFreeTestCoins + .addPermission("Admin") + .addPermission(new TariPermissionKeyList()) + .addPermission(new TariPermissionAccountInfo()) + .addPermission(new TariPermissionTransactionsGet()) + .addPermission(new TariPermissionSubstatesRead()) + .addPermission(new TariPermissionTemplatesRead()) + .addPermission(new TariPermissionTransactionSend()); +let walletDaemonOptionalPermissions = new TariPermissions(); + +export interface WalletSelectionProps { + open: boolean; + onConnected: (provider: TariProvider) => void; + onClose: () => void; +} + +export function TariWalletSelectionDialog(props: WalletSelectionProps) { + const { onClose, open, onConnected } = props; + + const [walletDaemonOpen, setWalletDaemonOpen] = React.useState(false); + const handleClose = () => { + setWalletDaemonOpen(false); + onClose(); + }; + + const onWalletDaemonClick = () => { + setWalletDaemonOpen(true); + }; + + const onMetamaskClick = async () => { + const metamaskProvider = new MetamaskTariProvider(SNAP_ID, window.ethereum); + await metamaskProvider.connect(); + onConnected(metamaskProvider); + handleClose(); + }; + + return ( + + + + Connect a wallet + + + + + + + + + + + + + + + + + ); +} + +function WalletConnectionMethodCard({ img, text, callback }: any) { + return ( + + { + await callback(); + }} + > + + + + + {text} + + + + ); +} diff --git a/template-web/src/connect/content/metamask-logo.svg b/template-web/src/connect/content/metamask-logo.svg new file mode 100644 index 0000000..673c3f0 --- /dev/null +++ b/template-web/src/connect/content/metamask-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/template-web/src/connect/content/tari-logo-white.svg b/template-web/src/connect/content/tari-logo-white.svg new file mode 100644 index 0000000..82e0b4b --- /dev/null +++ b/template-web/src/connect/content/tari-logo-white.svg @@ -0,0 +1,18 @@ + + + node-icon + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/template-web/src/connect/content/tari-logo.svg b/template-web/src/connect/content/tari-logo.svg new file mode 100644 index 0000000..38947b1 --- /dev/null +++ b/template-web/src/connect/content/tari-logo.svg @@ -0,0 +1,18 @@ + + + node-icon + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/template-web/src/index.css b/template-web/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/template-web/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/template-web/src/main.tsx b/template-web/src/main.tsx new file mode 100644 index 0000000..283c64d --- /dev/null +++ b/template-web/src/main.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./theme/theme.css"; +import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import App from "./App"; +import ErrorPage from "./routes/ErrorPage"; +import Substates from "./routes/substates"; + +const router = createBrowserRouter([ + { + path: "*", + element: , + errorElement: , + children: [ + { + path: "substates", + element: , + } + ], + }, +]); + +const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); +root.render( + + + , +); + + +import {providers} from "@tariproject/tarijs"; + +declare global { + const {TariProvider, MetaMaskInpageProvider} = providers; + interface Window { + tari: TariProvider; + ethereum: MetaMaskInpageProvider; + } +} diff --git a/template-web/src/routes/ErrorPage.tsx b/template-web/src/routes/ErrorPage.tsx new file mode 100644 index 0000000..23f8052 --- /dev/null +++ b/template-web/src/routes/ErrorPage.tsx @@ -0,0 +1,59 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { useRouteError } from "react-router-dom"; +import { StyledPaper } from "../components/StyledComponents"; +import Typography from "@mui/material/Typography"; +import Grid from "@mui/material/Grid"; +import Container from "@mui/material/Container"; + +type ErrorType = { message: string } | { statusText: string } | string | null; + +export default function ErrorPage() { + const error = useRouteError() as ErrorType; + console.error(error); + + return ( +
+ + + + + Oops! + Sorry, an unexpected error has occurred. + + {error?.message || error?.statusText || error || "Unknown error"} + {" "} + + + + +
+ ); +} diff --git a/template-web/src/routes/home/Home.css b/template-web/src/routes/home/Home.css new file mode 100644 index 0000000..17dac42 --- /dev/null +++ b/template-web/src/routes/home/Home.css @@ -0,0 +1,169 @@ +.section { + padding: 5px 10px; + border-bottom: 1px solid black; +} + +.caption { + font-weight: bold; +} + +.validator-node { + display: grid; +} + +.key { + font-family: monospace; + font-size: large; + user-select: all; + margin-top: auto; + margin-bottom: auto; +} + +.committee-wrapper { + display: grid; + grid-template-columns: 200px auto; + justify-content: start; + align-items: start; + column-gap: 10px; + padding: 10px; +} + +.committee-range { + display: grid; + grid-template-columns: auto auto; + justify-content: start; + align-items: center; + column-gap: 10px; +} + +.committee { + display: grid; + justify-content: start; + justify-items: start; +} + +.range { + grid-column: 2; +} + +.bold { + font-weight: bold; +} + +.label { + padding: 5px; +} + +.vns { + display: grid; + grid-template-columns: auto auto auto auto; + justify-content: start; + align-items: start; + column-gap: 10px; + padding: 10px; +} + +.members { + display: grid; + grid-template-columns: auto auto; + column-gap: 10px; +} + +.button, +.disabled-button { + display: inline-block; + margin-right: auto; + padding: 6px 14px; + border: 1px solid black; + border-radius: 6px; + background-origin: border-box; + box-shadow: 3px 3px 2px grey; + user-select: none; + width: 150px; +} + +.disabled-button { + color: grey; + border: 1px solid grey; +} + +.button:hover { + box-shadow: 5px 5px 2px grey; +} +.button:active { + box-shadow: 1px 1px 2px grey; +} + +.error { + padding: 10px; + font-size: larger; + color: red; + font-weight: bold; +} + +.me { + font-weight: bold; +} + +table { + border-spacing: 10px 0; +} + +td { + text-align: center; +} + +th { + font-weight: bold; + user-select: none; +} + +.sort-indicator { + position: absolute; +} + +.tooltip { + position: relative; +} + +.tooltip .tooltiptext { + visibility: hidden; + /* width: 120px; */ + padding: 5px; + border-radius: 5px; + position: absolute; + z-index: 1; + background-color: white; + border: 1px solid black; +} + +.json { + text-align: left; +} + +.tooltip:hover { + text-decoration: underline; +} + +.tooltip:hover .tooltiptext { + visibility: visible; +} + +ol li, +ul li { + list-style-type: none; +} + +ol, +ul { + margin: 0px; + padding-inline-start: 20px; +} + +.string { + color: green; +} + +.other { + color: red; +} diff --git a/template-web/src/routes/home/Home.tsx b/template-web/src/routes/home/Home.tsx new file mode 100644 index 0000000..40ff44a --- /dev/null +++ b/template-web/src/routes/home/Home.tsx @@ -0,0 +1,272 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import "./Home.css"; +import {StyledPaper} from "../../components/StyledComponents"; +import Grid from "@mui/material/Grid"; +import SecondaryHeading from "../../components/SecondaryHeading"; +import {FinalizeResult, TemplateDef} from "@tariproject/wallet_jrpc_client"; +import {useState, useEffect, useContext} from "react"; +import SettingsForm, {Settings} from "./SettingsForm.tsx"; +import CallTemplateForm from "../../components/CallTemplateForm.tsx"; +import {Error} from "@mui/icons-material"; +import * as wallet from "../../wallet.ts"; +import {Alert, CircularProgress} from "@mui/material"; +import * as React from "react"; +import Button from "@mui/material/Button"; +import {providers} from "@tariproject/tarijs"; +import useSettings from "../../store/settings.ts"; +import useTariProvider from "../../store/provider.ts"; + +const {TariProvider} = providers; + +function loadSettings(): Settings { + const lsSettings = localStorage.getItem("settings"); + if (lsSettings) { + return JSON.parse(lsSettings); + } + + return { + template: "" + }; +} + +function Home() { + const {settings, setSettings} = useSettings(); + const {provider} = useTariProvider(); + + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [components, setComponents] = useState([]); + const [selectedComponent, setSelectedComponent] = useState( + null + ); + const [ + templateDefinition, + setTemplateDefinition + ] = useState(null); + const [badges, setBadges] = useState([]); + const [selectedBadge, setSelectedBadge] = useState(null); + const [lastResult, setLastResult] = useState<{ + index: number; + result: FinalizeResult | null; + } | null>(null); + + + const onSaveSettings = (settings: Settings) => { + localStorage.setItem("settings", JSON.stringify(settings)); + setSettings(settings); + } + + useEffect(() => { + if (!provider) { + return; + } + + const getTemplateDef = ((settings.template) + ? wallet.getTemplateDefinition(provider, settings.template) + : Promise.resolve(null) + ) + .then(setTemplateDefinition) + .catch(e => { + setError(e.message); + }); + + const getBadges = wallet.listSubstates(provider, null, "Resource") + .then(substates => { + setBadges( + // Best guess :/ + substates + .filter(s => !!s.substate_id.NonFungible) + .map(s => s.substate_id.NonFungible.resource_address) + ); + }) + .catch(e => { + setError(e.message); + }); + + const getComponents = (settings.template + ? wallet.listSubstates(provider, settings.template, "Component") + : Promise.resolve(null) + ) + .then(substates => { + if (substates?.length) { + setComponents( + substates + .filter(s => !!s.substate_id.Component) + .map(s => s.substate_id.Component) + ); + } else { + setComponents([]); + } + }) + .catch(e => { + setError(e.message); + }); + + Promise.allSettled([getBadges, getComponents, getTemplateDef]).then( + () => { + setIsLoading(false); + } + ); + }, [settings, provider]); + + useEffect(() => { + if (!selectedComponent) { + setSelectedComponent(components.length > 0 ? components[0] : null); + } + }, [components, selectedComponent]); + + if (!provider) { + return +
Please connect your wallet
+
; + } + + if (!settings || !settings.template) { + return +
Please add a template address to settings
+
; + } + + + console.log(templateDefinition); + + const forms = templateDefinition?.V1.functions.map((func, i) => { + return ( + <> + { + setLastResult({index: i, result: null}); + wallet.buildInstructionsAndSubmit( + provider, + settings, + selectedBadge, + selectedComponent, + func, + values + ) + .then(resp => { + setLastResult({index: i, result: resp.result as FinalizeResult}); + }) + .catch(e => { + setLastResult(null); + setError(e.message); + }); + }} + /> + {lastResult?.result && lastResult.index === i ? ( + + {lastResult.result.result.Accept ? ( + + Accept: +
{JSON.stringify(lastResult.result.result.Accept)}
+ {lastResult.result.execution_results + .filter(r => r.indexed.value !== "Null") + .map((r, i) => ( +

{JSON.stringify(r.indexed.value)}

+ ))} +
+ ) : lastResult.result.result.AcceptFeeRejectRest ? ( + + AcceptFeeRejectRest: Error calling function:{" "} + {JSON.stringify( + lastResult.result.result.AcceptFeeRejectRest[1] + )} + + ) : ( + + Error calling function:{" "} + {JSON.stringify(lastResult.result.result.Reject)} + + )} + + {lastResult.result.logs.map((log, j) => ( +

+ {log.level} {log.message} +

+ ))} +
+ ) : ( + lastResult?.index === i && + )} + + ); + }); + + return { + await wallet.createFreeTestCoins(provider) + }} setSettings={onSaveSettings}> + {isLoading ? : null} + {forms?.map((form, i) => ( + + {form} + + ))} + ; +} + + +interface LayoutProps { + error: string | null; + settings: Settings | null; + setSettings: (settings: Settings) => void; + onCreateFreeTestCoins?: () => void; + children: React.ReactNode; +} + +function HomeLayout({error, settings, setSettings, onCreateFreeTestCoins, children}: LayoutProps) { + return ( + <> + + Template + + + {error && ( + } severity="error"> + {error} + + )} + + {} + {settings ? : } + + + + + {children} + + + + ) +} + + +export default Home; diff --git a/template-web/src/routes/home/SettingsForm.tsx b/template-web/src/routes/home/SettingsForm.tsx new file mode 100644 index 0000000..3e415e7 --- /dev/null +++ b/template-web/src/routes/home/SettingsForm.tsx @@ -0,0 +1,76 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import "./Home.css"; +import Button from "@mui/material/Button"; +import {FormLabel, TextField} from "@mui/material"; +import {useState} from "react"; +import Grid from "@mui/material/Grid"; +import useSettings from "../../store/settings.ts"; + +interface Props { + settings: Settings | null; + onSave: (settings: Settings) => void; +} + +export interface Settings { + template: string | null; +} + + +function SettingsForm(props: Props) { + const {settings, setSettings} = useSettings(); + + const [currentSettings, setCurrentSettings] = useState(settings); + + return ( +
{ + evt.preventDefault(); + setSettings(currentSettings); + }} + > + + Template ID + + setCurrentSettings({ + ...currentSettings, + template: evt.target.value + }) + } + value={currentSettings.template || ""} + /> + + + + +
+ ); +} + +export default SettingsForm; diff --git a/template-web/src/routes/home/index.ts b/template-web/src/routes/home/index.ts new file mode 100644 index 0000000..fbe3fed --- /dev/null +++ b/template-web/src/routes/home/index.ts @@ -0,0 +1,3 @@ +import Home from './Home'; + +export default Home; diff --git a/template-web/src/routes/substates/Substates.css b/template-web/src/routes/substates/Substates.css new file mode 100644 index 0000000..17dac42 --- /dev/null +++ b/template-web/src/routes/substates/Substates.css @@ -0,0 +1,169 @@ +.section { + padding: 5px 10px; + border-bottom: 1px solid black; +} + +.caption { + font-weight: bold; +} + +.validator-node { + display: grid; +} + +.key { + font-family: monospace; + font-size: large; + user-select: all; + margin-top: auto; + margin-bottom: auto; +} + +.committee-wrapper { + display: grid; + grid-template-columns: 200px auto; + justify-content: start; + align-items: start; + column-gap: 10px; + padding: 10px; +} + +.committee-range { + display: grid; + grid-template-columns: auto auto; + justify-content: start; + align-items: center; + column-gap: 10px; +} + +.committee { + display: grid; + justify-content: start; + justify-items: start; +} + +.range { + grid-column: 2; +} + +.bold { + font-weight: bold; +} + +.label { + padding: 5px; +} + +.vns { + display: grid; + grid-template-columns: auto auto auto auto; + justify-content: start; + align-items: start; + column-gap: 10px; + padding: 10px; +} + +.members { + display: grid; + grid-template-columns: auto auto; + column-gap: 10px; +} + +.button, +.disabled-button { + display: inline-block; + margin-right: auto; + padding: 6px 14px; + border: 1px solid black; + border-radius: 6px; + background-origin: border-box; + box-shadow: 3px 3px 2px grey; + user-select: none; + width: 150px; +} + +.disabled-button { + color: grey; + border: 1px solid grey; +} + +.button:hover { + box-shadow: 5px 5px 2px grey; +} +.button:active { + box-shadow: 1px 1px 2px grey; +} + +.error { + padding: 10px; + font-size: larger; + color: red; + font-weight: bold; +} + +.me { + font-weight: bold; +} + +table { + border-spacing: 10px 0; +} + +td { + text-align: center; +} + +th { + font-weight: bold; + user-select: none; +} + +.sort-indicator { + position: absolute; +} + +.tooltip { + position: relative; +} + +.tooltip .tooltiptext { + visibility: hidden; + /* width: 120px; */ + padding: 5px; + border-radius: 5px; + position: absolute; + z-index: 1; + background-color: white; + border: 1px solid black; +} + +.json { + text-align: left; +} + +.tooltip:hover { + text-decoration: underline; +} + +.tooltip:hover .tooltiptext { + visibility: visible; +} + +ol li, +ul li { + list-style-type: none; +} + +ol, +ul { + margin: 0px; + padding-inline-start: 20px; +} + +.string { + color: green; +} + +.other { + color: red; +} diff --git a/template-web/src/routes/substates/Substates.tsx b/template-web/src/routes/substates/Substates.tsx new file mode 100644 index 0000000..fa473fa --- /dev/null +++ b/template-web/src/routes/substates/Substates.tsx @@ -0,0 +1,125 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import "./Substates.css"; +import {StyledPaper} from "../../components/StyledComponents"; +import Grid from "@mui/material/Grid"; +import SecondaryHeading from "../../components/SecondaryHeading"; +import {useState, useEffect} from "react"; +import {Error} from "@mui/icons-material"; +import {getSubstate, listSubstates} from "../../wallet.ts"; +import {Alert, CircularProgress} from "@mui/material"; +import {Settings} from "../home/SettingsForm.tsx"; + +import {SubstatesGetResponse} from "@tariproject/wallet_jrpc_client"; +import useTariProvider from "../../store/provider.ts"; +import useSettings from "../../store/settings.ts"; + +function Substates() { + const {provider} = useTariProvider(); + const {settings} = useSettings(); + + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [components, setComponents] = useState([]); + const [selectedComponent, setSelectedComponent] = useState( + null + ); + const [ + loadedComponent, + setLoadedComponent + ] = useState(null); + + useEffect(() => { + if (settings) { + listSubstates(provider, settings.template, "Component") + .then(substates => { + setComponents( + substates + .filter(s => !!s.substate_id.Component) + .map(s => s.substate_id.Component) + ); + setIsLoading(false); + }) + .catch(e => { + setError(e.message); + }); + } + }, [settings]); + + useEffect(() => { + if (selectedComponent && provider) { + getSubstate(provider, selectedComponent).then( + substate => { + // TODO: fix interface for tarijs + setLoadedComponent(substate as SubstatesGetResponse | null); + } + ); + } else { + setSelectedComponent(components.length > 0 ? components[0] : null); + } + }, [components, selectedComponent, settings, provider]); + + if (isLoading || !settings) { + return ( + <> + + Components + + + {error && ( + } severity="error"> + {error} + + )} + + + + + + + + + ); + } + return ( + <> + + Components + + + {error && ( + } severity="error"> + {error} + + )} + +
+            {loadedComponent && JSON.stringify(loadedComponent.value, null, 2)}
+          
+
+
+ + ); +} + +export default Substates; diff --git a/template-web/src/routes/substates/index.ts b/template-web/src/routes/substates/index.ts new file mode 100644 index 0000000..8e729ae --- /dev/null +++ b/template-web/src/routes/substates/index.ts @@ -0,0 +1,3 @@ +import Substates from "./Substates.tsx"; + +export default Substates; diff --git a/template-web/src/store/provider.ts b/template-web/src/store/provider.ts new file mode 100644 index 0000000..97c7a01 --- /dev/null +++ b/template-web/src/store/provider.ts @@ -0,0 +1,43 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import {create} from "zustand"; +import {providers} from "@tariproject/tarijs"; + +const {TariProvider} = providers; + +export interface ProviderStore { + provider: TProvider, + + setProvider(provider: TProvider); +} + +const useTariProvider = create>()( + (set) => ({ + provider: null, + setProvider(provider) { + set({provider}) + }, + }), +); + +export default useTariProvider; diff --git a/template-web/src/store/settings.ts b/template-web/src/store/settings.ts new file mode 100644 index 0000000..73bac3b --- /dev/null +++ b/template-web/src/store/settings.ts @@ -0,0 +1,48 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import {create} from "zustand"; +import {createJSONStorage, persist} from "zustand/middleware"; + +export interface Settings { + template: string | null; +} + +export interface SettingsStore { + settings: Settings, + setSettings(settings: object); +} + +const useSettings = create()( + persist( + (set) => ({ + settings: {template: null}, + setSettings(settings) { set({settings}) }, + }), + { + name: "settings", + storage: createJSONStorage(() => localStorage), + }, + ), +); + +export default useSettings; diff --git a/template-web/src/theme/LayoutMain.tsx b/template-web/src/theme/LayoutMain.tsx new file mode 100644 index 0000000..72dca3b --- /dev/null +++ b/template-web/src/theme/LayoutMain.tsx @@ -0,0 +1,195 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import {useState} from "react"; +import {styled} from "@mui/material/styles"; +import CssBaseline from "@mui/material/CssBaseline"; +import MuiDrawer from "@mui/material/Drawer"; +import Box from "@mui/material/Box"; +import MuiAppBar, {AppBarProps as MuiAppBarProps} from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; +import List from "@mui/material/List"; +import IconButton from "@mui/material/IconButton"; +import MenuOpenOutlinedIcon from "@mui/icons-material/MenuOpenOutlined"; +import MenuOutlinedIcon from "@mui/icons-material/MenuOutlined"; +import {mainListItems} from "../components/MenuItems"; +import {ThemeProvider} from "@mui/material"; +import theme from "./theme"; +import {Outlet, Link} from "react-router-dom"; +import Logo from "../assets/Logo"; +import Container from "@mui/material/Container"; +import Breadcrumbs from "../components/Breadcrumbs"; +import {breadcrumbRoutes} from "../App"; +import Grid from "@mui/material/Grid"; +import {TariConnectButton} from "../connect/TariConnectButton.tsx"; + +const drawerWidth = 300; + +interface AppBarProps extends MuiAppBarProps { + open?: boolean; +} + +const AppBar = styled(MuiAppBar, { + shouldForwardProp: (prop) => prop !== "open", +})(({theme, open}) => ({ + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + ...(open && { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + }), +})); + +const Drawer = styled(MuiDrawer, { + shouldForwardProp: (prop) => prop !== "open", +})(({theme, open}) => ({ + "& .MuiDrawer-paper": { + position: "relative", + whiteSpace: "nowrap", + borderRight: "1px solid #F5F5F5", + boxShadow: "10px 14px 28px rgb(35 11 73 / 5%)", + width: drawerWidth, + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + boxSizing: "border-box", + ...(!open && { + overflowX: "hidden", + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.leavingScreen, + }), + width: theme.spacing(7), + [theme.breakpoints.up("sm")]: { + width: theme.spacing(9), + }, + }), + }, +})); + +export default function Layout() { + const [open, setOpen] = useState(false); + + const toggleDrawer = () => { + setOpen(!open); + }; + return ( + + + + + + + + + + + + + + + + + + + + + {mainListItems} + + + theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[900], + flexGrow: 1, + height: "100vh", + overflow: "auto", + }} + > + + + + +
+ +
+
+ +
+
+
+
+
+ ); +} diff --git a/template-web/src/theme/fonts/AvenirLTStd-Book.otf b/template-web/src/theme/fonts/AvenirLTStd-Book.otf new file mode 100644 index 0000000000000000000000000000000000000000..6117f64c53fa09c35a0ff95f16e8ab58953c4f95 GIT binary patch literal 28288 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 X+z^_BsnNoJpOIr0=_f8}BO>xIt}3c1 literal 0 HcmV?d00001 diff --git a/template-web/src/theme/fonts/AvenirLTStd-Heavy.otf b/template-web/src/theme/fonts/AvenirLTStd-Heavy.otf new file mode 100644 index 0000000000000000000000000000000000000000..24cced143da7e9fafaf8bf39eb385c5075932be2 GIT binary patch literal 28508 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 u4!tyU!FwzhJ literal 0 HcmV?d00001 diff --git a/template-web/src/theme/fonts/AvenirLTStd-Medium.otf b/template-web/src/theme/fonts/AvenirLTStd-Medium.otf new file mode 100644 index 0000000000000000000000000000000000000000..e902718152796a3b42299408775f8b1f21eecd1a GIT binary patch literal 28132 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 * { + width: 100%; + } +} + +@media screen and (min-width: 768px) { + .add-confirm-form { + flex-direction: row; + } + .flex-container { + flex-direction: row; + } +} diff --git a/template-web/src/theme/theme.ts b/template-web/src/theme/theme.ts new file mode 100644 index 0000000..fa9270a --- /dev/null +++ b/template-web/src/theme/theme.ts @@ -0,0 +1,102 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { createTheme } from "@mui/material/styles"; + +const theme = createTheme({ + palette: { + primary: { + main: "#9330FF", + }, + secondary: { + main: "#40388A", + }, + }, + shape: { + borderRadius: 10, + }, + typography: { + fontFamily: '"AvenirMedium", sans-serif', + body1: { + color: "#000000", + }, + body2: { + color: "#000000", + lineHeight: "1.5rem", + }, + h1: { + fontSize: "2.2rem", + lineHeight: "3.2rem", + }, + h2: { + fontSize: "1.9rem", + lineHeight: "2.9rem", + }, + h3: { + fontSize: "1.6rem", + lineHeight: "2.6rem", + }, + h4: { + fontSize: "1.3rem", + lineHeight: "2.3rem", + }, + h5: { + fontSize: "1rem", + lineHeight: "2em", + }, + h6: { + fontSize: "0.875rem", + lineHeight: "1.8rem", + }, + }, + transitions: { + duration: { + enteringScreen: 500, + leavingScreen: 500, + }, + }, + components: { + MuiButton: { + defaultProps: { + disableRipple: true, + sx: { + minHeight: "55px", + boxShadow: "none", + textTransform: "none", + fontSize: "1rem", + fontWeight: 500, + fontFamily: '"AvenirMedium", sans-serif', + letterSpacing: "0.5px", + }, + }, + }, + MuiTableCell: { + defaultProps: { + sx: { + borderBottom: "1px solid #f5f5f5", + }, + }, + }, + }, +}); + +export default theme; diff --git a/template-web/src/vite-env.d.ts b/template-web/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/template-web/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/template-web/src/wallet.ts b/template-web/src/wallet.ts new file mode 100644 index 0000000..559e610 --- /dev/null +++ b/template-web/src/wallet.ts @@ -0,0 +1,238 @@ +import {Settings} from "./routes/home/SettingsForm.tsx"; + +import { + FunctionDef, + SubstatesListRequest, + SubstatesGetRequest, + TransactionGetResultResponse, + Instruction, + SubstateType, + SubstateId, + Arg, + WalletDaemonClient, +} from "@tariproject/wallet_jrpc_client"; + + +import {providers} from '@tariproject/tarijs'; +import {TariProvider} from "@tariproject/tarijs/dist/providers"; + +const { + TariProvider, + metamask: {MetamaskTariProvider}, + walletDaemon: {WalletDaemonTariProvider}, + types: { + SubstateRequirement, + TransactionSubmitRequest, + TransactionStatus + } +} = providers; + +function createClient(url: string) { + return WalletDaemonClient.usingFetchTransport(url); +} + +export async function getTemplateDefinition( + provider: T, + template_address: string +) { + const resp = await provider.getTemplateDefinition(template_address); + return resp.template_definition; +} + +export async function listSubstates( + provider: T, + template: string | null, + substateType: SubstateType | null +) { + if (provider.providerName !== "WalletDaemon") { + throw new Error(`Unsupported provider ${provider.providerName}`); + } + const substates = await (provider as WalletDaemonTariProvider).listSubstates( + template, + substateType + ); + return substates; +} + +export async function createFreeTestCoins(provider: T) { + console.log("createFreeTestCoins", provider.providerName); + switch (provider.providerName) { + case "WalletDaemon": + const walletProvider = provider as WalletDaemonTariProvider; + await walletProvider.createFreeTestCoins(); + break; + case "Metamask": + const metamaskProvider = provider as MetamaskTariProvider; + await metamaskProvider.createFreeTestCoins(0); + break; + default: + throw new Error(`Unsupported provider: ${provider.providerName}`); + } +} + +export async function getSubstate(provider: T, substateId: string) { + const resp = await provider.getSubstate(substateId); + return resp; +} + +async function authorizeClient(client: WalletDaemonClient) { + // TODO: keep this token in local storage + const token = await client.authRequest(["Admin"]); + await client.authAccept(token, "web"); +} + +export async function buildInstructionsAndSubmit( + provider: TariProvider, + settings: Settings, + selectedBadge: string | null, + selectedComponent: string | null, + func: FunctionDef, + args: object +) { + const req = await createTransactionRequest( + provider, + settings, + selectedBadge, + selectedComponent, + func, + args + ); + + const resp = await provider.submitTransaction(req); + + let result = await waitForTransactionResult(provider, resp.transaction_id); + + return result; +} + +async function waitForTransactionResult(provider: TariProvider, transactionId: string) { + while (true) { + const resp = await provider.getTransactionResult(transactionId); + const FINALIZED_STATUSES = [ + TransactionStatus.Accepted, + TransactionStatus.Rejected, + TransactionStatus.InvalidTransaction, + TransactionStatus.OnlyFeeAccepted, + TransactionStatus.DryRun + ]; + + if (resp.status == TransactionStatus.Rejected) { + throw new Error(`Transaction rejected: ${JSON.stringify(resp.result)}`); + } + + if (FINALIZED_STATUSES.includes(resp.status)) { + return resp; + } + await new Promise(resolve => setTimeout(resolve, 1000)); + } +} + +export async function createTransactionRequest( + provider: TariProvider, + settings: Settings, + selectedBadge: string | null, + selectedComponent: string | null, + func: FunctionDef, + formValues: object +): Promise { + const fee = 2000; + const account = await provider.getAccount(); + + const fee_instructions = [ + { + CallMethod: { + component_address: account.address, + method: "pay_fee", + args: [`Amount(${fee})`] + } + } + ]; + + const args = Object.values(formValues) as Arg[]; + const isMethod = + func.arguments.length > 0 && func.arguments[0].name === "self"; + + if (!isMethod && !settings.template) { + throw new Error("Template not set"); + } + + if (isMethod && !selectedComponent) { + throw new Error("This call requires a component to be selected"); + } + + let bucketId = 0; + + const proofInstructions: Instruction[] = + isMethod && selectedBadge + ? [ + { + CallMethod: { + component_address: account.address, + method: "create_proof_for_resource", + args: [selectedBadge] + } + }, + { + PutLastInstructionOutputOnWorkspace: {key: [bucketId++]} + } + ] as Instruction[] + : []; + + const callInstruction = isMethod + ? { + CallMethod: { + component_address: selectedComponent, + method: func.name, + args: args + } + } as Instruction + : { + CallFunction: { + template_address: settings.template, + function: func.name, + args: args + } + } as Instruction; + + const nextInstructions: Instruction[] = + func.output.Other?.name === "Bucket" + ? [ + {PutLastInstructionOutputOnWorkspace: {key: [bucketId]}}, + { + CallMethod: { + component_address: account.address, + method: "deposit", + args: [{Workspace: [bucketId]}] + } + } + ] as Instruction[] + : []; + + const instructions: Instruction[] = [ + ...proofInstructions, + callInstruction, + ...nextInstructions, + "DropAllProofsInWorkspace" as Instruction + ]; + + const required_substates = [ + {substate_id: account.address, version: null} + ] + + if (selectedComponent) { + required_substates.push({substate_id: selectedComponent, version: null}); + } + + return { + account_id: account.account_id, + fee_instructions, + instructions, + inputs: [], + input_refs: [], + override_inputs: false, + required_substates, + is_dry_run: false, + min_epoch: null, + max_epoch: null + }; +} diff --git a/template-web/tsconfig.json b/template-web/tsconfig.json new file mode 100644 index 0000000..a7fc6fb --- /dev/null +++ b/template-web/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/template-web/tsconfig.node.json b/template-web/tsconfig.node.json new file mode 100644 index 0000000..97ede7e --- /dev/null +++ b/template-web/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/template-web/vite.config.ts b/template-web/vite.config.ts new file mode 100644 index 0000000..861b04b --- /dev/null +++ b/template-web/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/template_web.py b/template_web.py new file mode 100644 index 0000000..1a3af01 --- /dev/null +++ b/template_web.py @@ -0,0 +1,23 @@ +from Common.config import DATA_FOLDER, TEMPLATE_WEB_PORT +from Processes.common_exec import CommonExec +from Processes.subprocess_wrapper import SubprocessWrapper +import subprocess + + +class TemplateWebServer(CommonExec): + def __init__(self, signaling_server_address: str): + super().__init__("template-web") + SubprocessWrapper.call( + ["npm", "install"], + stdin=subprocess.PIPE, + stdout=open(f"{DATA_FOLDER}/stdout/template-web_install.log", "a+"), + stderr=subprocess.STDOUT, + cwd="template-web", + ) + if TEMPLATE_WEB_PORT == "auto": + self.http_port = self.get_port("HTTP") + else: + self.http_port = int(TEMPLATE_WEB_PORT) + self.exec = ["npm", "--prefix", "template-web", "run", "dev", "--", "--port", str(self.http_port), "--host", "0.0.0.0"] + self.env["VITE_SIGNALING_SERVER_ADDRESS"] = signaling_server_address + self.run() diff --git a/webui/src/App.css b/webui/src/App.css index 2be85c4..8e4a31d 100644 --- a/webui/src/App.css +++ b/webui/src/App.css @@ -27,7 +27,12 @@ padding: 10px; } -.info * { +#templates { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; } .infos { diff --git a/webui/src/routes/Main.tsx b/webui/src/routes/Main.tsx index 176cfaf..02b2901 100644 --- a/webui/src/routes/Main.tsx +++ b/webui/src/routes/Main.tsx @@ -9,6 +9,7 @@ enum Executable { Indexer = 5, DanWallet = 6, Templates = 7, + TemplateWeb = 8, } async function jsonRpc2(address: string, method: string, params: any = null) { @@ -378,6 +379,7 @@ export default function Main() { const [logs, setLogs] = useState({}); const [stdoutLogs, setStdoutLogs] = useState({}); const [connectorSample, setConnectorSample] = useState(null); + const [templateWeb, setTemplateWeb] = useState(null); const [selectedFile, setSelectedFile] = useState(null); const [showLogs, setShowLogs] = useState(false); const [autoRefresh, setAutoRefresh] = useState(true); @@ -413,6 +415,9 @@ export default function Main() { jsonRpc("http", "TariConnector") .then((resp) => setConnectorSample(resp)) .catch((error) => console.log(error)); + jsonRpc("http", "TemplateWeb") + .then((resp) => setTemplateWeb(resp)) + .catch((error) => console.log(error)); getLogs("miner"); getStdout("miner"); }, []); @@ -513,7 +518,15 @@ export default function Main() { + {templateWeb && ( + + + + )} + {connectorSample && (