diff options
33 files changed, 2493 insertions, 0 deletions
diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..9246d7e --- /dev/null +++ b/.github/workflows/python-publish.yml | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | name: Release | ||
| 2 | |||
| 3 | on: | ||
| 4 | push: | ||
| 5 | tags: | ||
| 6 | - 'v*' | ||
| 7 | pull_request: | ||
| 8 | branches: | ||
| 9 | - 'main' | ||
| 10 | |||
| 11 | jobs: | ||
| 12 | deploy: | ||
| 13 | runs-on: ubuntu-latest | ||
| 14 | steps: | ||
| 15 | - uses: actions/checkout@v2 | ||
| 16 | - name: Set up Python | ||
| 17 | uses: actions/setup-python@v2 | ||
| 18 | with: | ||
| 19 | python-version: '3.10' | ||
| 20 | - name: Set up Node | ||
| 21 | uses: actions/setup-node@v2 | ||
| 22 | with: | ||
| 23 | node-version: '16' | ||
| 24 | - name: Install node dependencies | ||
| 25 | run: | | ||
| 26 | yarn install | ||
| 27 | - name: Install python dependencies | ||
| 28 | run: | | ||
| 29 | python -m pip install --upgrade pip | ||
| 30 | pip install build | ||
| 31 | - name: Build package | ||
| 32 | run: | | ||
| 33 | yarn build | ||
| 34 | python -m build | ||
| 35 | - name: Publish package | ||
| 36 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 | ||
| 37 | if: github.event_name != 'pull_request' | ||
| 38 | with: | ||
| 39 | user: __token__ | ||
| 40 | password: ${{ secrets.PYPI_API_TOKEN }} | ||
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3e66e6 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | |||
| 2 | # Created by https://www.toptal.com/developers/gitignore/api/python,react,pycharm+all,yarn | ||
| 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python,react,pycharm+all,yarn | ||
| 4 | |||
| 5 | ### PyCharm+all ### | ||
| 6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider | ||
| 7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
| 8 | |||
| 9 | # User-specific stuff | ||
| 10 | .idea/**/workspace.xml | ||
| 11 | .idea/**/tasks.xml | ||
| 12 | .idea/**/usage.statistics.xml | ||
| 13 | .idea/**/dictionaries | ||
| 14 | .idea/**/shelf | ||
| 15 | |||
| 16 | # AWS User-specific | ||
| 17 | .idea/**/aws.xml | ||
| 18 | |||
| 19 | # Generated files | ||
| 20 | .idea/**/contentModel.xml | ||
| 21 | |||
| 22 | # Sensitive or high-churn files | ||
| 23 | .idea/**/dataSources/ | ||
| 24 | .idea/**/dataSources.ids | ||
| 25 | .idea/**/dataSources.local.xml | ||
| 26 | .idea/**/sqlDataSources.xml | ||
| 27 | .idea/**/dynamic.xml | ||
| 28 | .idea/**/uiDesigner.xml | ||
| 29 | .idea/**/dbnavigator.xml | ||
| 30 | |||
| 31 | # Gradle | ||
| 32 | .idea/**/gradle.xml | ||
| 33 | .idea/**/libraries | ||
| 34 | |||
| 35 | # Gradle and Maven with auto-import | ||
| 36 | # When using Gradle or Maven with auto-import, you should exclude module files, | ||
| 37 | # since they will be recreated, and may cause churn. Uncomment if using | ||
| 38 | # auto-import. | ||
| 39 | # .idea/artifacts | ||
| 40 | # .idea/compiler.xml | ||
| 41 | # .idea/jarRepositories.xml | ||
| 42 | # .idea/modules.xml | ||
| 43 | # .idea/*.iml | ||
| 44 | # .idea/modules | ||
| 45 | # *.iml | ||
| 46 | # *.ipr | ||
| 47 | |||
| 48 | # CMake | ||
| 49 | cmake-build-*/ | ||
| 50 | |||
| 51 | # Mongo Explorer plugin | ||
| 52 | .idea/**/mongoSettings.xml | ||
| 53 | |||
| 54 | # File-based project format | ||
| 55 | *.iws | ||
| 56 | |||
| 57 | # IntelliJ | ||
| 58 | out/ | ||
| 59 | |||
| 60 | # mpeltonen/sbt-idea plugin | ||
| 61 | .idea_modules/ | ||
| 62 | |||
| 63 | # JIRA plugin | ||
| 64 | atlassian-ide-plugin.xml | ||
| 65 | |||
| 66 | # Cursive Clojure plugin | ||
| 67 | .idea/replstate.xml | ||
| 68 | |||
| 69 | # Crashlytics plugin (for Android Studio and IntelliJ) | ||
| 70 | com_crashlytics_export_strings.xml | ||
| 71 | crashlytics.properties | ||
| 72 | crashlytics-build.properties | ||
| 73 | fabric.properties | ||
| 74 | |||
| 75 | # Editor-based Rest Client | ||
| 76 | .idea/httpRequests | ||
| 77 | |||
| 78 | # Android studio 3.1+ serialized cache file | ||
| 79 | .idea/caches/build_file_checksums.ser | ||
| 80 | |||
| 81 | ### PyCharm+all Patch ### | ||
| 82 | # Ignores the whole .idea folder and all .iml files | ||
| 83 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 | ||
| 84 | |||
| 85 | .idea/ | ||
| 86 | |||
| 87 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 | ||
| 88 | |||
| 89 | *.iml | ||
| 90 | modules.xml | ||
| 91 | .idea/misc.xml | ||
| 92 | *.ipr | ||
| 93 | |||
| 94 | # Sonarlint plugin | ||
| 95 | .idea/sonarlint | ||
| 96 | |||
| 97 | ### Python ### | ||
| 98 | # Byte-compiled / optimized / DLL files | ||
| 99 | __pycache__/ | ||
| 100 | *.py[cod] | ||
| 101 | *$py.class | ||
| 102 | |||
| 103 | # C extensions | ||
| 104 | *.so | ||
| 105 | |||
| 106 | # Distribution / packaging | ||
| 107 | .Python | ||
| 108 | build/ | ||
| 109 | develop-eggs/ | ||
| 110 | dist/ | ||
| 111 | downloads/ | ||
| 112 | eggs/ | ||
| 113 | .eggs/ | ||
| 114 | lib/ | ||
| 115 | lib64/ | ||
| 116 | parts/ | ||
| 117 | sdist/ | ||
| 118 | var/ | ||
| 119 | wheels/ | ||
| 120 | share/python-wheels/ | ||
| 121 | *.egg-info/ | ||
| 122 | .installed.cfg | ||
| 123 | *.egg | ||
| 124 | MANIFEST | ||
| 125 | |||
| 126 | # PyInstaller | ||
| 127 | # Usually these files are written by a python script from a template | ||
| 128 | # before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
| 129 | *.manifest | ||
| 130 | *.spec | ||
| 131 | |||
| 132 | # Installer logs | ||
| 133 | pip-log.txt | ||
| 134 | pip-delete-this-directory.txt | ||
| 135 | |||
| 136 | # Unit test / coverage reports | ||
| 137 | htmlcov/ | ||
| 138 | .tox/ | ||
| 139 | .nox/ | ||
| 140 | .coverage | ||
| 141 | .coverage.* | ||
| 142 | .cache | ||
| 143 | nosetests.xml | ||
| 144 | coverage.xml | ||
| 145 | *.cover | ||
| 146 | *.py,cover | ||
| 147 | .hypothesis/ | ||
| 148 | .pytest_cache/ | ||
| 149 | cover/ | ||
| 150 | |||
| 151 | # Translations | ||
| 152 | *.mo | ||
| 153 | *.pot | ||
| 154 | |||
| 155 | # Django stuff: | ||
| 156 | *.log | ||
| 157 | local_settings.py | ||
| 158 | db.sqlite3 | ||
| 159 | db.sqlite3-journal | ||
| 160 | |||
| 161 | # Flask stuff: | ||
| 162 | instance/ | ||
| 163 | .webassets-cache | ||
| 164 | |||
| 165 | # Scrapy stuff: | ||
| 166 | .scrapy | ||
| 167 | |||
| 168 | # Sphinx documentation | ||
| 169 | docs/_build/ | ||
| 170 | |||
| 171 | # PyBuilder | ||
| 172 | .pybuilder/ | ||
| 173 | target/ | ||
| 174 | |||
| 175 | # Jupyter Notebook | ||
| 176 | .ipynb_checkpoints | ||
| 177 | |||
| 178 | # IPython | ||
| 179 | profile_default/ | ||
| 180 | ipython_config.py | ||
| 181 | |||
| 182 | # pyenv | ||
| 183 | # For a library or package, you might want to ignore these files since the code is | ||
| 184 | # intended to run in multiple environments; otherwise, check them in: | ||
| 185 | # .python-version | ||
| 186 | |||
| 187 | # pipenv | ||
| 188 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
| 189 | # However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
| 190 | # having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
| 191 | # install all needed dependencies. | ||
| 192 | #Pipfile.lock | ||
| 193 | |||
| 194 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow | ||
| 195 | __pypackages__/ | ||
| 196 | |||
| 197 | # Celery stuff | ||
| 198 | celerybeat-schedule | ||
| 199 | celerybeat.pid | ||
| 200 | |||
| 201 | # SageMath parsed files | ||
| 202 | *.sage.py | ||
| 203 | |||
| 204 | # Environments | ||
| 205 | .env | ||
| 206 | .venv | ||
| 207 | env/ | ||
| 208 | venv/ | ||
| 209 | ENV/ | ||
| 210 | env.bak/ | ||
| 211 | venv.bak/ | ||
| 212 | |||
| 213 | # Spyder project settings | ||
| 214 | .spyderproject | ||
| 215 | .spyproject | ||
| 216 | |||
| 217 | # Rope project settings | ||
| 218 | .ropeproject | ||
| 219 | |||
| 220 | # mkdocs documentation | ||
| 221 | /site | ||
| 222 | |||
| 223 | # mypy | ||
| 224 | .mypy_cache/ | ||
| 225 | .dmypy.json | ||
| 226 | dmypy.json | ||
| 227 | |||
| 228 | # Pyre type checker | ||
| 229 | .pyre/ | ||
| 230 | |||
| 231 | # pytype static type analyzer | ||
| 232 | .pytype/ | ||
| 233 | |||
| 234 | # Cython debug symbols | ||
| 235 | cython_debug/ | ||
| 236 | |||
| 237 | ### react ### | ||
| 238 | .DS_* | ||
| 239 | logs | ||
| 240 | **/*.backup.* | ||
| 241 | **/*.back.* | ||
| 242 | |||
| 243 | node_modules | ||
| 244 | bower_components | ||
| 245 | |||
| 246 | *.sublime* | ||
| 247 | |||
| 248 | psd | ||
| 249 | thumb | ||
| 250 | sketch | ||
| 251 | |||
| 252 | ### yarn ### | ||
| 253 | # https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored | ||
| 254 | |||
| 255 | .yarn/* | ||
| 256 | !.yarn/releases | ||
| 257 | !.yarn/plugins | ||
| 258 | !.yarn/sdks | ||
| 259 | !.yarn/versions | ||
| 260 | |||
| 261 | # if you are NOT using Zero-installs, then: | ||
| 262 | # comment the following lines | ||
| 263 | !.yarn/cache | ||
| 264 | |||
| 265 | # and uncomment the following lines | ||
| 266 | # .pnp.* | ||
| 267 | |||
| 268 | # End of https://www.toptal.com/developers/gitignore/api/python,react,pycharm+all,yarn | ||
| 269 | |||
| 270 | dist | ||
| 271 | ttun/staticfiles | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | BSD 3-Clause License | ||
| 2 | |||
| 3 | Copyright (c) 2022, Tom van der Lee | ||
| 4 | All rights reserved. | ||
| 5 | |||
| 6 | Redistribution and use in source and binary forms, with or without | ||
| 7 | modification, are permitted provided that the following conditions are met: | ||
| 8 | |||
| 9 | 1. Redistributions of source code must retain the above copyright notice, this | ||
| 10 | list of conditions and the following disclaimer. | ||
| 11 | |||
| 12 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 13 | this list of conditions and the following disclaimer in the documentation | ||
| 14 | and/or other materials provided with the distribution. | ||
| 15 | |||
| 16 | 3. Neither the name of the copyright holder nor the names of its | ||
| 17 | contributors may be used to endorse or promote products derived from | ||
| 18 | this software without specific prior written permission. | ||
| 19 | |||
| 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
| 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..0dd72f5 --- /dev/null +++ b/MANIFEST.in | |||
| @@ -0,0 +1 @@ | |||
| recursive-include ttun/staticfiles * | |||
diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..16538d9 --- /dev/null +++ b/README.rst | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | =========== | ||
| 2 | TTUN Client | ||
| 3 | =========== | ||
| 4 | |||
| 5 | |Deploy| | ||
| 6 | |||
| 7 | .. |Deploy| image:: https://github.com/tomvanderlee/ttun-client/actions/workflows/python-publish.yml/badge.svg | ||
| 8 | :target: https://github.com/tomvanderlee/ttun-client/actions/workflows/python-publish.yml | ||
| 9 | |||
| 10 | Expose a localport via you selfhosted `TTUN Server <https://github.com/tomvanderlee/ttun-server>`_ | ||
| 11 | |||
| 12 | Installing | ||
| 13 | ---------- | ||
| 14 | |||
| 15 | :: | ||
| 16 | |||
| 17 | pip install ttun | ||
| 18 | |||
| 19 | Developing | ||
| 20 | ---------- | ||
| 21 | |||
| 22 | 1. Create and activate a python 3.10 virtual environment | ||
| 23 | |||
| 24 | 2. Install requirements:: | ||
| 25 | |||
| 26 | pip install -r requirements.txt | ||
| 27 | |||
| 28 | 3. Run:: | ||
| 29 | |||
| 30 | python -m ttun | ||
diff --git a/build_requirements.txt b/build_requirements.txt new file mode 100644 index 0000000..03befb7 --- /dev/null +++ b/build_requirements.txt | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | setuptools | ||
| 2 | build | ||
| 3 | setuptools-git-versioning | ||
diff --git a/index.html b/index.html new file mode 100644 index 0000000..a09a4ed --- /dev/null +++ b/index.html | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <title>React Vite Micro Typescript App</title> | ||
| 5 | </head> | ||
| 6 | <body> | ||
| 7 | <div id="root"></div> | ||
| 8 | <script type="module" src="./src/index.tsx"></script> | ||
| 9 | </body> | ||
| 10 | </html> | ||
diff --git a/package.json b/package.json new file mode 100644 index 0000000..f49df56 --- /dev/null +++ b/package.json | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | { | ||
| 2 | "name": "client", | ||
| 3 | "version": "0.1.0", | ||
| 4 | "description": "", | ||
| 5 | "scripts": { | ||
| 6 | "start": "vite", | ||
| 7 | "build": "vite build --outDir ttun/staticfiles", | ||
| 8 | "typecheck": "tsc --noEmit", | ||
| 9 | "typewatch": "tsc --noEmit --watch" | ||
| 10 | }, | ||
| 11 | "license": "MIT", | ||
| 12 | "dependencies": { | ||
| 13 | "classnames": "^2.3.1", | ||
| 14 | "react": "^17.0.2", | ||
| 15 | "react-dom": "^17.0.2", | ||
| 16 | "react-json-view": "^1.21.3" | ||
| 17 | }, | ||
| 18 | "devDependencies": { | ||
| 19 | "@types/react": "^16.9.34", | ||
| 20 | "@types/react-dom": "^16.9.7", | ||
| 21 | "babel-preset-nano-react-app": "^0.1.0", | ||
| 22 | "sass": "^1.45.2", | ||
| 23 | "typescript": "^3.8.3", | ||
| 24 | "vite": "^2.6.7" | ||
| 25 | } | ||
| 26 | } | ||
diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ba7a2d8 --- /dev/null +++ b/pyproject.toml | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | [build-system] | ||
| 2 | requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning", ] | ||
| 3 | build-backend = "setuptools.build_meta" | ||
| 4 | |||
| 5 | [tool.setuptools-git-versioning] | ||
| 6 | enabled = true | ||
diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..04b1cf3 --- /dev/null +++ b/requirements.txt | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | -r build_requirements.txt | ||
| 2 | websockets ~= 10.0 | ||
| 3 | aiohttp ~= 3.8 | ||
| 4 | appdirs ~= 1.4 | ||
diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..e0b1a3a --- /dev/null +++ b/setup.cfg | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | [metadata] | ||
| 2 | name = ttun | ||
| 3 | |||
| 4 | [options] | ||
| 5 | include_package_data = True | ||
| 6 | packages = ttun | ||
| 7 | install_requires = | ||
| 8 | websockets ~= 10.0 | ||
| 9 | aiohttp ~= 3.8 | ||
| 10 | appdirs ~= 1.4 | ||
| 11 | |||
| 12 | [options.entry_points] | ||
| 13 | console_scripts = | ||
| 14 | ttun = ttun.__main__:main | ||
diff --git a/src/_reset.scss b/src/_reset.scss new file mode 100644 index 0000000..ed11813 --- /dev/null +++ b/src/_reset.scss | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* http://meyerweb.com/eric/tools/css/reset/ | ||
| 2 | v2.0 | 20110126 | ||
| 3 | License: none (public domain) | ||
| 4 | */ | ||
| 5 | |||
| 6 | html, body, div, span, applet, object, iframe, | ||
| 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, | ||
| 8 | a, abbr, acronym, address, big, cite, code, | ||
| 9 | del, dfn, em, img, ins, kbd, q, s, samp, | ||
| 10 | small, strike, strong, sub, sup, tt, var, | ||
| 11 | b, u, i, center, | ||
| 12 | dl, dt, dd, ol, ul, li, | ||
| 13 | fieldset, form, label, legend, | ||
| 14 | table, caption, tbody, tfoot, thead, tr, th, td, | ||
| 15 | article, aside, canvas, details, embed, | ||
| 16 | figure, figcaption, footer, header, hgroup, | ||
| 17 | menu, nav, output, ruby, section, summary, | ||
| 18 | time, mark, audio, video { | ||
| 19 | margin: 0; | ||
| 20 | padding: 0; | ||
| 21 | border: 0; | ||
| 22 | font-size: 100%; | ||
| 23 | font: inherit; | ||
| 24 | vertical-align: baseline; | ||
| 25 | } | ||
| 26 | /* HTML5 display-role reset for older browsers */ | ||
| 27 | article, aside, details, figcaption, figure, | ||
| 28 | footer, header, hgroup, menu, nav, section { | ||
| 29 | display: block; | ||
| 30 | } | ||
| 31 | body { | ||
| 32 | line-height: 1; | ||
| 33 | } | ||
| 34 | ol, ul { | ||
| 35 | list-style: none; | ||
| 36 | } | ||
| 37 | blockquote, q { | ||
| 38 | quotes: none; | ||
| 39 | } | ||
| 40 | blockquote:before, blockquote:after, | ||
| 41 | q:before, q:after { | ||
| 42 | content: ''; | ||
| 43 | content: none; | ||
| 44 | } | ||
| 45 | table { | ||
| 46 | border-collapse: collapse; | ||
| 47 | border-spacing: 0; | ||
| 48 | } | ||
diff --git a/src/components/App/App.module.scss b/src/components/App/App.module.scss new file mode 100644 index 0000000..2036eb9 --- /dev/null +++ b/src/components/App/App.module.scss | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | .app { | ||
| 2 | display: flex; | ||
| 3 | flex-flow: column nowrap; | ||
| 4 | grid-template-rows: auto 1fr; | ||
| 5 | height: 100vh; | ||
| 6 | overflow: hidden; | ||
| 7 | } | ||
| 8 | |||
| 9 | .main { | ||
| 10 | display: flex; | ||
| 11 | flex-flow: row nowrap; | ||
| 12 | flex-grow: 1; | ||
| 13 | overflow: hidden; | ||
| 14 | } | ||
| 15 | |||
| 16 | .header { | ||
| 17 | font-size: 1.2em; | ||
| 18 | display: flex; | ||
| 19 | flex-flow: row nowrap; | ||
| 20 | align-items: center; | ||
| 21 | justify-content: space-between; | ||
| 22 | background: black; | ||
| 23 | color: white; | ||
| 24 | padding: 1em; | ||
| 25 | |||
| 26 | a { | ||
| 27 | color: white; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | .sidebar { | ||
| 32 | width: calc((6 / 16) * 100%); | ||
| 33 | height: 100%; | ||
| 34 | grid-area: sidebar; | ||
| 35 | border-right: 1px solid black; | ||
| 36 | overflow-y: auto; | ||
| 37 | |||
| 38 | li { | ||
| 39 | border-bottom: 1px solid gray; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | .details { | ||
| 44 | width: calc((10 / 16) * 100%); | ||
| 45 | overflow: hidden; | ||
| 46 | height: 100%; | ||
| 47 | } | ||
| 48 | |||
| 49 | .noRequest, .noRequestSelected { | ||
| 50 | width: 100%; | ||
| 51 | height: 100%; | ||
| 52 | display: flex; | ||
| 53 | justify-content: center; | ||
| 54 | align-items: center; | ||
| 55 | } | ||
diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx new file mode 100644 index 0000000..3a7fe9b --- /dev/null +++ b/src/components/App/App.tsx | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | import * as React from "react"; | ||
| 2 | import useRequests, {RequestResponse} from "../../hooks/useRequests"; | ||
| 3 | import {useEffect, useMemo, useState} from "react"; | ||
| 4 | |||
| 5 | import styles from './App.module.scss'; | ||
| 6 | import Details from "../Details/Details"; | ||
| 7 | import RequestSummary from "../RequestSummary/RequestSummary"; | ||
| 8 | import {getHost} from "../../utils"; | ||
| 9 | |||
| 10 | interface Config { | ||
| 11 | url: string | ||
| 12 | } | ||
| 13 | |||
| 14 | export default function App() { | ||
| 15 | const [config, setConfig]= useState<Config | null>(null) | ||
| 16 | useEffect(() => { | ||
| 17 | fetch(`http://${getHost()}/config/`) | ||
| 18 | .then(response => response.json() as Promise<Config>) | ||
| 19 | .then(setConfig) | ||
| 20 | }, []) | ||
| 21 | |||
| 22 | const requests = useRequests(); | ||
| 23 | const [selectedRequestIndex, setSelectedRequestIndex] = useState<number | null>(null); | ||
| 24 | const selectedRequest = useMemo<RequestResponse | null>(() => ( | ||
| 25 | selectedRequestIndex === null | ||
| 26 | ? null | ||
| 27 | : requests[selectedRequestIndex] | ||
| 28 | ), [selectedRequestIndex, requests]); | ||
| 29 | |||
| 30 | return config && ( | ||
| 31 | <div className={styles.app}> | ||
| 32 | <header className={styles.header}> | ||
| 33 | TTUN | ||
| 34 | <a href={config.url} target="_blank">{config.url}</a> | ||
| 35 | </header> | ||
| 36 | <main className={styles.main}> | ||
| 37 | <ul className={styles.sidebar}> | ||
| 38 | { | ||
| 39 | requests.length > 0 | ||
| 40 | ? requests.slice(0).reverse().map((requestResponse, index) => ( | ||
| 41 | <li onClick={() => setSelectedRequestIndex(requests.length - index - 1)} key={`request-${index}`}> | ||
| 42 | <RequestSummary requestResponse={requestResponse} /> | ||
| 43 | </li> | ||
| 44 | )) | ||
| 45 | : ( | ||
| 46 | <div className={styles.noRequest}> | ||
| 47 | <p>No requests</p> | ||
| 48 | </div> | ||
| 49 | ) | ||
| 50 | } | ||
| 51 | </ul> | ||
| 52 | |||
| 53 | <div className={styles.details}> | ||
| 54 | { | ||
| 55 | selectedRequest !== null | ||
| 56 | ? ( | ||
| 57 | <Details requestResponse={selectedRequest} /> | ||
| 58 | ) : ( | ||
| 59 | <div className={styles.noRequestSelected}> | ||
| 60 | <p>Select a request to inspect it</p> | ||
| 61 | </div> | ||
| 62 | ) | ||
| 63 | } | ||
| 64 | </div> | ||
| 65 | </main> | ||
| 66 | </div> | ||
| 67 | ); | ||
| 68 | } | ||
diff --git a/src/components/Content/Content.module.scss b/src/components/Content/Content.module.scss new file mode 100644 index 0000000..8908516 --- /dev/null +++ b/src/components/Content/Content.module.scss | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | .content { | ||
| 2 | width: 100%; | ||
| 3 | height: 100%; | ||
| 4 | display: flex; | ||
| 5 | flex-flow: column nowrap; | ||
| 6 | overflow: hidden; | ||
| 7 | } | ||
| 8 | |||
| 9 | .header { | ||
| 10 | flex-shrink: 0; | ||
| 11 | flex-grow: 0; | ||
| 12 | width: 100%; | ||
| 13 | display: flex; | ||
| 14 | padding: 0.5em; | ||
| 15 | background-color: black; | ||
| 16 | color: white; | ||
| 17 | } | ||
| 18 | |||
| 19 | .body { | ||
| 20 | flex-grow: 1; | ||
| 21 | flex-shrink: 1; | ||
| 22 | overflow-y: auto; | ||
| 23 | |||
| 24 | pre { | ||
| 25 | width: 100%; | ||
| 26 | height: 100%; | ||
| 27 | padding: 1em; | ||
| 28 | font-family: monospace; | ||
| 29 | overflow: auto; | ||
| 30 | } | ||
| 31 | |||
| 32 | iframe { | ||
| 33 | height: 100%; | ||
| 34 | width: 100%; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | .renderError { | ||
| 39 | width: 100%; | ||
| 40 | height: 100%; | ||
| 41 | display: flex; | ||
| 42 | flex-flow: column nowrap; | ||
| 43 | justify-content: center; | ||
| 44 | align-items: center; | ||
| 45 | |||
| 46 | a { | ||
| 47 | margin-top: 1em; | ||
| 48 | text-decoration: underline; | ||
| 49 | color: blue; | ||
| 50 | } | ||
| 51 | } | ||
diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx new file mode 100644 index 0000000..a7b5949 --- /dev/null +++ b/src/components/Content/Content.tsx | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | import styles from "~components/Details/Details.module.scss"; | ||
| 2 | import * as React from "react"; | ||
| 3 | import classNames from "classnames"; | ||
| 4 | import {RequestPayload, ResponsePayload} from "~hooks/useRequests"; | ||
| 5 | import { | ||
| 6 | Dispatch, | ||
| 7 | forwardRef, SetStateAction, | ||
| 8 | useEffect, | ||
| 9 | useImperativeHandle, | ||
| 10 | useMemo, | ||
| 11 | useRef, | ||
| 12 | useState | ||
| 13 | } from "react"; | ||
| 14 | import ReactJson from 'react-json-view'; | ||
| 15 | import styles from './Content.module.scss'; | ||
| 16 | |||
| 17 | interface ContentProps { | ||
| 18 | data: RequestPayload | ResponsePayload | ||
| 19 | setRaw: Dispatch<SetStateAction<boolean>> | ||
| 20 | raw?: boolean | ||
| 21 | } | ||
| 22 | |||
| 23 | export default function Content({ raw, setRaw, ...props }: ContentProps): JSX.Element { | ||
| 24 | return ( | ||
| 25 | <div className={styles.content}> | ||
| 26 | <div className={styles.header}> | ||
| 27 | <input id='raw' type='checkbox' checked={raw} onChange={() => setRaw(!raw)}/> | ||
| 28 | <label htmlFor='raw'>Raw</label> | ||
| 29 | </div> | ||
| 30 | <div className={styles.body}> | ||
| 31 | {(() => { | ||
| 32 | try { | ||
| 33 | return ContentBody({ ...props, raw }) | ||
| 34 | } catch { | ||
| 35 | return ( | ||
| 36 | <div className={styles.renderError}> | ||
| 37 | <p>Body could not be rendered</p> | ||
| 38 | <a onClick={() => setRaw(true)}>View raw</a> | ||
| 39 | </div> | ||
| 40 | ) | ||
| 41 | } | ||
| 42 | })()} | ||
| 43 | </div> | ||
| 44 | </div> | ||
| 45 | ) | ||
| 46 | }; | ||
| 47 | |||
| 48 | function ContentBody({ data, raw = false }: Omit<ContentProps, 'setRaw'>) { | ||
| 49 | const contentType = useMemo(() => { | ||
| 50 | if (raw) { | ||
| 51 | return ''; | ||
| 52 | } | ||
| 53 | |||
| 54 | const [_, type] = ( | ||
| 55 | Object | ||
| 56 | .entries(data.headers) | ||
| 57 | .find(([key]) => key.toLowerCase() === 'content-type') | ||
| 58 | ); | ||
| 59 | |||
| 60 | return type.toLowerCase().split(';')[0]; | ||
| 61 | }, [data, raw]); | ||
| 62 | |||
| 63 | if (raw) { | ||
| 64 | return <pre>{atob(data.body)}</pre> | ||
| 65 | } | ||
| 66 | |||
| 67 | if (['application/pdf', 'text/html'].includes(contentType)) { | ||
| 68 | return <iframe | ||
| 69 | src={`data:${contentType};base64,${data.body}`} | ||
| 70 | srcDoc={contentType === 'text/html' ? atob(data.body) : undefined} | ||
| 71 | loading='lazy' | ||
| 72 | sandbox='' | ||
| 73 | /> | ||
| 74 | } | ||
| 75 | |||
| 76 | if (contentType.startsWith('application/json')) { | ||
| 77 | return <ReactJson | ||
| 78 | src={JSON.parse(atob(data.body))} | ||
| 79 | style={{ | ||
| 80 | padding: '1em', | ||
| 81 | width: '100%', | ||
| 82 | height: '100%', | ||
| 83 | }} | ||
| 84 | /> | ||
| 85 | } | ||
| 86 | |||
| 87 | if (contentType.startsWith('audio')) { | ||
| 88 | return <audio src={`data:${contentType};base64,${data.body}`} /> | ||
| 89 | } | ||
| 90 | |||
| 91 | if (contentType.startsWith('video')) { | ||
| 92 | return <video src={`data:${contentType};base64,${data.body}`} /> | ||
| 93 | } | ||
| 94 | |||
| 95 | if (contentType.startsWith('image')) { | ||
| 96 | return <img src={`data:${contentType};base64,${data.body}`} alt=''/> | ||
| 97 | } | ||
| 98 | |||
| 99 | throw new Error('Not Rendered'); | ||
| 100 | }; | ||
diff --git a/src/components/Details/Details.module.scss b/src/components/Details/Details.module.scss new file mode 100644 index 0000000..32197f0 --- /dev/null +++ b/src/components/Details/Details.module.scss | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | .details { | ||
| 2 | height: 100%; | ||
| 3 | display: flex; | ||
| 4 | flex-flow: column nowrap; | ||
| 5 | align-items: stretch; | ||
| 6 | overflow: hidden; | ||
| 7 | } | ||
| 8 | |||
| 9 | .header { | ||
| 10 | flex-shrink: 0; | ||
| 11 | flex-grow: 0; | ||
| 12 | } | ||
| 13 | |||
| 14 | .content { | ||
| 15 | flex-grow: 1; | ||
| 16 | flex-shrink: 1; | ||
| 17 | overflow-y: auto; | ||
| 18 | } | ||
| 19 | |||
| 20 | .summary { | ||
| 21 | font-size: 2em; | ||
| 22 | } | ||
| 23 | |||
| 24 | .tabs { | ||
| 25 | display: flex; | ||
| 26 | border-bottom: 1px solid black; | ||
| 27 | |||
| 28 | &:last-child { | ||
| 29 | flex-grow: 1; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | .tab { | ||
| 34 | background-color: white; | ||
| 35 | border: none; | ||
| 36 | border-top: 1px solid black; | ||
| 37 | border-right: 1px solid black; | ||
| 38 | border-radius: 0; | ||
| 39 | color: black; | ||
| 40 | font-size: 1.2em; | ||
| 41 | padding: 0.5em; | ||
| 42 | |||
| 43 | &.selected { | ||
| 44 | background-color: black; | ||
| 45 | color: white; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | .emptySpace { | ||
| 50 | flex-grow: 1; | ||
| 51 | display: flex; | ||
| 52 | justify-content: flex-end; | ||
| 53 | align-items: center; | ||
| 54 | font-size: 1.2em; | ||
| 55 | padding: 0.5em; | ||
| 56 | } | ||
| 57 | |||
| 58 | .resend { | ||
| 59 | margin-left: 1em; | ||
| 60 | } | ||
| 61 | |||
| 62 | .headers { | ||
| 63 | display: grid; | ||
| 64 | grid-template-columns: auto 1fr; | ||
| 65 | border: 1px solid black; | ||
| 66 | margin: 1em; | ||
| 67 | overflow-x: auto; | ||
| 68 | |||
| 69 | h2 { | ||
| 70 | grid-column: 1/ span 2; | ||
| 71 | background-color: black; | ||
| 72 | color: white; | ||
| 73 | padding: 0.5em; | ||
| 74 | } | ||
| 75 | |||
| 76 | > div { | ||
| 77 | line-break: auto; | ||
| 78 | padding: 0.5em; | ||
| 79 | |||
| 80 | &:nth-of-type(4n), &:nth-of-type(4n - 1) { | ||
| 81 | background-color: lightgray; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
diff --git a/src/components/Details/Details.tsx b/src/components/Details/Details.tsx new file mode 100644 index 0000000..c4a23f4 --- /dev/null +++ b/src/components/Details/Details.tsx | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | import * as React from "react"; | ||
| 2 | import { | ||
| 3 | RequestPayload, | ||
| 4 | RequestResponse, | ||
| 5 | ResponsePayload | ||
| 6 | } from "~hooks/useRequests"; | ||
| 7 | import {useCallback, useEffect, useMemo, useState} from "react"; | ||
| 8 | import styles from "./Details.module.scss"; | ||
| 9 | import RequestSummary from "../RequestSummary/RequestSummary"; | ||
| 10 | import classNames from 'classnames'; | ||
| 11 | import Content from "../Content/Content"; | ||
| 12 | import {getHost} from "../../utils"; | ||
| 13 | |||
| 14 | |||
| 15 | interface TimingProps { | ||
| 16 | timing: number; | ||
| 17 | } | ||
| 18 | |||
| 19 | |||
| 20 | function Timing({ timing }: TimingProps) { | ||
| 21 | const value = useMemo(() => (Math.round(timing * 1000) / 1000), [timing]); | ||
| 22 | const showSeconds = useMemo(() => value > 1, [value]); | ||
| 23 | |||
| 24 | return !Number.isNaN(value) | ||
| 25 | ? ( | ||
| 26 | <> | ||
| 27 | {`${showSeconds ? value : value * 1000}${ showSeconds ? 's' : 'ms' }`} | ||
| 28 | </> | ||
| 29 | ) | ||
| 30 | : null; | ||
| 31 | } | ||
| 32 | |||
| 33 | interface HeadersProps { | ||
| 34 | title: string | ||
| 35 | headers: { | ||
| 36 | [key: string]: string | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | function Headers({ title, headers }: HeadersProps) { | ||
| 41 | return ( | ||
| 42 | <div className={styles.headers}> | ||
| 43 | <h2>{ title }</h2> | ||
| 44 | { | ||
| 45 | Object.entries(headers).map(([key, value]) => ( | ||
| 46 | <> | ||
| 47 | <div>{key}</div> | ||
| 48 | <div>{value}</div> | ||
| 49 | </> | ||
| 50 | )) | ||
| 51 | } | ||
| 52 | </div> | ||
| 53 | ) | ||
| 54 | } | ||
| 55 | |||
| 56 | interface DetailsProps { | ||
| 57 | requestResponse: RequestResponse | ||
| 58 | } | ||
| 59 | |||
| 60 | type Tab = 'headers' | 'request' | 'response' | ||
| 61 | |||
| 62 | export default function Details({ requestResponse }: DetailsProps) { | ||
| 63 | const [tab, selectTab] = useState<Tab>('headers'); | ||
| 64 | const [raw, setRaw] = useState(false); | ||
| 65 | |||
| 66 | const resend = useCallback(async () => fetch( | ||
| 67 | `http://${getHost()}/resend/`, | ||
| 68 | { | ||
| 69 | method: 'POST', | ||
| 70 | body: JSON.stringify({ | ||
| 71 | ...requestResponse.request, | ||
| 72 | id: undefined | ||
| 73 | }) | ||
| 74 | } | ||
| 75 | ), [requestResponse]); | ||
| 76 | |||
| 77 | return ( | ||
| 78 | <div className={styles.details}> | ||
| 79 | <div className={styles.header}> | ||
| 80 | <RequestSummary requestResponse={requestResponse} className={styles.summary}/> | ||
| 81 | |||
| 82 | <div className={styles.tabs}> | ||
| 83 | <button | ||
| 84 | onClick={() => selectTab('headers')} | ||
| 85 | className={classNames(styles.tab, { | ||
| 86 | [styles.selected]: tab === 'headers' | ||
| 87 | })} | ||
| 88 | disabled={requestResponse.response === undefined} | ||
| 89 | > | ||
| 90 | Headers | ||
| 91 | </button> | ||
| 92 | <button | ||
| 93 | onClick={() => selectTab('request')} | ||
| 94 | className={classNames(styles.tab, { | ||
| 95 | [styles.selected]: tab === 'request' | ||
| 96 | })} | ||
| 97 | > | ||
| 98 | Request | ||
| 99 | </button> | ||
| 100 | <button | ||
| 101 | onClick={() => selectTab('response')} | ||
| 102 | className={classNames(styles.tab, { | ||
| 103 | [styles.selected]: tab === 'response' | ||
| 104 | })} | ||
| 105 | disabled={requestResponse.response === undefined} | ||
| 106 | > | ||
| 107 | Response | ||
| 108 | </button> | ||
| 109 | |||
| 110 | <div className={styles.emptySpace}> | ||
| 111 | <Timing timing={requestResponse.response?.timing ?? NaN} /> | ||
| 112 | <button className={styles.resend} onClick={() => resend()}>Resend</button> | ||
| 113 | </div> | ||
| 114 | </div> | ||
| 115 | </div> | ||
| 116 | <div className={styles.content}> | ||
| 117 | { | ||
| 118 | tab === 'headers' && ( | ||
| 119 | <> | ||
| 120 | <Headers | ||
| 121 | title="Request Headers" | ||
| 122 | headers={requestResponse.request.headers} | ||
| 123 | /> | ||
| 124 | { | ||
| 125 | requestResponse.response && ( | ||
| 126 | <Headers | ||
| 127 | title="Response Headers" | ||
| 128 | headers={requestResponse.response.headers} | ||
| 129 | /> | ||
| 130 | ) | ||
| 131 | } | ||
| 132 | </> | ||
| 133 | ) | ||
| 134 | } | ||
| 135 | { | ||
| 136 | tab === 'request' && ( | ||
| 137 | <Content data={requestResponse.request} raw={raw} setRaw={setRaw}/> | ||
| 138 | ) | ||
| 139 | } | ||
| 140 | { | ||
| 141 | tab === 'response' && requestResponse.response !== undefined && ( | ||
| 142 | <Content data={requestResponse.response} raw={raw} setRaw={setRaw}/> | ||
| 143 | ) | ||
| 144 | } | ||
| 145 | </div> | ||
| 146 | </div> | ||
| 147 | ) | ||
| 148 | } | ||
diff --git a/src/components/RequestSummary/RequestSummary.module.scss b/src/components/RequestSummary/RequestSummary.module.scss new file mode 100644 index 0000000..e1752b3 --- /dev/null +++ b/src/components/RequestSummary/RequestSummary.module.scss | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | .requestSummary { | ||
| 2 | display: grid; | ||
| 3 | grid-template-columns: auto 1fr auto; | ||
| 4 | padding: 1em; | ||
| 5 | grid-gap: 1em; | ||
| 6 | align-items: center; | ||
| 7 | } | ||
| 8 | |||
| 9 | .method { | ||
| 10 | } | ||
| 11 | |||
| 12 | .statusCode { | ||
| 13 | padding: 0.2em; | ||
| 14 | border-radius: 0.4em; | ||
| 15 | background-color: darkgray; | ||
| 16 | |||
| 17 | &.info, &.success, &.redirect { | ||
| 18 | background-color: forestgreen; | ||
| 19 | } | ||
| 20 | |||
| 21 | &.clientError, &.serverError { | ||
| 22 | background-color: red; | ||
| 23 | } | ||
| 24 | } | ||
diff --git a/src/components/RequestSummary/RequestSummary.tsx b/src/components/RequestSummary/RequestSummary.tsx new file mode 100644 index 0000000..af928c0 --- /dev/null +++ b/src/components/RequestSummary/RequestSummary.tsx | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | import {RequestResponse} from "~hooks/useRequests"; | ||
| 2 | import * as React from "react"; | ||
| 3 | import classNames from "classnames"; | ||
| 4 | |||
| 5 | import styles from './RequestSummary.module.scss'; | ||
| 6 | |||
| 7 | interface RequestSummaryProps { | ||
| 8 | requestResponse: RequestResponse | ||
| 9 | className?: string | ||
| 10 | } | ||
| 11 | |||
| 12 | function isBetween(value: number, min: number, max: number) { | ||
| 13 | return value >= min && value <= max | ||
| 14 | } | ||
| 15 | |||
| 16 | export default function RequestSummary({ requestResponse: { request, response }, className = ''}: RequestSummaryProps) { | ||
| 17 | const statusCode = response?.status ?? 0 | ||
| 18 | return ( | ||
| 19 | <div className={classNames(styles.requestSummary, className)}> | ||
| 20 | <span className={styles.method}>{ request.method }</span> | ||
| 21 | <p>{ request.path }</p> | ||
| 22 | <span className={classNames(styles.statusCode, { | ||
| 23 | [styles.info]: isBetween(statusCode, 100, 199), | ||
| 24 | [styles.success]: isBetween(statusCode, 200, 299), | ||
| 25 | [styles.redirect]: isBetween(statusCode, 300, 399), | ||
| 26 | [styles.clientError]: isBetween(statusCode, 400, 499), | ||
| 27 | [styles.serverError]: isBetween(statusCode, 500, 599) | ||
| 28 | })}> | ||
| 29 | { response?.status ?? 'Loading...'} | ||
| 30 | </span> | ||
| 31 | </div> | ||
| 32 | ) | ||
| 33 | } | ||
diff --git a/src/hooks/useRequests.tsx b/src/hooks/useRequests.tsx new file mode 100644 index 0000000..3ad5cc7 --- /dev/null +++ b/src/hooks/useRequests.tsx | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | import {useCallback, useEffect, useMemo, useState} from "react"; | ||
| 2 | import {getHost} from "../utils"; | ||
| 3 | |||
| 4 | type Dict = { | ||
| 5 | [key: string]: string | ||
| 6 | } | ||
| 7 | |||
| 8 | export interface RequestPayload { | ||
| 9 | id: string | ||
| 10 | body: string | ||
| 11 | cookies: Dict | ||
| 12 | headers: Dict | ||
| 13 | method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | ||
| 14 | path: string | ||
| 15 | } | ||
| 16 | |||
| 17 | interface Request { | ||
| 18 | type: 'request', | ||
| 19 | payload: RequestPayload, | ||
| 20 | } | ||
| 21 | |||
| 22 | export interface ResponsePayload { | ||
| 23 | id: string | ||
| 24 | timing: number | ||
| 25 | body: string | ||
| 26 | cookies: Dict | ||
| 27 | headers: Dict | ||
| 28 | status: number | ||
| 29 | } | ||
| 30 | |||
| 31 | interface Response { | ||
| 32 | type: 'response', | ||
| 33 | payload: ResponsePayload, | ||
| 34 | } | ||
| 35 | |||
| 36 | export interface RequestResponse { | ||
| 37 | request: RequestPayload | ||
| 38 | response?: ResponsePayload | ||
| 39 | } | ||
| 40 | |||
| 41 | export default function useRequests(): RequestResponse[] { | ||
| 42 | const wsHost = useMemo(getHost, []); | ||
| 43 | const connect = useCallback(() => new WebSocket(`ws://${wsHost}/inspect/`), [wsHost]) | ||
| 44 | |||
| 45 | const [requests, setRequests] = useState<RequestPayload[]>([]); | ||
| 46 | const [responses, setResponses] = useState<ResponsePayload[]>([]); | ||
| 47 | const [ws, setWs] = useState(() => connect()); | ||
| 48 | |||
| 49 | useEffect(() => { | ||
| 50 | const reconnect = () => setWs(() => connect()) | ||
| 51 | const onMessage = ({ data }) => { | ||
| 52 | const { type, payload } = JSON.parse(data) as Request | Response | ||
| 53 | |||
| 54 | switch (type) { | ||
| 55 | case 'request': | ||
| 56 | setRequests((rqs) => [...rqs, payload as RequestPayload]) | ||
| 57 | break | ||
| 58 | case 'response': | ||
| 59 | setResponses((rps) => [...rps, payload as ResponsePayload]) | ||
| 60 | break | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | ws.addEventListener('message', onMessage) | ||
| 65 | ws.addEventListener('close', reconnect) | ||
| 66 | |||
| 67 | return () => { | ||
| 68 | ws.removeEventListener('message', onMessage); | ||
| 69 | ws.removeEventListener('close', reconnect); | ||
| 70 | } | ||
| 71 | }, [ws]) | ||
| 72 | |||
| 73 | return useMemo<RequestResponse[]>(() => requests.map((request) => ({ | ||
| 74 | request: request, | ||
| 75 | response: responses.find(({ id }) => id === request.id) | ||
| 76 | })), [requests, responses]) | ||
| 77 | } | ||
diff --git a/src/index.scss b/src/index.scss new file mode 100644 index 0000000..ef8fd7f --- /dev/null +++ b/src/index.scss | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | @import "reset"; | ||
| 2 | |||
| 3 | * { | ||
| 4 | box-sizing: border-box; | ||
| 5 | } | ||
| 6 | |||
| 7 | html, body, #root { | ||
| 8 | margin: 0; | ||
| 9 | padding: 0; | ||
| 10 | |||
| 11 | height: 100vh; | ||
| 12 | width: 100vw; | ||
| 13 | |||
| 14 | font-family: sans-serif; | ||
| 15 | overflow: hidden; | ||
| 16 | } | ||
diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..a6c4952 --- /dev/null +++ b/src/index.tsx | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | import * as React from "react"; | ||
| 2 | import * as ReactDOM from "react-dom"; | ||
| 3 | import App from "./components/App/App"; | ||
| 4 | |||
| 5 | import './index.scss'; | ||
| 6 | |||
| 7 | ReactDOM.render(<App />, document.getElementById("root")); | ||
diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..dcf010a --- /dev/null +++ b/src/utils.ts | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | export function getHost() { | ||
| 2 | // @ts-ignore | ||
| 3 | return import.meta.env.DEV ? 'localhost:4040' : window.location.host | ||
| 4 | } | ||
diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..986e0c9 --- /dev/null +++ b/tsconfig.json | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | { | ||
| 2 | "compilerOptions": { | ||
| 3 | "baseUrl": "./src", | ||
| 4 | "jsx": "react", | ||
| 5 | "moduleResolution": "Node", | ||
| 6 | "paths": { | ||
| 7 | "~*": [ | ||
| 8 | "./*" | ||
| 9 | ] | ||
| 10 | }, | ||
| 11 | "strict": true, | ||
| 12 | "target": "ES2015" | ||
| 13 | }, | ||
| 14 | "include": [ | ||
| 15 | "src/**/*" | ||
| 16 | ] | ||
| 17 | } \ No newline at end of file | ||
diff --git a/ttun/__init__.py b/ttun/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ttun/__init__.py | |||
diff --git a/ttun/__main__.py b/ttun/__main__.py new file mode 100644 index 0000000..1a3ca69 --- /dev/null +++ b/ttun/__main__.py | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | import asyncio | ||
| 2 | from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter | ||
| 3 | from asyncio import FIRST_EXCEPTION | ||
| 4 | |||
| 5 | from ttun.client import Client | ||
| 6 | from asyncio.exceptions import TimeoutError, CancelledError | ||
| 7 | |||
| 8 | from ttun.inspect_server import Server | ||
| 9 | from ttun.settings import SERVER_HOSTNAME, SERVER_USING_SSL | ||
| 10 | |||
| 11 | inspect_queue = asyncio.Queue() | ||
| 12 | |||
| 13 | def main(): | ||
| 14 | parser = ArgumentParser(prog='ttun', formatter_class=ArgumentDefaultsHelpFormatter) | ||
| 15 | parser.add_argument( | ||
| 16 | 'port', | ||
| 17 | help='The local port to expose' | ||
| 18 | ) | ||
| 19 | parser.add_argument( | ||
| 20 | '--server', | ||
| 21 | default=f'{"wss" if SERVER_USING_SSL else "ws"}://{SERVER_HOSTNAME}', | ||
| 22 | help='The hostname of the ttun server', | ||
| 23 | ) | ||
| 24 | parser.add_argument( | ||
| 25 | '-s', '--subdomain', | ||
| 26 | default=None, | ||
| 27 | help = 'The subdomain of the ttun tunnel', | ||
| 28 | ) | ||
| 29 | args = parser.parse_args() | ||
| 30 | |||
| 31 | client = Client( | ||
| 32 | port=args.port, | ||
| 33 | subdomain=args.subdomain, | ||
| 34 | server=args.server, | ||
| 35 | ) | ||
| 36 | |||
| 37 | try: | ||
| 38 | loop = asyncio.get_running_loop() | ||
| 39 | except RuntimeError: | ||
| 40 | loop = asyncio.new_event_loop() | ||
| 41 | asyncio.set_event_loop(loop) | ||
| 42 | |||
| 43 | loop.run_until_complete(client.connect()) | ||
| 44 | |||
| 45 | server = Server(config=client.config, on_resend=client.proxyRequest) | ||
| 46 | tasks = { | ||
| 47 | loop.create_task(client.handle_messages()), | ||
| 48 | loop.create_task(server.run()) | ||
| 49 | } | ||
| 50 | |||
| 51 | print(client.config['url']) | ||
| 52 | try: | ||
| 53 | loop.run_until_complete(asyncio.wait(tasks, return_when=FIRST_EXCEPTION)) | ||
| 54 | except (CancelledError, TimeoutError): | ||
| 55 | for task in tasks: | ||
| 56 | task.cancel() | ||
| 57 | loop.close() | ||
| 58 | except KeyboardInterrupt: | ||
| 59 | pass | ||
| 60 | |||
| 61 | if __name__ == '__main__': | ||
| 62 | main() | ||
diff --git a/ttun/client.py b/ttun/client.py new file mode 100644 index 0000000..8be013b --- /dev/null +++ b/ttun/client.py | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | import asyncio | ||
| 2 | import json | ||
| 3 | from base64 import b64encode, b64decode | ||
| 4 | from time import perf_counter, process_time | ||
| 5 | from typing import Optional, Callable, Coroutine, Awaitable | ||
| 6 | from uuid import uuid4 | ||
| 7 | |||
| 8 | import websockets | ||
| 9 | from aiohttp import ClientSession | ||
| 10 | from websockets import WebSocketClientProtocol | ||
| 11 | from websockets.exceptions import ConnectionClosed | ||
| 12 | |||
| 13 | from ttun.pubsub import PubSub | ||
| 14 | from ttun.types import Config, RequestData, ResponseData | ||
| 15 | from timeit import timeit | ||
| 16 | |||
| 17 | |||
| 18 | class Client: | ||
| 19 | def __init__(self, port: int, server: str, subdomain: str = None): | ||
| 20 | self.port = port | ||
| 21 | self.server = server | ||
| 22 | self.subdomain = subdomain | ||
| 23 | |||
| 24 | self.config: Optional[Config] = None | ||
| 25 | self.connection: WebSocketClientProtocol = None | ||
| 26 | |||
| 27 | async def send(self, data: dict): | ||
| 28 | await self.connection.send(json.dumps(data)) | ||
| 29 | |||
| 30 | async def receive(self) -> dict: | ||
| 31 | return json.loads(await self.connection.recv()) | ||
| 32 | |||
| 33 | @staticmethod | ||
| 34 | def loop(sleep: int = None): | ||
| 35 | async def wrapper(callback: Callable[[], Coroutine]): | ||
| 36 | while True: | ||
| 37 | try: | ||
| 38 | await callback() | ||
| 39 | |||
| 40 | if sleep is not None: | ||
| 41 | await asyncio.sleep(sleep) | ||
| 42 | |||
| 43 | except ConnectionClosed: | ||
| 44 | break | ||
| 45 | return wrapper | ||
| 46 | |||
| 47 | async def connect(self) -> WebSocketClientProtocol: | ||
| 48 | self.connection = await websockets.connect(f'{self.server}/tunnel/') | ||
| 49 | |||
| 50 | await self.send({ | ||
| 51 | 'subdomain': self.subdomain | ||
| 52 | }) | ||
| 53 | |||
| 54 | self.config = await self.receive() | ||
| 55 | |||
| 56 | if self.connection.open: | ||
| 57 | return self.connection | ||
| 58 | |||
| 59 | async def handle_messages(self): | ||
| 60 | while True: | ||
| 61 | try: | ||
| 62 | request: RequestData = await self.receive() | ||
| 63 | await self.proxyRequest( | ||
| 64 | request=request, | ||
| 65 | on_response=lambda response: self.send(response) | ||
| 66 | ) | ||
| 67 | |||
| 68 | except ConnectionClosed: | ||
| 69 | break | ||
| 70 | |||
| 71 | async def proxyRequest(self, request: RequestData, on_response: Callable[[ResponseData], Awaitable] = None): | ||
| 72 | async with ClientSession() as session: | ||
| 73 | request_id = uuid4() | ||
| 74 | await PubSub.publish({ | ||
| 75 | "type": "request", | ||
| 76 | "payload": { | ||
| 77 | "id": request_id.hex, | ||
| 78 | **request | ||
| 79 | } | ||
| 80 | }) | ||
| 81 | |||
| 82 | start = perf_counter() | ||
| 83 | response = await session.request( | ||
| 84 | method=request['method'], | ||
| 85 | url=f'http://localhost:{self.port}{request["path"]}', | ||
| 86 | headers=request['headers'], | ||
| 87 | cookies=request['cookies'], | ||
| 88 | data=b64decode(request['body'].encode()) | ||
| 89 | ) | ||
| 90 | end = perf_counter() | ||
| 91 | |||
| 92 | response_data = ResponseData( | ||
| 93 | status=response.status, | ||
| 94 | headers=dict(response.headers), | ||
| 95 | cookies=dict(response.cookies), | ||
| 96 | body=b64encode(await response.read()).decode() | ||
| 97 | ) | ||
| 98 | |||
| 99 | if on_response is not None: | ||
| 100 | await on_response(response_data) | ||
| 101 | |||
| 102 | await PubSub.publish({ | ||
| 103 | "type": "response", | ||
| 104 | "payload": { | ||
| 105 | "id": request_id.hex, | ||
| 106 | "timing": end - start, | ||
| 107 | **response_data, | ||
| 108 | } | ||
| 109 | }) | ||
diff --git a/ttun/inspect_server.py b/ttun/inspect_server.py new file mode 100644 index 0000000..37f1aea --- /dev/null +++ b/ttun/inspect_server.py | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | from importlib import resources | ||
| 2 | from pathlib import Path | ||
| 3 | from typing import Callable, Awaitable, Optional | ||
| 4 | |||
| 5 | from aiohttp import web | ||
| 6 | |||
| 7 | from ttun.pubsub import PubSub | ||
| 8 | from ttun.types import Config, RequestData | ||
| 9 | |||
| 10 | BASE_DIR = Path(__file__).resolve().parent | ||
| 11 | |||
| 12 | |||
| 13 | def no_print(*args, **kwargs): | ||
| 14 | pass | ||
| 15 | |||
| 16 | |||
| 17 | class Server: | ||
| 18 | def __init__(self, config: Config, on_resend: Callable[[RequestData], Awaitable]): | ||
| 19 | self.config = { | ||
| 20 | **config, | ||
| 21 | 'assets': '/assets/' | ||
| 22 | } | ||
| 23 | |||
| 24 | self.on_resend = on_resend | ||
| 25 | |||
| 26 | self.app = web.Application() | ||
| 27 | with resources.path(__package__, 'staticfiles') as staticfiles: | ||
| 28 | self.app.add_routes([ | ||
| 29 | web.get('/inspect/', self.inspect_socket), | ||
| 30 | web.get('/config/', self.get_config), | ||
| 31 | web.post('/resend/', self.resend), | ||
| 32 | web.get('/', self.root), | ||
| 33 | web.static('/', staticfiles), | ||
| 34 | ]) | ||
| 35 | |||
| 36 | async def run(self): | ||
| 37 | port = 4040 | ||
| 38 | while True: | ||
| 39 | try: | ||
| 40 | await web._run_app(self.app, port=port) | ||
| 41 | except OSError: | ||
| 42 | port += 1 | ||
| 43 | |||
| 44 | async def root(self, request: web.Request): | ||
| 45 | with resources.path(__package__, 'staticfiles') as staticfiles: | ||
| 46 | return web.Response( | ||
| 47 | body=resources.read_text(f'{__package__}.staticfiles', f'index.html'), | ||
| 48 | content_type='text/html' | ||
| 49 | ) | ||
| 50 | |||
| 51 | async def get_config(self, request: web.Request): | ||
| 52 | return web.json_response( | ||
| 53 | self.config, | ||
| 54 | headers={ | ||
| 55 | 'Access-Control-Allow-Origin': '*' | ||
| 56 | } | ||
| 57 | ) | ||
| 58 | |||
| 59 | async def resend(self, request: web.Request): | ||
| 60 | await self.on_resend(await request.json()) | ||
| 61 | return web.json_response() | ||
| 62 | |||
| 63 | async def inspect_socket(self, request: web.Request): | ||
| 64 | ws = web.WebSocketResponse() | ||
| 65 | await ws.prepare(request) | ||
| 66 | |||
| 67 | with PubSub.subscribe() as subscription: | ||
| 68 | while message := await subscription.get(): | ||
| 69 | await ws.send_json(message, False) | ||
| 70 | |||
| 71 | return ws | ||
diff --git a/ttun/pubsub.py b/ttun/pubsub.py new file mode 100644 index 0000000..5d155ea --- /dev/null +++ b/ttun/pubsub.py | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | import asyncio | ||
| 2 | from contextlib import contextmanager | ||
| 3 | from typing import Any, Generator, Iterator | ||
| 4 | |||
| 5 | |||
| 6 | class PubSub: | ||
| 7 | _instance = None | ||
| 8 | |||
| 9 | def __init__(self): | ||
| 10 | self.queues: list[asyncio.Queue] = [] | ||
| 11 | |||
| 12 | @classmethod | ||
| 13 | def instance(cls) -> 'PubSub': | ||
| 14 | if cls._instance == None: | ||
| 15 | cls._instance = cls() | ||
| 16 | return cls._instance | ||
| 17 | |||
| 18 | @classmethod | ||
| 19 | @contextmanager | ||
| 20 | def subscribe(cls) -> Iterator[asyncio.Queue]: | ||
| 21 | queue = asyncio.Queue() | ||
| 22 | |||
| 23 | instance = cls.instance() | ||
| 24 | instance.queues.append(queue) | ||
| 25 | |||
| 26 | try: | ||
| 27 | yield queue | ||
| 28 | finally: | ||
| 29 | instance.queues.remove(queue) | ||
| 30 | del queue | ||
| 31 | |||
| 32 | @classmethod | ||
| 33 | async def publish(cls, msg: Any): | ||
| 34 | for queue in cls.instance().queues: | ||
| 35 | await queue.put(msg) | ||
diff --git a/ttun/settings.py b/ttun/settings.py new file mode 100644 index 0000000..a20b6c9 --- /dev/null +++ b/ttun/settings.py | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | import sys | ||
| 2 | from configparser import ConfigParser | ||
| 3 | from os import mkdir | ||
| 4 | from pathlib import Path | ||
| 5 | |||
| 6 | import appdirs | ||
| 7 | |||
| 8 | config_file = Path(appdirs.user_config_dir('ttun-client', 'ttun', roaming=True)) / 'config.ini' | ||
| 9 | |||
| 10 | config= ConfigParser() | ||
| 11 | config['server'] = { | ||
| 12 | 'hostname': '', | ||
| 13 | 'using_ssl': 'yes', | ||
| 14 | } | ||
| 15 | |||
| 16 | if not config_file.parent.exists(): | ||
| 17 | mkdir(config_file.parent) | ||
| 18 | else: | ||
| 19 | config.read(filenames=config_file) | ||
| 20 | |||
| 21 | with open(config_file, 'w') as f: | ||
| 22 | config.write(f) | ||
| 23 | |||
| 24 | SERVER_HOSTNAME = config['server'].get('hostname') | ||
| 25 | SERVER_USING_SSL = config['server'].get('using_ssl').lower() in ['yes', 'true'] | ||
| 26 | |||
| 27 | try: | ||
| 28 | assert SERVER_HOSTNAME != '' | ||
| 29 | except AssertionError: | ||
| 30 | print(f'Please add a valid server hostname in {config_file}') | ||
| 31 | sys.exit(1) | ||
diff --git a/ttun/types.py b/ttun/types.py new file mode 100644 index 0000000..cf94b9e --- /dev/null +++ b/ttun/types.py | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | from typing import TypedDict, Optional | ||
| 2 | |||
| 3 | |||
| 4 | class Message(TypedDict): | ||
| 5 | type: str | ||
| 6 | |||
| 7 | |||
| 8 | class RequestData(TypedDict): | ||
| 9 | method: str | ||
| 10 | path: str | ||
| 11 | headers: dict | ||
| 12 | cookies: dict | ||
| 13 | body: Optional[str] | ||
| 14 | |||
| 15 | |||
| 16 | class ResponseData(TypedDict): | ||
| 17 | status: int | ||
| 18 | headers: dict | ||
| 19 | cookies: dict | ||
| 20 | body: Optional[str] | ||
| 21 | |||
| 22 | |||
| 23 | class Config(TypedDict): | ||
| 24 | url: str | ||
diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..df25824 --- /dev/null +++ b/yarn.lock | |||
| @@ -0,0 +1,995 @@ | |||
| 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | ||
| 2 | # yarn lockfile v1 | ||
| 3 | |||
| 4 | |||
| 5 | "@babel/code-frame@^7.16.7": | ||
| 6 | version "7.16.7" | ||
| 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" | ||
| 8 | integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== | ||
| 9 | dependencies: | ||
| 10 | "@babel/highlight" "^7.16.7" | ||
| 11 | |||
| 12 | "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": | ||
| 13 | version "7.16.4" | ||
| 14 | resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" | ||
| 15 | integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== | ||
| 16 | |||
| 17 | "@babel/core@^7.2.2": | ||
| 18 | version "7.16.7" | ||
| 19 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" | ||
| 20 | integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA== | ||
| 21 | dependencies: | ||
| 22 | "@babel/code-frame" "^7.16.7" | ||
| 23 | "@babel/generator" "^7.16.7" | ||
| 24 | "@babel/helper-compilation-targets" "^7.16.7" | ||
| 25 | "@babel/helper-module-transforms" "^7.16.7" | ||
| 26 | "@babel/helpers" "^7.16.7" | ||
| 27 | "@babel/parser" "^7.16.7" | ||
| 28 | "@babel/template" "^7.16.7" | ||
| 29 | "@babel/traverse" "^7.16.7" | ||
| 30 | "@babel/types" "^7.16.7" | ||
| 31 | convert-source-map "^1.7.0" | ||
| 32 | debug "^4.1.0" | ||
| 33 | gensync "^1.0.0-beta.2" | ||
| 34 | json5 "^2.1.2" | ||
| 35 | semver "^6.3.0" | ||
| 36 | source-map "^0.5.0" | ||
| 37 | |||
| 38 | "@babel/generator@^7.16.7": | ||
| 39 | version "7.16.7" | ||
| 40 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.7.tgz#b42bf46a3079fa65e1544135f32e7958f048adbb" | ||
| 41 | integrity sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg== | ||
| 42 | dependencies: | ||
| 43 | "@babel/types" "^7.16.7" | ||
| 44 | jsesc "^2.5.1" | ||
| 45 | source-map "^0.5.0" | ||
| 46 | |||
| 47 | "@babel/helper-annotate-as-pure@^7.16.7": | ||
| 48 | version "7.16.7" | ||
| 49 | resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" | ||
| 50 | integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== | ||
| 51 | dependencies: | ||
| 52 | "@babel/types" "^7.16.7" | ||
| 53 | |||
| 54 | "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7": | ||
| 55 | version "7.16.7" | ||
| 56 | resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" | ||
| 57 | integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== | ||
| 58 | dependencies: | ||
| 59 | "@babel/compat-data" "^7.16.4" | ||
| 60 | "@babel/helper-validator-option" "^7.16.7" | ||
| 61 | browserslist "^4.17.5" | ||
| 62 | semver "^6.3.0" | ||
| 63 | |||
| 64 | "@babel/helper-create-class-features-plugin@^7.16.7": | ||
| 65 | version "7.16.7" | ||
| 66 | resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz#9c5b34b53a01f2097daf10678d65135c1b9f84ba" | ||
| 67 | integrity sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw== | ||
| 68 | dependencies: | ||
| 69 | "@babel/helper-annotate-as-pure" "^7.16.7" | ||
| 70 | "@babel/helper-environment-visitor" "^7.16.7" | ||
| 71 | "@babel/helper-function-name" "^7.16.7" | ||
| 72 | "@babel/helper-member-expression-to-functions" "^7.16.7" | ||
| 73 | "@babel/helper-optimise-call-expression" "^7.16.7" | ||
| 74 | "@babel/helper-replace-supers" "^7.16.7" | ||
| 75 | "@babel/helper-split-export-declaration" "^7.16.7" | ||
| 76 | |||
| 77 | "@babel/helper-define-polyfill-provider@^0.3.0": | ||
| 78 | version "0.3.0" | ||
| 79 | resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" | ||
| 80 | integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== | ||
| 81 | dependencies: | ||
| 82 | "@babel/helper-compilation-targets" "^7.13.0" | ||
| 83 | "@babel/helper-module-imports" "^7.12.13" | ||
| 84 | "@babel/helper-plugin-utils" "^7.13.0" | ||
| 85 | "@babel/traverse" "^7.13.0" | ||
| 86 | debug "^4.1.1" | ||
| 87 | lodash.debounce "^4.0.8" | ||
| 88 | resolve "^1.14.2" | ||
| 89 | semver "^6.1.2" | ||
| 90 | |||
| 91 | "@babel/helper-environment-visitor@^7.16.7": | ||
| 92 | version "7.16.7" | ||
| 93 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" | ||
| 94 | integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== | ||
| 95 | dependencies: | ||
| 96 | "@babel/types" "^7.16.7" | ||
| 97 | |||
| 98 | "@babel/helper-function-name@^7.16.7": | ||
| 99 | version "7.16.7" | ||
| 100 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" | ||
| 101 | integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== | ||
| 102 | dependencies: | ||
| 103 | "@babel/helper-get-function-arity" "^7.16.7" | ||
| 104 | "@babel/template" "^7.16.7" | ||
| 105 | "@babel/types" "^7.16.7" | ||
| 106 | |||
| 107 | "@babel/helper-get-function-arity@^7.16.7": | ||
| 108 | version "7.16.7" | ||
| 109 | resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" | ||
| 110 | integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== | ||
| 111 | dependencies: | ||
| 112 | "@babel/types" "^7.16.7" | ||
| 113 | |||
| 114 | "@babel/helper-hoist-variables@^7.16.7": | ||
| 115 | version "7.16.7" | ||
| 116 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" | ||
| 117 | integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== | ||
| 118 | dependencies: | ||
| 119 | "@babel/types" "^7.16.7" | ||
| 120 | |||
| 121 | "@babel/helper-member-expression-to-functions@^7.16.7": | ||
| 122 | version "7.16.7" | ||
| 123 | resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" | ||
| 124 | integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== | ||
| 125 | dependencies: | ||
| 126 | "@babel/types" "^7.16.7" | ||
| 127 | |||
| 128 | "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": | ||
| 129 | version "7.16.7" | ||
| 130 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" | ||
| 131 | integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== | ||
| 132 | dependencies: | ||
| 133 | "@babel/types" "^7.16.7" | ||
| 134 | |||
| 135 | "@babel/helper-module-transforms@^7.16.7": | ||
| 136 | version "7.16.7" | ||
| 137 | resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" | ||
| 138 | integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== | ||
| 139 | dependencies: | ||
| 140 | "@babel/helper-environment-visitor" "^7.16.7" | ||
| 141 | "@babel/helper-module-imports" "^7.16.7" | ||
| 142 | "@babel/helper-simple-access" "^7.16.7" | ||
| 143 | "@babel/helper-split-export-declaration" "^7.16.7" | ||
| 144 | "@babel/helper-validator-identifier" "^7.16.7" | ||
| 145 | "@babel/template" "^7.16.7" | ||
| 146 | "@babel/traverse" "^7.16.7" | ||
| 147 | "@babel/types" "^7.16.7" | ||
| 148 | |||
| 149 | "@babel/helper-optimise-call-expression@^7.16.7": | ||
| 150 | version "7.16.7" | ||
| 151 | resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" | ||
| 152 | integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== | ||
| 153 | dependencies: | ||
| 154 | "@babel/types" "^7.16.7" | ||
| 155 | |||
| 156 | "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.16.7": | ||
| 157 | version "7.16.7" | ||
| 158 | resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" | ||
| 159 | integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== | ||
| 160 | |||
| 161 | "@babel/helper-replace-supers@^7.16.7": | ||
| 162 | version "7.16.7" | ||
| 163 | resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" | ||
| 164 | integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== | ||
| 165 | dependencies: | ||
| 166 | "@babel/helper-environment-visitor" "^7.16.7" | ||
| 167 | "@babel/helper-member-expression-to-functions" "^7.16.7" | ||
| 168 | "@babel/helper-optimise-call-expression" "^7.16.7" | ||
| 169 | "@babel/traverse" "^7.16.7" | ||
| 170 | "@babel/types" "^7.16.7" | ||
| 171 | |||
| 172 | "@babel/helper-simple-access@^7.16.7": | ||
| 173 | version "7.16.7" | ||
| 174 | resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" | ||
| 175 | integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== | ||
| 176 | dependencies: | ||
| 177 | "@babel/types" "^7.16.7" | ||
| 178 | |||
| 179 | "@babel/helper-split-export-declaration@^7.16.7": | ||
| 180 | version "7.16.7" | ||
| 181 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" | ||
| 182 | integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== | ||
| 183 | dependencies: | ||
| 184 | "@babel/types" "^7.16.7" | ||
| 185 | |||
| 186 | "@babel/helper-validator-identifier@^7.16.7": | ||
| 187 | version "7.16.7" | ||
| 188 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" | ||
| 189 | integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== | ||
| 190 | |||
| 191 | "@babel/helper-validator-option@^7.16.7": | ||
| 192 | version "7.16.7" | ||
| 193 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" | ||
| 194 | integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== | ||
| 195 | |||
| 196 | "@babel/helpers@^7.16.7": | ||
| 197 | version "7.16.7" | ||
| 198 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" | ||
| 199 | integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== | ||
| 200 | dependencies: | ||
| 201 | "@babel/template" "^7.16.7" | ||
| 202 | "@babel/traverse" "^7.16.7" | ||
| 203 | "@babel/types" "^7.16.7" | ||
| 204 | |||
| 205 | "@babel/highlight@^7.16.7": | ||
| 206 | version "7.16.7" | ||
| 207 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" | ||
| 208 | integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== | ||
| 209 | dependencies: | ||
| 210 | "@babel/helper-validator-identifier" "^7.16.7" | ||
| 211 | chalk "^2.0.0" | ||
| 212 | js-tokens "^4.0.0" | ||
| 213 | |||
| 214 | "@babel/parser@^7.16.7": | ||
| 215 | version "7.16.7" | ||
| 216 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.7.tgz#d372dda9c89fcec340a82630a9f533f2fe15877e" | ||
| 217 | integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA== | ||
| 218 | |||
| 219 | "@babel/plugin-proposal-class-properties@^7.3.0": | ||
| 220 | version "7.16.7" | ||
| 221 | resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" | ||
| 222 | integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== | ||
| 223 | dependencies: | ||
| 224 | "@babel/helper-create-class-features-plugin" "^7.16.7" | ||
| 225 | "@babel/helper-plugin-utils" "^7.16.7" | ||
| 226 | |||
| 227 | "@babel/plugin-transform-runtime@^7.2.0": | ||
| 228 | version "7.16.7" | ||
| 229 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.7.tgz#1da184cb83a2287a01956c10c60e66dd503c18aa" | ||
| 230 | integrity sha512-2FoHiSAWkdq4L06uaDN3rS43i6x28desUVxq+zAFuE6kbWYQeiLPJI5IC7Sg9xKYVcrBKSQkVUfH6aeQYbl9QA== | ||
| 231 | dependencies: | ||
| 232 | "@babel/helper-module-imports" "^7.16.7" | ||
| 233 | "@babel/helper-plugin-utils" "^7.16.7" | ||
| 234 | babel-plugin-polyfill-corejs2 "^0.3.0" | ||
| 235 | babel-plugin-polyfill-corejs3 "^0.4.0" | ||
| 236 | babel-plugin-polyfill-regenerator "^0.3.0" | ||
| 237 | semver "^6.3.0" | ||
| 238 | |||
| 239 | "@babel/runtime@^7.10.2": | ||
| 240 | version "7.16.7" | ||
| 241 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" | ||
| 242 | integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== | ||
| 243 | dependencies: | ||
| 244 | regenerator-runtime "^0.13.4" | ||
| 245 | |||
| 246 | "@babel/template@^7.16.7": | ||
| 247 | version "7.16.7" | ||
| 248 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" | ||
| 249 | integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== | ||
| 250 | dependencies: | ||
| 251 | "@babel/code-frame" "^7.16.7" | ||
| 252 | "@babel/parser" "^7.16.7" | ||
| 253 | "@babel/types" "^7.16.7" | ||
| 254 | |||
| 255 | "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7": | ||
| 256 | version "7.16.7" | ||
| 257 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.7.tgz#dac01236a72c2560073658dd1a285fe4e0865d76" | ||
| 258 | integrity sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ== | ||
| 259 | dependencies: | ||
| 260 | "@babel/code-frame" "^7.16.7" | ||
| 261 | "@babel/generator" "^7.16.7" | ||
| 262 | "@babel/helper-environment-visitor" "^7.16.7" | ||
| 263 | "@babel/helper-function-name" "^7.16.7" | ||
| 264 | "@babel/helper-hoist-variables" "^7.16.7" | ||
| 265 | "@babel/helper-split-export-declaration" "^7.16.7" | ||
| 266 | "@babel/parser" "^7.16.7" | ||
| 267 | "@babel/types" "^7.16.7" | ||
| 268 | debug "^4.1.0" | ||
| 269 | globals "^11.1.0" | ||
| 270 | |||
| 271 | "@babel/types@^7.16.7": | ||
| 272 | version "7.16.7" | ||
| 273 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.7.tgz#4ed19d51f840ed4bd5645be6ce40775fecf03159" | ||
| 274 | integrity sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg== | ||
| 275 | dependencies: | ||
| 276 | "@babel/helper-validator-identifier" "^7.16.7" | ||
| 277 | to-fast-properties "^2.0.0" | ||
| 278 | |||
| 279 | "@types/prop-types@*": | ||
| 280 | version "15.7.4" | ||
| 281 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" | ||
| 282 | integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== | ||
| 283 | |||
| 284 | "@types/react-dom@^16.9.7": | ||
| 285 | version "16.9.14" | ||
| 286 | resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.14.tgz#674b8f116645fe5266b40b525777fc6bb8eb3bcd" | ||
| 287 | integrity sha512-FIX2AVmPTGP30OUJ+0vadeIFJJ07Mh1m+U0rxfgyW34p3rTlXI+nlenvAxNn4BP36YyI9IJ/+UJ7Wu22N1pI7A== | ||
| 288 | dependencies: | ||
| 289 | "@types/react" "^16" | ||
| 290 | |||
| 291 | "@types/react@^16", "@types/react@^16.9.34": | ||
| 292 | version "16.14.21" | ||
| 293 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.21.tgz#35199b21a278355ec7a3c40003bd6a334bd4ae4a" | ||
| 294 | integrity sha512-rY4DzPKK/4aohyWiDRHS2fotN5rhBSK6/rz1X37KzNna9HJyqtaGAbq9fVttrEPWF5ywpfIP1ITL8Xi2QZn6Eg== | ||
| 295 | dependencies: | ||
| 296 | "@types/prop-types" "*" | ||
| 297 | "@types/scheduler" "*" | ||
| 298 | csstype "^3.0.2" | ||
| 299 | |||
| 300 | "@types/scheduler@*": | ||
| 301 | version "0.16.2" | ||
| 302 | resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" | ||
| 303 | integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== | ||
| 304 | |||
| 305 | ansi-styles@^3.2.1: | ||
| 306 | version "3.2.1" | ||
| 307 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" | ||
| 308 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== | ||
| 309 | dependencies: | ||
| 310 | color-convert "^1.9.0" | ||
| 311 | |||
| 312 | anymatch@~3.1.2: | ||
| 313 | version "3.1.2" | ||
| 314 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" | ||
| 315 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== | ||
| 316 | dependencies: | ||
| 317 | normalize-path "^3.0.0" | ||
| 318 | picomatch "^2.0.4" | ||
| 319 | |||
| 320 | asap@~2.0.3: | ||
| 321 | version "2.0.6" | ||
| 322 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" | ||
| 323 | integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= | ||
| 324 | |||
| 325 | babel-plugin-polyfill-corejs2@^0.3.0: | ||
| 326 | version "0.3.0" | ||
| 327 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" | ||
| 328 | integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== | ||
| 329 | dependencies: | ||
| 330 | "@babel/compat-data" "^7.13.11" | ||
| 331 | "@babel/helper-define-polyfill-provider" "^0.3.0" | ||
| 332 | semver "^6.1.1" | ||
| 333 | |||
| 334 | babel-plugin-polyfill-corejs3@^0.4.0: | ||
| 335 | version "0.4.0" | ||
| 336 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz#0b571f4cf3d67f911512f5c04842a7b8e8263087" | ||
| 337 | integrity sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw== | ||
| 338 | dependencies: | ||
| 339 | "@babel/helper-define-polyfill-provider" "^0.3.0" | ||
| 340 | core-js-compat "^3.18.0" | ||
| 341 | |||
| 342 | babel-plugin-polyfill-regenerator@^0.3.0: | ||
| 343 | version "0.3.0" | ||
| 344 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" | ||
| 345 | integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== | ||
| 346 | dependencies: | ||
| 347 | "@babel/helper-define-polyfill-provider" "^0.3.0" | ||
| 348 | |||
| 349 | babel-preset-nano-react-app@^0.1.0: | ||
| 350 | version "0.1.0" | ||
| 351 | resolved "https://registry.yarnpkg.com/babel-preset-nano-react-app/-/babel-preset-nano-react-app-0.1.0.tgz#1e33f12e96f7ec9a66de44b5702c8f7c46111f93" | ||
| 352 | integrity sha512-PHBHthxW7nhKS8+WshTv/3q/7vCzYPGVFCN1vKR49Dp8P5YlO3OVhErha/Xj8tNTZs0wnQAZg8Hhbi8rf8du2A== | ||
| 353 | dependencies: | ||
| 354 | "@babel/core" "^7.2.2" | ||
| 355 | "@babel/plugin-proposal-class-properties" "^7.3.0" | ||
| 356 | "@babel/plugin-transform-runtime" "^7.2.0" | ||
| 357 | |||
| 358 | base16@^1.0.0: | ||
| 359 | version "1.0.0" | ||
| 360 | resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" | ||
| 361 | integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= | ||
| 362 | |||
| 363 | binary-extensions@^2.0.0: | ||
| 364 | version "2.2.0" | ||
| 365 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" | ||
| 366 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== | ||
| 367 | |||
| 368 | braces@~3.0.2: | ||
| 369 | version "3.0.2" | ||
| 370 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" | ||
| 371 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== | ||
| 372 | dependencies: | ||
| 373 | fill-range "^7.0.1" | ||
| 374 | |||
| 375 | browserslist@^4.17.5, browserslist@^4.19.1: | ||
| 376 | version "4.19.1" | ||
| 377 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" | ||
| 378 | integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== | ||
| 379 | dependencies: | ||
| 380 | caniuse-lite "^1.0.30001286" | ||
| 381 | electron-to-chromium "^1.4.17" | ||
| 382 | escalade "^3.1.1" | ||
| 383 | node-releases "^2.0.1" | ||
| 384 | picocolors "^1.0.0" | ||
| 385 | |||
| 386 | caniuse-lite@^1.0.30001286: | ||
| 387 | version "1.0.30001295" | ||
| 388 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001295.tgz#68a60f8f0664f342b2835c5d8898b4faea7b3d51" | ||
| 389 | integrity sha512-lSP16vcyC0FEy0R4ECc9duSPoKoZy+YkpGkue9G4D81OfPnliopaZrU10+qtPdT8PbGXad/PNx43TIQrOmJZSQ== | ||
| 390 | |||
| 391 | chalk@^2.0.0: | ||
| 392 | version "2.4.2" | ||
| 393 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" | ||
| 394 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== | ||
| 395 | dependencies: | ||
| 396 | ansi-styles "^3.2.1" | ||
| 397 | escape-string-regexp "^1.0.5" | ||
| 398 | supports-color "^5.3.0" | ||
| 399 | |||
| 400 | "chokidar@>=3.0.0 <4.0.0": | ||
| 401 | version "3.5.2" | ||
| 402 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" | ||
| 403 | integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== | ||
| 404 | dependencies: | ||
| 405 | anymatch "~3.1.2" | ||
| 406 | braces "~3.0.2" | ||
| 407 | glob-parent "~5.1.2" | ||
| 408 | is-binary-path "~2.1.0" | ||
| 409 | is-glob "~4.0.1" | ||
| 410 | normalize-path "~3.0.0" | ||
| 411 | readdirp "~3.6.0" | ||
| 412 | optionalDependencies: | ||
| 413 | fsevents "~2.3.2" | ||
| 414 | |||
| 415 | classnames@^2.3.1: | ||
| 416 | version "2.3.1" | ||
| 417 | resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" | ||
| 418 | integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== | ||
| 419 | |||
| 420 | color-convert@^1.9.0: | ||
| 421 | version "1.9.3" | ||
| 422 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" | ||
| 423 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== | ||
| 424 | dependencies: | ||
| 425 | color-name "1.1.3" | ||
| 426 | |||
| 427 | color-name@1.1.3: | ||
| 428 | version "1.1.3" | ||
| 429 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" | ||
| 430 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= | ||
| 431 | |||
| 432 | convert-source-map@^1.7.0: | ||
| 433 | version "1.8.0" | ||
| 434 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" | ||
| 435 | integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== | ||
| 436 | dependencies: | ||
| 437 | safe-buffer "~5.1.1" | ||
| 438 | |||
| 439 | core-js-compat@^3.18.0: | ||
| 440 | version "3.20.2" | ||
| 441 | resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.2.tgz#d1ff6936c7330959b46b2e08b122a8b14e26140b" | ||
| 442 | integrity sha512-qZEzVQ+5Qh6cROaTPFLNS4lkvQ6mBzE3R6A6EEpssj7Zr2egMHgsy4XapdifqJDGC9CBiNv7s+ejI96rLNQFdg== | ||
| 443 | dependencies: | ||
| 444 | browserslist "^4.19.1" | ||
| 445 | semver "7.0.0" | ||
| 446 | |||
| 447 | cross-fetch@^3.0.4: | ||
| 448 | version "3.1.4" | ||
| 449 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" | ||
| 450 | integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== | ||
| 451 | dependencies: | ||
| 452 | node-fetch "2.6.1" | ||
| 453 | |||
| 454 | csstype@^3.0.2: | ||
| 455 | version "3.0.10" | ||
| 456 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5" | ||
| 457 | integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA== | ||
| 458 | |||
| 459 | debug@^4.1.0, debug@^4.1.1: | ||
| 460 | version "4.3.3" | ||
| 461 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" | ||
| 462 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== | ||
| 463 | dependencies: | ||
| 464 | ms "2.1.2" | ||
| 465 | |||
| 466 | electron-to-chromium@^1.4.17: | ||
| 467 | version "1.4.31" | ||
| 468 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.31.tgz#8d5ccc3f8253cd142b07afaa84f200fd33a7f2a6" | ||
| 469 | integrity sha512-t3XVQtk+Frkv6aTD4RRk0OqosU+VLe1dQFW83MDer78ZD6a52frgXuYOIsLYTQiH2Lm+JB2OKYcn7zrX+YGAiQ== | ||
| 470 | |||
| 471 | esbuild-android-arm64@0.13.15: | ||
| 472 | version "0.13.15" | ||
| 473 | resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" | ||
| 474 | integrity sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg== | ||
| 475 | |||
| 476 | esbuild-darwin-64@0.13.15: | ||
| 477 | version "0.13.15" | ||
| 478 | resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72" | ||
| 479 | integrity sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ== | ||
| 480 | |||
| 481 | esbuild-darwin-arm64@0.13.15: | ||
| 482 | version "0.13.15" | ||
| 483 | resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a" | ||
| 484 | integrity sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ== | ||
| 485 | |||
| 486 | esbuild-freebsd-64@0.13.15: | ||
| 487 | version "0.13.15" | ||
| 488 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85" | ||
| 489 | integrity sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA== | ||
| 490 | |||
| 491 | esbuild-freebsd-arm64@0.13.15: | ||
| 492 | version "0.13.15" | ||
| 493 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52" | ||
| 494 | integrity sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ== | ||
| 495 | |||
| 496 | esbuild-linux-32@0.13.15: | ||
| 497 | version "0.13.15" | ||
| 498 | resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69" | ||
| 499 | integrity sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g== | ||
| 500 | |||
| 501 | esbuild-linux-64@0.13.15: | ||
| 502 | version "0.13.15" | ||
| 503 | resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3" | ||
| 504 | integrity sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA== | ||
| 505 | |||
| 506 | esbuild-linux-arm64@0.13.15: | ||
| 507 | version "0.13.15" | ||
| 508 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1" | ||
| 509 | integrity sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA== | ||
| 510 | |||
| 511 | esbuild-linux-arm@0.13.15: | ||
| 512 | version "0.13.15" | ||
| 513 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe" | ||
| 514 | integrity sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA== | ||
| 515 | |||
| 516 | esbuild-linux-mips64le@0.13.15: | ||
| 517 | version "0.13.15" | ||
| 518 | resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7" | ||
| 519 | integrity sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg== | ||
| 520 | |||
| 521 | esbuild-linux-ppc64le@0.13.15: | ||
| 522 | version "0.13.15" | ||
| 523 | resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2" | ||
| 524 | integrity sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ== | ||
| 525 | |||
| 526 | esbuild-netbsd-64@0.13.15: | ||
| 527 | version "0.13.15" | ||
| 528 | resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038" | ||
| 529 | integrity sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w== | ||
| 530 | |||
| 531 | esbuild-openbsd-64@0.13.15: | ||
| 532 | version "0.13.15" | ||
| 533 | resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7" | ||
| 534 | integrity sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g== | ||
| 535 | |||
| 536 | esbuild-sunos-64@0.13.15: | ||
| 537 | version "0.13.15" | ||
| 538 | resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4" | ||
| 539 | integrity sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw== | ||
| 540 | |||
| 541 | esbuild-windows-32@0.13.15: | ||
| 542 | version "0.13.15" | ||
| 543 | resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7" | ||
| 544 | integrity sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw== | ||
| 545 | |||
| 546 | esbuild-windows-64@0.13.15: | ||
| 547 | version "0.13.15" | ||
| 548 | resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294" | ||
| 549 | integrity sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ== | ||
| 550 | |||
| 551 | esbuild-windows-arm64@0.13.15: | ||
| 552 | version "0.13.15" | ||
| 553 | resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3" | ||
| 554 | integrity sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA== | ||
| 555 | |||
| 556 | esbuild@^0.13.12: | ||
| 557 | version "0.13.15" | ||
| 558 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.15.tgz#db56a88166ee373f87dbb2d8798ff449e0450cdf" | ||
| 559 | integrity sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw== | ||
| 560 | optionalDependencies: | ||
| 561 | esbuild-android-arm64 "0.13.15" | ||
| 562 | esbuild-darwin-64 "0.13.15" | ||
| 563 | esbuild-darwin-arm64 "0.13.15" | ||
| 564 | esbuild-freebsd-64 "0.13.15" | ||
| 565 | esbuild-freebsd-arm64 "0.13.15" | ||
| 566 | esbuild-linux-32 "0.13.15" | ||
| 567 | esbuild-linux-64 "0.13.15" | ||
| 568 | esbuild-linux-arm "0.13.15" | ||
| 569 | esbuild-linux-arm64 "0.13.15" | ||
| 570 | esbuild-linux-mips64le "0.13.15" | ||
| 571 | esbuild-linux-ppc64le "0.13.15" | ||
| 572 | esbuild-netbsd-64 "0.13.15" | ||
| 573 | esbuild-openbsd-64 "0.13.15" | ||
| 574 | esbuild-sunos-64 "0.13.15" | ||
| 575 | esbuild-windows-32 "0.13.15" | ||
| 576 | esbuild-windows-64 "0.13.15" | ||
| 577 | esbuild-windows-arm64 "0.13.15" | ||
| 578 | |||
| 579 | escalade@^3.1.1: | ||
| 580 | version "3.1.1" | ||
| 581 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" | ||
| 582 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== | ||
| 583 | |||
| 584 | escape-string-regexp@^1.0.5: | ||
| 585 | version "1.0.5" | ||
| 586 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" | ||
| 587 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= | ||
| 588 | |||
| 589 | fbemitter@^3.0.0: | ||
| 590 | version "3.0.0" | ||
| 591 | resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3" | ||
| 592 | integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw== | ||
| 593 | dependencies: | ||
| 594 | fbjs "^3.0.0" | ||
| 595 | |||
| 596 | fbjs-css-vars@^1.0.0: | ||
| 597 | version "1.0.2" | ||
| 598 | resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" | ||
| 599 | integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== | ||
| 600 | |||
| 601 | fbjs@^3.0.0, fbjs@^3.0.1: | ||
| 602 | version "3.0.2" | ||
| 603 | resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.2.tgz#dfae08a85c66a58372993ce2caf30863f569ff94" | ||
| 604 | integrity sha512-qv+boqYndjElAJHNN3NoM8XuwQZ1j2m3kEvTgdle8IDjr6oUbkEpvABWtj/rQl3vq4ew7dnElBxL4YJAwTVqQQ== | ||
| 605 | dependencies: | ||
| 606 | cross-fetch "^3.0.4" | ||
| 607 | fbjs-css-vars "^1.0.0" | ||
| 608 | loose-envify "^1.0.0" | ||
| 609 | object-assign "^4.1.0" | ||
| 610 | promise "^7.1.1" | ||
| 611 | setimmediate "^1.0.5" | ||
| 612 | ua-parser-js "^0.7.30" | ||
| 613 | |||
| 614 | fill-range@^7.0.1: | ||
| 615 | version "7.0.1" | ||
| 616 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" | ||
| 617 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== | ||
| 618 | dependencies: | ||
| 619 | to-regex-range "^5.0.1" | ||
| 620 | |||
| 621 | flux@^4.0.1: | ||
| 622 | version "4.0.3" | ||
| 623 | resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.3.tgz#573b504a24982c4768fdfb59d8d2ea5637d72ee7" | ||
| 624 | integrity sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw== | ||
| 625 | dependencies: | ||
| 626 | fbemitter "^3.0.0" | ||
| 627 | fbjs "^3.0.1" | ||
| 628 | |||
| 629 | fsevents@~2.3.2: | ||
| 630 | version "2.3.2" | ||
| 631 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" | ||
| 632 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== | ||
| 633 | |||
| 634 | function-bind@^1.1.1: | ||
| 635 | version "1.1.1" | ||
| 636 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" | ||
| 637 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== | ||
| 638 | |||
| 639 | gensync@^1.0.0-beta.2: | ||
| 640 | version "1.0.0-beta.2" | ||
| 641 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" | ||
| 642 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== | ||
| 643 | |||
| 644 | glob-parent@~5.1.2: | ||
| 645 | version "5.1.2" | ||
| 646 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" | ||
| 647 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== | ||
| 648 | dependencies: | ||
| 649 | is-glob "^4.0.1" | ||
| 650 | |||
| 651 | globals@^11.1.0: | ||
| 652 | version "11.12.0" | ||
| 653 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" | ||
| 654 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== | ||
| 655 | |||
| 656 | has-flag@^3.0.0: | ||
| 657 | version "3.0.0" | ||
| 658 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" | ||
| 659 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= | ||
| 660 | |||
| 661 | has@^1.0.3: | ||
| 662 | version "1.0.3" | ||
| 663 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" | ||
| 664 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== | ||
| 665 | dependencies: | ||
| 666 | function-bind "^1.1.1" | ||
| 667 | |||
| 668 | immutable@^4.0.0: | ||
| 669 | version "4.0.0" | ||
| 670 | resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" | ||
| 671 | integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== | ||
| 672 | |||
| 673 | is-binary-path@~2.1.0: | ||
| 674 | version "2.1.0" | ||
| 675 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" | ||
| 676 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== | ||
| 677 | dependencies: | ||
| 678 | binary-extensions "^2.0.0" | ||
| 679 | |||
| 680 | is-core-module@^2.2.0: | ||
| 681 | version "2.8.0" | ||
| 682 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" | ||
| 683 | integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== | ||
| 684 | dependencies: | ||
| 685 | has "^1.0.3" | ||
| 686 | |||
| 687 | is-extglob@^2.1.1: | ||
| 688 | version "2.1.1" | ||
| 689 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" | ||
| 690 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= | ||
| 691 | |||
| 692 | is-glob@^4.0.1, is-glob@~4.0.1: | ||
| 693 | version "4.0.3" | ||
| 694 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" | ||
| 695 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== | ||
| 696 | dependencies: | ||
| 697 | is-extglob "^2.1.1" | ||
| 698 | |||
| 699 | is-number@^7.0.0: | ||
| 700 | version "7.0.0" | ||
| 701 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" | ||
| 702 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== | ||
| 703 | |||
| 704 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: | ||
| 705 | version "4.0.0" | ||
| 706 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" | ||
| 707 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== | ||
| 708 | |||
| 709 | jsesc@^2.5.1: | ||
| 710 | version "2.5.2" | ||
| 711 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" | ||
| 712 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== | ||
| 713 | |||
| 714 | json5@^2.1.2: | ||
| 715 | version "2.2.0" | ||
| 716 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" | ||
| 717 | integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== | ||
| 718 | dependencies: | ||
| 719 | minimist "^1.2.5" | ||
| 720 | |||
| 721 | lodash.curry@^4.0.1: | ||
| 722 | version "4.1.1" | ||
| 723 | resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" | ||
| 724 | integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA= | ||
| 725 | |||
| 726 | lodash.debounce@^4.0.8: | ||
| 727 | version "4.0.8" | ||
| 728 | resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" | ||
| 729 | integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= | ||
| 730 | |||
| 731 | lodash.flow@^3.3.0: | ||
| 732 | version "3.5.0" | ||
| 733 | resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" | ||
| 734 | integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= | ||
| 735 | |||
| 736 | loose-envify@^1.0.0, loose-envify@^1.1.0: | ||
| 737 | version "1.4.0" | ||
| 738 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" | ||
| 739 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== | ||
| 740 | dependencies: | ||
| 741 | js-tokens "^3.0.0 || ^4.0.0" | ||
| 742 | |||
| 743 | minimist@^1.2.5: | ||
| 744 | version "1.2.5" | ||
| 745 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" | ||
| 746 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== | ||
| 747 | |||
| 748 | ms@2.1.2: | ||
| 749 | version "2.1.2" | ||
| 750 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" | ||
| 751 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== | ||
| 752 | |||
| 753 | nanoid@^3.1.30: | ||
| 754 | version "3.1.30" | ||
| 755 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" | ||
| 756 | integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== | ||
| 757 | |||
| 758 | node-fetch@2.6.1: | ||
| 759 | version "2.6.1" | ||
| 760 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" | ||
| 761 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== | ||
| 762 | |||
| 763 | node-releases@^2.0.1: | ||
| 764 | version "2.0.1" | ||
| 765 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" | ||
| 766 | integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== | ||
| 767 | |||
| 768 | normalize-path@^3.0.0, normalize-path@~3.0.0: | ||
| 769 | version "3.0.0" | ||
| 770 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" | ||
| 771 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== | ||
| 772 | |||
| 773 | object-assign@^4.1.0, object-assign@^4.1.1: | ||
| 774 | version "4.1.1" | ||
| 775 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | ||
| 776 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= | ||
| 777 | |||
| 778 | path-parse@^1.0.6: | ||
| 779 | version "1.0.7" | ||
| 780 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" | ||
| 781 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== | ||
| 782 | |||
| 783 | picocolors@^1.0.0: | ||
| 784 | version "1.0.0" | ||
| 785 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" | ||
| 786 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== | ||
| 787 | |||
| 788 | picomatch@^2.0.4, picomatch@^2.2.1: | ||
| 789 | version "2.3.1" | ||
| 790 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" | ||
| 791 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== | ||
| 792 | |||
| 793 | postcss@^8.4.5: | ||
| 794 | version "8.4.5" | ||
| 795 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" | ||
| 796 | integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== | ||
| 797 | dependencies: | ||
| 798 | nanoid "^3.1.30" | ||
| 799 | picocolors "^1.0.0" | ||
| 800 | source-map-js "^1.0.1" | ||
| 801 | |||
| 802 | promise@^7.1.1: | ||
| 803 | version "7.3.1" | ||
| 804 | resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" | ||
| 805 | integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== | ||
| 806 | dependencies: | ||
| 807 | asap "~2.0.3" | ||
| 808 | |||
| 809 | pure-color@^1.2.0: | ||
| 810 | version "1.3.0" | ||
| 811 | resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" | ||
| 812 | integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= | ||
| 813 | |||
| 814 | react-base16-styling@^0.6.0: | ||
| 815 | version "0.6.0" | ||
| 816 | resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" | ||
| 817 | integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw= | ||
| 818 | dependencies: | ||
| 819 | base16 "^1.0.0" | ||
| 820 | lodash.curry "^4.0.1" | ||
| 821 | lodash.flow "^3.3.0" | ||
| 822 | pure-color "^1.2.0" | ||
| 823 | |||
| 824 | react-dom@^17.0.2: | ||
| 825 | version "17.0.2" | ||
| 826 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" | ||
| 827 | integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== | ||
| 828 | dependencies: | ||
| 829 | loose-envify "^1.1.0" | ||
| 830 | object-assign "^4.1.1" | ||
| 831 | scheduler "^0.20.2" | ||
| 832 | |||
| 833 | react-json-view@^1.21.3: | ||
| 834 | version "1.21.3" | ||
| 835 | resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" | ||
| 836 | integrity sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw== | ||
| 837 | dependencies: | ||
| 838 | flux "^4.0.1" | ||
| 839 | react-base16-styling "^0.6.0" | ||
| 840 | react-lifecycles-compat "^3.0.4" | ||
| 841 | react-textarea-autosize "^8.3.2" | ||
| 842 | |||
| 843 | react-lifecycles-compat@^3.0.4: | ||
| 844 | version "3.0.4" | ||
| 845 | resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" | ||
| 846 | integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== | ||
| 847 | |||
| 848 | react-textarea-autosize@^8.3.2: | ||
| 849 | version "8.3.3" | ||
| 850 | resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8" | ||
| 851 | integrity sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ== | ||
| 852 | dependencies: | ||
| 853 | "@babel/runtime" "^7.10.2" | ||
| 854 | use-composed-ref "^1.0.0" | ||
| 855 | use-latest "^1.0.0" | ||
| 856 | |||
| 857 | react@^17.0.2: | ||
| 858 | version "17.0.2" | ||
| 859 | resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" | ||
| 860 | integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== | ||
| 861 | dependencies: | ||
| 862 | loose-envify "^1.1.0" | ||
| 863 | object-assign "^4.1.1" | ||
| 864 | |||
| 865 | readdirp@~3.6.0: | ||
| 866 | version "3.6.0" | ||
| 867 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" | ||
| 868 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== | ||
| 869 | dependencies: | ||
| 870 | picomatch "^2.2.1" | ||
| 871 | |||
| 872 | regenerator-runtime@^0.13.4: | ||
| 873 | version "0.13.9" | ||
| 874 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" | ||
| 875 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== | ||
| 876 | |||
| 877 | resolve@^1.14.2, resolve@^1.20.0: | ||
| 878 | version "1.20.0" | ||
| 879 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" | ||
| 880 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== | ||
| 881 | dependencies: | ||
| 882 | is-core-module "^2.2.0" | ||
| 883 | path-parse "^1.0.6" | ||
| 884 | |||
| 885 | rollup@^2.59.0: | ||
| 886 | version "2.62.0" | ||
| 887 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.62.0.tgz#9e640b419fc5b9e0241844f6d55258bd79986ecc" | ||
| 888 | integrity sha512-cJEQq2gwB0GWMD3rYImefQTSjrPYaC6s4J9pYqnstVLJ1CHa/aZNVkD4Epuvg4iLeMA4KRiq7UM7awKK6j7jcw== | ||
| 889 | optionalDependencies: | ||
| 890 | fsevents "~2.3.2" | ||
| 891 | |||
| 892 | safe-buffer@~5.1.1: | ||
| 893 | version "5.1.2" | ||
| 894 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" | ||
| 895 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== | ||
| 896 | |||
| 897 | sass@^1.45.2: | ||
| 898 | version "1.45.2" | ||
| 899 | resolved "https://registry.yarnpkg.com/sass/-/sass-1.45.2.tgz#130b428c1692201cfa181139835d6fc378a33323" | ||
| 900 | integrity sha512-cKfs+F9AMPAFlbbTXNsbGvg3y58nV0mXA3E94jqaySKcC8Kq3/8983zVKQ0TLMUrHw7hF9Tnd3Bz9z5Xgtrl9g== | ||
| 901 | dependencies: | ||
| 902 | chokidar ">=3.0.0 <4.0.0" | ||
| 903 | immutable "^4.0.0" | ||
| 904 | source-map-js ">=0.6.2 <2.0.0" | ||
| 905 | |||
| 906 | scheduler@^0.20.2: | ||
| 907 | version "0.20.2" | ||
| 908 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" | ||
| 909 | integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== | ||
| 910 | dependencies: | ||
| 911 | loose-envify "^1.1.0" | ||
| 912 | object-assign "^4.1.1" | ||
| 913 | |||
| 914 | semver@7.0.0: | ||
| 915 | version "7.0.0" | ||
| 916 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" | ||
| 917 | integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== | ||
| 918 | |||
| 919 | semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: | ||
| 920 | version "6.3.0" | ||
| 921 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" | ||
| 922 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== | ||
| 923 | |||
| 924 | setimmediate@^1.0.5: | ||
| 925 | version "1.0.5" | ||
| 926 | resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" | ||
| 927 | integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= | ||
| 928 | |||
| 929 | "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1: | ||
| 930 | version "1.0.1" | ||
| 931 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" | ||
| 932 | integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== | ||
| 933 | |||
| 934 | source-map@^0.5.0: | ||
| 935 | version "0.5.7" | ||
| 936 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" | ||
| 937 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= | ||
| 938 | |||
| 939 | supports-color@^5.3.0: | ||
| 940 | version "5.5.0" | ||
| 941 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" | ||
| 942 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== | ||
| 943 | dependencies: | ||
| 944 | has-flag "^3.0.0" | ||
| 945 | |||
| 946 | to-fast-properties@^2.0.0: | ||
| 947 | version "2.0.0" | ||
| 948 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" | ||
| 949 | integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= | ||
| 950 | |||
| 951 | to-regex-range@^5.0.1: | ||
| 952 | version "5.0.1" | ||
| 953 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" | ||
| 954 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== | ||
| 955 | dependencies: | ||
| 956 | is-number "^7.0.0" | ||
| 957 | |||
| 958 | typescript@^3.8.3: | ||
| 959 | version "3.9.10" | ||
| 960 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" | ||
| 961 | integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== | ||
| 962 | |||
| 963 | ua-parser-js@^0.7.30: | ||
| 964 | version "0.7.31" | ||
| 965 | resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" | ||
| 966 | integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== | ||
| 967 | |||
| 968 | use-composed-ref@^1.0.0: | ||
| 969 | version "1.2.1" | ||
| 970 | resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.2.1.tgz#9bdcb5ccd894289105da2325e1210079f56bf849" | ||
| 971 | integrity sha512-6+X1FLlIcjvFMAeAD/hcxDT8tmyrWnbSPMU0EnxQuDLIxokuFzWliXBiYZuGIx+mrAMLBw0WFfCkaPw8ebzAhw== | ||
| 972 | |||
| 973 | use-isomorphic-layout-effect@^1.0.0: | ||
| 974 | version "1.1.1" | ||
| 975 | resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225" | ||
| 976 | integrity sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ== | ||
| 977 | |||
| 978 | use-latest@^1.0.0: | ||
| 979 | version "1.2.0" | ||
| 980 | resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" | ||
| 981 | integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== | ||
| 982 | dependencies: | ||
| 983 | use-isomorphic-layout-effect "^1.0.0" | ||
| 984 | |||
| 985 | vite@^2.6.7: | ||
| 986 | version "2.7.10" | ||
| 987 | resolved "https://registry.yarnpkg.com/vite/-/vite-2.7.10.tgz#d12c4c10e56a0ecf7890cb529c15996c6111218f" | ||
| 988 | integrity sha512-KEY96ntXUid1/xJihJbgmLZx7QSC2D4Tui0FdS0Old5OokYzFclcofhtxtjDdGOk/fFpPbHv9yw88+rB93Tb8w== | ||
| 989 | dependencies: | ||
| 990 | esbuild "^0.13.12" | ||
| 991 | postcss "^8.4.5" | ||
| 992 | resolve "^1.20.0" | ||
| 993 | rollup "^2.59.0" | ||
| 994 | optionalDependencies: | ||
| 995 | fsevents "~2.3.2" | ||
