From 1293948cf4e0403bf1e9bc00302a0cbf9c5d76a7 Mon Sep 17 00:00:00 2001 From: Becca Petrin Date: Mon, 13 Jul 2020 13:24:54 -0700 Subject: [PATCH] Release/0.1.0 (#130) * set dbauth=yes for main files * use status message for field status * add salt in request * update make proto target * change password field to hashed password * include generated c stubs in gitignore * tidy up Makefile and add protobuf autogenerated .h and .c to make clean * add gen-libpqpatch target to Makefile * edit gen-libpqpatch target to include new files * remove trailing slash in * update hashed pw field name * add dbauth.h abstraction for connecting to Authenticator * compile protobuf c libraries before postgresql * implement sending Authenticator request from C * fix setdbauth=yes in main.c * add authenticator service and build files * add go.mod * remove unnecessary lines in dockerfile * remove unnecessary comments in dockerfile * set gopath in dockerfile * add docker networking between containers * remove docker rm netowrk * add dbauth.h abstraction for connecting to Authenticator * compile protobuf c libraries before postgresql * implement sending Authenticator request from C * fix setdbauth=yes in main.c * add authenticator binary to .gitignore * add logging to authenticator * remove dbauth library for now * move sdk into its own folder * add grpc_cli to authenticator Dockerfile * mount whole dbauth folder in authenticator container * add docker-compose.yml * remove make-run and run-env make targets in favor of docker compose * working cpp sdk for libpq * implement md5 hash on password * include go.sum * add dbauth sdk for libpq * remove authenticator entry from .gitignore * remove authenticator executable * added to test grpc client * change salt and hashed pw to bytes * update authenticator to expect salt and return hashedpw as bytes * fix byte strying compare * change order in Dockerfile for better caching * remove executable from repo * gRPC server listen on all interfaces * client.go: send salt string as bytes * docker-compose spin up go client * makefile target for authenticator * make succeed even if go build fails * change hashedpassword back into a string * implement postgres md5 generation in authenticator * set log level to debug * fix bug in hash computation * update cpp protobuf files * remove cpp testing file * update dbauth_libpq cpp library * remove cpp testing program * libpq dbauth authenticate implementation * add examples dir * add local postgres server to docker-compose * make sdk include ready made dbauth libpq * remove debug statement from dbauth_libpq lib * allow no password if usedbauth is set * move python example to different folder * change C example to use local db * add authenticator executable properly to .gitignore * remove dbauth.h * remove main example program * consolidate sdk/internal to sdk/ * rename dbauth_libpq to dbauth_client * remove authenticator/messages to authenticator/protos * remvoe test.sh script * update authenticator protos and service to split user and hash * favor command to entrypoint * authenticator validate salt to be 4 bytes * update SDK protobuf code * Fix bug using identity instead of user in hash * update client side for separate user and password calls * make gen-libpqpatch idempotent * run go fmt * improve salt error message * working prototype for libhook * working hash computation in Python * remove cpp dependencies from dockerfile * cleanup code * Add aws boto to sdk * move cpp client into separate folder * update authenticator and protos to include AWS IAM authentication * preliminary approzium python module implementation * .gitignore python stuff * obtain grpc tools via pip in dockerfile * IAM-ify GetDBHasher in authenticator * real IAM verification via STS * remove old experiments code * working approzium python module that generates hash * Add client example * cut Dockerfile down * remove examples folder * move logging setup to __init__.py * add setup.py * add readme for sdk * add first test * run black on python sdk * add SSL support * refactor psycopg2 connection code * add tiny C extension to change psycopg2 connection to sync * Revert "add tiny C extension to change psycopg2 connection to sync" This reverts commit c9885301d1278199c342af5be43506bca160a001. * fix merge error * run blackify code * add additional check in sync-ing connection * update protos * update python sdk makefile to output protos in right directory * add authenticator integration to Python sdk * add secrets file to store dev credentials * refactor verify service code * remove Go client * run go fmt * Add authentication challenge verification step * refactor authenticator.go * change all dbauth references to approzium * regression fix * Define ctypes functions arg and res types * Make DSN string a required parameter just like Psycopg2 * Disable autocommit mode in sync connections * Add empty dsn in client.py * change connect interface to fit psycopg2 more * Change authenticator and iam_role to module-level attributes * remove experiment file * blackify imports * update client to new interface * remove dead code * add Psycopg2 test suite to .gitignore * don't change logging level when importing package * Add script that runs PG2 test suite * fix regression * move low-level psycopg2 functions to _psycopg2_ctypes.py * Implemented acknowleged MD5 * setup appropriate module-level logging * Add ssl support to postgres db docker image * Revert acknowledged MD5 authentication * Add SSL db dockerfile * Add scram.pyx file from Asyncpg * Have an MD5 and SHA256 DBs in docker-compose * Add debug statements in client.py * add SCRAM SHA-256 authentication support * Refactor reading Postgres messages * Add Cython to setup.py * Allow authenticator to hold multiple dev credentials * implement PG SHA256 on authenticator side * Implement PG SHA-256 communication on Python SDK * install SDK in editable mode in Docker image * replace assert statements with runtime checks * Add check for openssl * Implement Authenticator object and implement interface around it * Upgrade Pip in SDK dockerfile Upgrading pip is important because it speeds up the installation of gRPC(-tools) considerably. * upate protos of PGSHA256 to be more secure * rename aios_gen_cert.sh * update proto to include whole authentication msg * Update authenticator to return cproof and sproof * add reference wikipedia link * remove manual hash calculation code from Python sdk * Add Vault credential manager * update SDK to use DBPort * Update package name (#37) * Convert variables from snake case to camel case (#38) * Update package name * Convert snake case variables to camel case * Seed Vault in its own test, and add fmt and test to Makefile (#36) * Seed Vault in its own test, and add fmt and test to Makefile * Revert Makefile changes * Delete fmt check script * E2E Docker-compose workflow and CI via Github Actions (#40) * add db common vars to docker-compose file * remvoe gRPC cli from authenticator dockerfile * add ping program to sdk dockerfile * consolite dockerfiles into a multi-stage dockerfile * define tests in docker-compose * prefer secrets file to vault * more accurate Make target name * set psycopg2 testsuite to use Authenticator * Create main.yml * add SSL certs target to Makefile * set COMPOSE_DOCKER_CLI_BUILD=1 in Makefile * remove unnecessary whitespace * add env vars to Makefile * change test target in Makefile * allow passing AWS secrets as env vars * seed vault as part of docker-compose * replace services with one tests service * rename environment variable pg2_testsuite.py * document python SDK test makefile * improved Makefile * remove legacy Makefile target * Add target for seeding Vault with a specific host * ensure SSL before docker build * Update Readme with dev instructions * move around Dockerfile for better caching * fix Python version to 3.7 * Stop using async because it becomes SyntaxError in Python>=3.7 (#42) * Python style fixes and a Go Unittest for xorBytes (#43) * add .flake8 file * Style changes to please Flake8 * Run Python lint commands in correct path * add setup.py to flake8 exclude * Automatic lint Signed-off-by: GitHub Actions Bot * Add pyproject.toml for Black * export Authenticator from __init__.py * add testing for xorBytes func Co-authored-by: UpGado * Automatic lint Signed-off-by: GitHub Actions Bot * Update test (#48) * Improvements to CI (#51) * Remove -diff flag from isort command --diff causes isort to just run a check without actually fixing the cose * Make isort run without asking * Automatic lint Signed-off-by: GitHub Actions Bot * add isort skip protobuf import * Automatic lint Signed-off-by: GitHub Actions Bot * Add run-in-docker target in Makefile * Update main.yml * require certs for run-in-docker * Update main.yml * dont run dc-build on each test * add pytest.ini * add Python tests make target * Update main.yml * Add simple happy-path tests for connections * Automatic lint Signed-off-by: GitHub Actions Bot * require seeding hosts before pytest * Install multiple Python versions * Update main.yml * Update main.yml * Update main.yml * Update main.yml * Update main.yml * Update main.yml * Update main.yml * Update main.yml * Revert "Install multiple Python versions" This reverts commit 7452ed715f9a1bab96f4fe506b294d1fdc91816c. * Update main.yml * Update main.yml * add asnyc_ to test matrix * Automatic lint Signed-off-by: GitHub Actions Bot * run isort on sdk * Automatic lint Signed-off-by: GitHub Actions Bot * Update main.yml Co-authored-by: UpGado * Implement Connection Pool support for Psycopg2 interface (#46) * Stop using async because it becomes SyntaxError in Python>=3.7 * add .flake8 file * Style changes to please Flake8 * Run Python lint commands in correct path * add setup.py to flake8 exclude * Automatic lint Signed-off-by: GitHub Actions Bot * Add pyproject.toml for Black * export Authenticator from __init__.py * Move Psycopg2 into its own submodule * Automatic lint Signed-off-by: GitHub Actions Bot * Add pool.py * move examples to separate folder * add testing for xorBytes func * Automatic lint Signed-off-by: GitHub Actions Bot * remove logging from examples * remove unused import * add clarifying comment * add __init__.py and move functionality to separate file * Automatic lint Signed-off-by: GitHub Actions Bot * remove unused import * add tests for PG2 pool * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: UpGado * Security hardening (#47) * Security hardening * Automatic lint Signed-off-by: GitHub Actions Bot * Update tests * Use role ARN * Support Go calls and aim tests at real AWS * Change verifyIdentity to getIdentity * Fix overzealous find and replace * Update all protobufs and related code * Automatic lint Signed-off-by: GitHub Actions Bot * Update code to match protos * Correct python code type errs * Automatic lint Signed-off-by: GitHub Actions Bot * Update protobufs per discussion * Automatic lint Signed-off-by: GitHub Actions Bot * Update Go tests * Update Makefile * Properly pull env var into Makefile * Try again with TEST_IAM_ROLE * Add env var to workflow yaml * Pass TEST_IAM_ROLE into Python tests too * Confirm Vault secret was fully written * increase err output * Search for role arns in the db * Revert mount change because need to enable build kit Co-authored-by: tyrannosaurus-becks * Add mutex to protect int from races (#54) * Security hardening from fuzzing (#58) * Add fuzzing test for authenticator request receiving methods * Add test for xorBytes * Fix import order * Propagate WriteString err * Add docs (#59) * add gatsby docs * update docs * add makefile for running site * first draft quickstart and overview * rename quickstart file * update quickstart * add architecture diagram * reference arch in overview * Update README with docs and credits (#60) * Add pytest-parallel (#62) * Add support for Asyncpg (#52) * Stop using async because it becomes SyntaxError in Python>=3.7 * add .flake8 file * Style changes to please Flake8 * Run Python lint commands in correct path * add setup.py to flake8 exclude * Automatic lint Signed-off-by: GitHub Actions Bot * Add pyproject.toml for Black * export Authenticator from __init__.py * Move Psycopg2 into its own submodule * Automatic lint Signed-off-by: GitHub Actions Bot * Add pool.py * move examples to separate folder * add testing for xorBytes func * Automatic lint Signed-off-by: GitHub Actions Bot * remove logging from examples * remove unused import * add clarifying comment * add __init__.py and move functionality to separate file * Automatic lint Signed-off-by: GitHub Actions Bot * remove unused import * add tests for PG2 pool * Automatic lint Signed-off-by: GitHub Actions Bot * Implement _postgres/ submodule for common Postgres code * fix bug when multiple messages being parsed * update path of variables * Asyncpg support * Add asyncpg example * style fixes * Automatic lint Signed-off-by: GitHub Actions Bot * remove unused import * add tests for asyncpg support * Automatic lint Signed-off-by: GitHub Actions Bot * Add pytest-asyncio to Dockerfile * add asyncpg to Dockerfile" * Automatic lint Signed-off-by: GitHub Actions Bot * Less intrusive asyncpg connection method * Automatic lint Signed-off-by: GitHub Actions Bot * move connect method behind interface * Automatic lint Signed-off-by: GitHub Actions Bot * Add asyncpg pool functionality * fix missing import * Automatic lint Signed-off-by: GitHub Actions Bot * Implement AuthClient.attribution_info (#63) * Stop using async because it becomes SyntaxError in Python>=3.7 * add .flake8 file * Style changes to please Flake8 * Run Python lint commands in correct path * add setup.py to flake8 exclude * Automatic lint Signed-off-by: GitHub Actions Bot * Add pyproject.toml for Black * export Authenticator from __init__.py * add testing for xorBytes func * Automatic lint Signed-off-by: GitHub Actions Bot * switch around interface * update client to match * Automatic lint Signed-off-by: GitHub Actions Bot * Update code to reference AuthClient * Automatic lint Signed-off-by: GitHub Actions Bot * fix default authenticator for psycopg2 * use default authenticator client in one of tests * Automatic lint Signed-off-by: GitHub Actions Bot * add default auth client to asyncpg test * add use default auth client in asyncpg * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: UpGado * add tests for parse_msg and construct_msg * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: UpGado * Add automatic ARN determination (#64) * Support iam from local environment * Strip unused import * Automatic lint Signed-off-by: GitHub Actions Bot * Automatic lint Signed-off-by: GitHub Actions Bot * Minimize STS calls * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: tyrannosaurus-becks * Add environmental configuration and docs (#69) * Code nit picks (#72) * Move Go code around * Automatic lint Signed-off-by: GitHub Actions Bot * Indicate that the ctx variables are unused * Add increment counter method Co-authored-by: tyrannosaurus-becks * Implement Sphinx integration as a route within Gatsby server (#70) * Switch over to using Poetry * Add Sphinx to project structure * Automatic lint Signed-off-by: GitHub Actions Bot * rename SDK to Languages * rename sphinx title * Gatsby serve static even in develop mode * Automatic lint Signed-off-by: GitHub Actions Bot * Add docs/static/api/ to .gitignore * add test.html static file * Add sphinx to npm build * try to make netlify run Python 3.7 * add runtime.txt * Turn many submodules into private members * Automatic lint Signed-off-by: GitHub Actions Bot * add module to conf.py * add sphinx-apidoc * change theme to default * Automatic lint Signed-off-by: GitHub Actions Bot * install dependencies in netlify * point netlify to use poetry * add pytest-parallel to pyproject.toml * netlify install libpq-dev * move pytest-parallel to dev deps * sudo apt installg * ignore error in netlify env * Update Makefile * Update Makefile * Update pyproject.toml * Update Makefile * Update Makefile * Update Makefile * put psycopg2 back in pyproject.toml * add pytets-asyncio to pyprojecttoml * test * Update Makefile * try run sphinx in poetry * remove psycopg2 on netlify env * ignore many errors * try removing lock file * use sed to remove psycopg2 from deps * sed in place * give up on psycopg2-binary on netlify * Add mock importg * remove psycopg2 when building docs * Update .gitignore * Update Makefile * Delete test.html * Delete tox.ini * Update docs/src/pages/languages/python.mdx Co-authored-by: Becca Petrin * add route paths to language * add routes to pages * update compatibility page * fix working links Co-authored-by: UpGado Co-authored-by: Becca Petrin * Include AWS platforms in docs (#76) * Include AWS platforms in docs * Add quotation marks * Add note that passwords arent in client memory * Update Vault docs * Add support for using a Vault token sink file (#78) * Add Docstrings to Python SDK (#77) * fix lock and pyproject.toml * change docs into one page * remove psycopg2 from import mock * Use psycopg2-binary instead in netlify * restructure package doc page * Add docstrings * Add psycopg2 pool example * fix long lines * add examples to asyncpg docstrings * Add API Doc to TOC * fix long line * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: UpGado * Update docs (#79) * update examples * Fix typo * delete unused code * update overview * update overview * add documentation for setting default auth client * rename api to api reference * add example to Python SDK page * remove examples from sidebar * make examples subheader * remove examples from sidebar * Add JSON attribution_info to authenticator (#84) * Show automatically determiend ARN in attribution_info * Add attribution_info_json to authenticator object * Automatic lint Signed-off-by: GitHub Actions Bot * Add attribution_info_json docstring * Update docstring Co-authored-by: UpGado * Create CODE_OF_CONDUCT.md (#86) * Create CODE_OF_CONDUCT.md * Move code to .github folder * Update issue templates (#87) * Update issue templates * Strip smartphone references * Strip note about browser * Improve server-side logging (#85) * Improve server-side logging * Make redaction less brittle * Add how to securely disclose vulnerabilities and get support (#89) * Add avenue for responsible disclosure and support * Add secure disclosure and support instrucations * Update README.md Co-authored-by: Dio Gado Co-authored-by: Dio Gado * Add readthedocs integration (#90) * explicitly specify master_doc * Automatic lint Signed-off-by: GitHub Actions Bot * add .readthedocs.yml * update readthedocs.yml * Add extra_dependencies to .readthedocs.yml * fix path * Use optional deps in poetry config * Add docs badge to README.md * fix hyperlink * add build status badge * Fix status badge * updated Dockerfile to install all libs * update poetry.lock Co-authored-by: UpGado * Improved protobufs by adding `PasswordRequest` (#93) * Update protobufs on Authenticator side * Update Makefile for new directory structure * Update gRPC code in Python SDK * Automatic lint Signed-off-by: GitHub Actions Bot * remove oneof in protobut because it complicates Go code * Update Go tests for new protobufs * Automatic lint Signed-off-by: GitHub Actions Bot * Pass logger to getPassword Co-authored-by: UpGado * Disable test parallelism (#91) * Fix isort change in Github actions workflow (#97) * Update main.yml * Update main.yml * Automatic lint Signed-off-by: GitHub Actions Bot * Fix lint tools versions in CI Co-authored-by: UpGado * Skip flaky test (#98) * Add MySQL connector support (#94) * Update protobufs on Authenticator side * Update Makefile for new directory structure * Update gRPC code in Python SDK * Automatic lint Signed-off-by: GitHub Actions Bot * remove oneof in protobut because it complicates Go code * Update Go tests for new protobufs * Automatic lint Signed-off-by: GitHub Actions Bot * Add MySQL connector support to Python SDK * Add MySQL SHA1 hash support to Authenticator * Add MYSQL methods to Authenticator * Add import _mysql * Add MySQL connector to pyproject.toml * Automatic lint Signed-off-by: GitHub Actions Bot * Update poetry.lock * Update Makefile and docker-compose files to add MySQL * Update Python SDK protobuf * Automatic lint Signed-off-by: GitHub Actions Bot * add docstring to MySQL * Add MySQL connector example * fix long line * Add doc section for approzium.mysql.connector * fix indentation * patch MySQLConnection instead of its property * Automatic lint Signed-off-by: GitHub Actions Bot * Add _parse_kwargs func * Add MySQL connector pooling * Add MySQL pool example * Add MySQL pool example * remove unused imports * Automatic lint Signed-off-by: GitHub Actions Bot * Add MySQL pooling to docs * Add tests for authenticator.GetMYSQLSHA1Hash * Automatic lint Signed-off-by: GitHub Actions Bot * Specify sha1 in mysql server host name * correct service name in docker-compose.test.yml * Fix hostname in Makefile * Automatic lint Signed-off-by: GitHub Actions Bot * Remove log statement in favor of reqlogger * Add fuzz test for MySQLSHA1 * Automatic lint Signed-off-by: GitHub Actions Bot * fix pass logger instead of context * Fix passing authenticator in MySQL connector * Automatic lint Signed-off-by: GitHub Actions Bot * Automatic lint Signed-off-by: GitHub Actions Bot * Fix MySQL _parse_kwargs * Add MySQL connector pool test * Automatic lint Signed-off-by: GitHub Actions Bot * Rename HOST to ADDR to be more precise in Makefile * update compatibility page * Add note to MySQL connector docstring * change API doc page title * update MySQL connector example * Update API reference page title * Automatic lint Signed-off-by: GitHub Actions Bot Co-authored-by: UpGado Co-authored-by: Becca Petrin Co-authored-by: tyrannosaurus-becks * Add server-side metrics with Prometheus support (#95) * Add server-side metrics with Prometheus support * Add health endpoint and document HA (#96) * Automatic lint Signed-off-by: GitHub Actions Bot * Improve column label * Add authType type * Automatic lint Signed-off-by: GitHub Actions Bot * Add link to configuration docs * Automatic lint Signed-off-by: GitHub Actions Bot * Update gRPC port from 6000 to 6001 * Add metric tracker for new request * Update new test Co-authored-by: tyrannosaurus-becks * Improve Python SDK Docs (#100) * Update protobufs on Authenticator side * Update Makefile for new directory structure * Update gRPC code in Python SDK * Automatic lint Signed-off-by: GitHub Actions Bot * remove oneof in protobut because it complicates Go code * Update Go tests for new protobufs * Automatic lint Signed-off-by: GitHub Actions Bot * Add MySQL connector support to Python SDK * Add MySQL SHA1 hash support to Authenticator * Add MYSQL methods to Authenticator * Add import _mysql * Add MySQL connector to pyproject.toml * Automatic lint Signed-off-by: GitHub Actions Bot * Update poetry.lock * Update Makefile and docker-compose files to add MySQL * Update Python SDK protobuf * Automatic lint Signed-off-by: GitHub Actions Bot * add docstring to MySQL * Add MySQL connector example * fix long line * Add doc section for approzium.mysql.connector * fix indentation * patch MySQLConnection instead of its property * Automatic lint Signed-off-by: GitHub Actions Bot * Add _parse_kwargs func * Add MySQL connector pooling * Add MySQL pool example * Add MySQL pool example * remove unused imports * Automatic lint Signed-off-by: GitHub Actions Bot * Add MySQL pooling to docs * Add tests for authenticator.GetMYSQLSHA1Hash * Automatic lint Signed-off-by: GitHub Actions Bot * Specify sha1 in mysql server host name * correct service name in docker-compose.test.yml * Fix hostname in Makefile * Automatic lint Signed-off-by: GitHub Actions Bot * Remove log statement in favor of reqlogger * Add fuzz test for MySQLSHA1 * Automatic lint Signed-off-by: GitHub Actions Bot * fix pass logger instead of context * Fix passing authenticator in MySQL connector * Automatic lint Signed-off-by: GitHub Actions Bot * Automatic lint Signed-off-by: GitHub Actions Bot * Fix MySQL _parse_kwargs * Add MySQL connector pool test * Automatic lint Signed-off-by: GitHub Actions Bot * Rename HOST to ADDR to be more precise in Makefile * update compatibility page * Add note to MySQL connector docstring * change API doc page title * update MySQL connector example * Update API reference page title * Add getting started page * Add link * try to add link * add getting-started to TOC * add getting-started to TOC * mend * mend * mend * add table * update table * update table * update table * update table * update table * Add Usage section * Update userguide * Update userguide * add other links to TOC * add slack link * Specify readthedocs theme * flatten headers in userguide.rst * flatten headers in userguide.rst * Flatten API docs * Add a word * Add link to general documentationg * fix link * add examples page * Consolidate examples * Reference examples files in docs * Fix multiline docstring * remove old examples * fix mysql connector example * Automatic lint Signed-off-by: GitHub Actions Bot * Change port 6000 to 6001 in examples Co-authored-by: UpGado * Split CI workflow into test and lint workflows (#101) * Split workflow into two workflows * Add names to workflows * Separate badges in README.md * Enable testing with base AWS identity and optionally with assumable AWS role (#105) * Update README * Rename examples to avoid namespace conflict * Automatically determine IAM_TEST_ROLE * WIP update README.md instructions * WIP update README.md instructions * Rename TEST_IAM_ROLE to TEST_ASSUMABLE_ARN * Automatic lint Signed-off-by: GitHub Actions Bot * Add TEST_BASE_ARN to seed commands * README: add instruction to enable approzium path * Run Python tests using both base and assumable AWS roles * Automatic lint Signed-off-by: GitHub Actions Bot * more beautiful Makefile * Rename variable in test workflow * one less hop in Makefile * reqire dc-build before test target * less redundant * update outdated term * remove dead code * Make TestMetrics an acceptance test Co-authored-by: Becca Petrin Co-authored-by: UpGado * Add ability to configure authenticator using config YAML (#106) * Use cleanenv for config reading * run go mod tidy * Add read config from file option * Add note to self to update docs * Add table to configuation page * Remove building Python docs in Netlify * Complete table * Finish configuration table * remove old tag * Better comment * Automatic lint Signed-off-by: GitHub Actions Bot * Update configuration page * Switch to viper * remove comment * Add reading config from yaml: * update configuration doc * Automatic lint Signed-off-by: GitHub Actions Bot * empty approzium_config.yml * Fix redefining pflags on each invocation * Automatic lint Signed-off-by: GitHub Actions Bot * Rename approzium_config.yml to approzium.config.yml * add example data in approzium.config.yml * clarify doc Co-authored-by: UpGado * Fix running approzium.psycopg2 on OSX (#109) * use find_library to find libpq * add warning to approzium.psycopg2.connect * Replace approzium org with cyralinc (#114) * Create LICENSE (#115) * Update issue templates (#116) * Create CONTRIBUTING.md (#117) * Create CONTRIBUTING.md * Move to .github folder * fix examples paths (#122) * Docasaurus (#110) * init docasaurus * transfer existing content from docz to docasaurus * add .DS_Store to .gitignore * add architecture diagram * add logo, change colors * add @docusaurus/plugin-ideal-image * add makefile * remove docasaurus docs * update link to python client library api * add roadmap to sidebar * add security model to docs * nit pick * Add external link symbol for Python API doc * fix broken links on overview page * remove features * Add examples page * udpate overview * update home page * add info modal * update css * update docasaurus config * move documentaiton navlink * swizzle footer and navbar * swizzle codeblock * fix info modal styling * fix info modal interaction * style code, links * adjust code margin * update button color * update code styling * add blurb for architecture diagram * init docasaurus * transfer existing content from docz to docasaurus * add .DS_Store to .gitignore * add architecture diagram * add logo, change colors * add @docusaurus/plugin-ideal-image * add makefile * remove docasaurus docs * update link to python client library api * add roadmap to sidebar * add security model to docs * nit pick * Add external link symbol for Python API doc * fix broken links on overview page * Add examples page * remove features * udpate overview * update home page * add info modal * update css * update docasaurus config * move documentaiton navlink * swizzle footer and navbar * swizzle codeblock * fix info modal styling * fix info modal interaction * style code, links * adjust code margin * update button color * add blurb for architecture diagram * update code styling * updated configuration docs Co-authored-by: Dio Gado * Add support for TLS and dev mode (#111) * Add support for TLS and dev mode * Update health check * Always err when TLS is enabled but no cert/key * Fix err output * Changes from feedback * Fix linting issues * Automatic lint Signed-off-by: GitHub Actions Bot * Fix conftest.py * Fix incorrect parameter * Continue to fix the trail of typos * Add disable_tls param to AuthClient * Move TLS example * Remove diff markup * Add TLS example Co-authored-by: tyrannosaurus-becks * Add ability to cut binaries (#124) * split authenticator into two images (#128) Co-authored-by: root Co-authored-by: Timothy Nguyen Co-authored-by: Dio Gado Co-authored-by: Timothy Nguyen Co-authored-by: Dio Gado Co-authored-by: UpGado Co-authored-by: tyrannosaurus-becks --- .github/CODE_OF_CONDUCT.md | 76 + .github/CONTRIBUTING.md | 15 + .github/ISSUE_TEMPLATE/bug_report.md | 31 + .github/ISSUE_TEMPLATE/feature_request.md | 20 + .github/workflows/lint.yml | 34 + .github/workflows/test.yml | 30 + .gitignore | 217 + .readthedocs.yml | 24 + Dockerfile | 51 + LICENSE | 201 + Makefile | 69 + README.md | 60 +- authenticator/Makefile | 17 + authenticator/README.md | 24 + authenticator/approzium.config.yml | 6 + authenticator/go.mod | 25 + authenticator/go.sum | 465 + authenticator/main.go | 86 + authenticator/scripts/build.sh | 92 + authenticator/server/api/api.go | 74 + authenticator/server/api/health.go | 28 + authenticator/server/api/health_test.go | 21 + authenticator/server/authenticator.go | 397 + authenticator/server/authenticator_test.go | 440 + authenticator/server/config/config.go | 158 + authenticator/server/config/config_test.go | 47 + authenticator/server/credmgrs/credmgr.go | 152 + authenticator/server/credmgrs/hc_vault.go | 127 + .../server/credmgrs/hc_vault_test.go | 149 + authenticator/server/credmgrs/local_file.go | 84 + authenticator/server/identity/aws.go | 205 + authenticator/server/identity/aws_test.go | 73 + authenticator/server/identity/provider.go | 161 + authenticator/server/metrics/registry.go | 12 + .../server/protos/authenticator.pb.go | 683 + .../server/protos/authenticator.proto | 63 + authenticator/server/requestlogger.go | 198 + authenticator/server/requestmetrics.go | 117 + authenticator/server/testing/approzium.key | 51 + authenticator/server/testing/approzium.pem | 31 + authenticator/server/testing/awsutil.go | 56 + authenticator/server/testing/ca.cert | 28 + authenticator/server/testing/ca.key | 51 + authenticator/server/testing/client.key | 51 + authenticator/server/testing/client.pem | 30 + authenticator/server/testing/prometheus.txt | 39 + authenticator/server/testing/secrets.yaml | 21 + authenticator/server/testing/testutil.go | 43 + docker-compose.test.yml | 34 + docker-compose.yml | 47 + docs/.gitignore | 20 + docs/Makefile | 23 + docs/README.md | 24 + docs/babel.config.js | 3 + docs/docs/architecture.mdx | 15 + docs/docs/compatibility.mdx | 15 + docs/docs/configuration.mdx | 35 + docs/docs/examples.mdx | 98 + docs/docs/images/architecture-diagram.png | Bin 0 -> 142844 bytes docs/docs/images/overview-diagram.png | Bin 0 -> 86212 bytes docs/docs/observability.mdx | 83 + docs/docs/overview.md | 57 + docs/docs/quickstart.mdx | 73 + docs/docs/roadmap.mdx | 25 + docs/docs/security-model.mdx | 26 + docs/docusaurus.config.js | 56 + docs/package.json | 44 + docs/sidebars.js | 22 + docs/src/css/custom.css | 60 + docs/src/pages/components/InfoModal/index.js | 78 + .../components/InfoModal/styles.module.css | 83 + docs/src/pages/index.js | 45 + docs/src/pages/styles.module.css | 84 + docs/src/theme/CodeBlock/index.js | 246 + docs/src/theme/CodeBlock/styles.module.css | 66 + docs/src/theme/Footer/index.js | 128 + docs/src/theme/Footer/styles.module.css | 19 + docs/src/theme/Navbar/index.js | 349 + docs/src/theme/Navbar/styles.module.css | 51 + docs/static/.nojekyll | 0 docs/static/img/apzm-icon.png | Bin 0 -> 11511 bytes docs/yarn.lock | 10296 ++++++++++++++++ sdk/python/.flake8 | 12 + sdk/python/Makefile | 23 + sdk/python/README.md | 1 + sdk/python/approzium/__init__.py | 19 + sdk/python/approzium/_authenticator.py | 236 + sdk/python/approzium/_iam.py | 38 + sdk/python/approzium/_misc.py | 9 + sdk/python/approzium/_mysql/__init__.py | 17 + sdk/python/approzium/_postgres/__init__.py | 116 + sdk/python/approzium/_postgres/scram.py | 125 + .../approzium/_protos/authenticator_pb2.py | 518 + .../_protos/authenticator_pb2_grpc.py | 127 + sdk/python/approzium/_socketfromfd.py | 92 + sdk/python/approzium/asyncpg/__init__.py | 3 + .../approzium/asyncpg/_asyncpg_connect.py | 132 + sdk/python/approzium/asyncpg/pool.py | 104 + sdk/python/approzium/mysql/__init__.py | 0 .../approzium/mysql/connector/__init__.py | 3 + .../approzium/mysql/connector/_connect.py | 113 + .../approzium/mysql/connector/pooling.py | 13 + sdk/python/approzium/psycopg2/__init__.py | 3 + .../approzium/psycopg2/_psycopg2_connect.py | 121 + .../approzium/psycopg2/_psycopg2_ctypes.py | 141 + sdk/python/approzium/psycopg2/pool.py | 41 + sdk/python/docs/Makefile | 20 + sdk/python/docs/make.bat | 35 + sdk/python/docs/source/api.rst | 48 + sdk/python/docs/source/conf.py | 56 + sdk/python/docs/source/examples.rst | 29 + sdk/python/docs/source/index.rst | 53 + sdk/python/docs/source/userguide.rst | 64 + sdk/python/examples/asyncpg_connect.py | 27 + .../examples/mysql_connector_connect.py | 25 + sdk/python/examples/psycopg2_connect.py | 16 + sdk/python/poetry.lock | 628 + sdk/python/pyproject.toml | 46 + sdk/python/pytest.ini | 3 + sdk/python/tests/conftest.py | 41 + sdk/python/tests/run_pg2_testsuite.py | 66 + sdk/python/tests/test__postgres.py | 30 + sdk/python/tests/test_approzium_sdk.py | 8 + sdk/python/tests/test_asyncpg_connect.py | 38 + sdk/python/tests/test_mysql_connect.py | 34 + sdk/python/tests/test_psycopg2_connect.py | 66 + ssl/Dockerfile | 6 + ssl/gen_cert.sh | 62 + 128 files changed, 20745 insertions(+), 1 deletion(-) create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .readthedocs.yml create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 authenticator/Makefile create mode 100644 authenticator/README.md create mode 100644 authenticator/approzium.config.yml create mode 100644 authenticator/go.mod create mode 100644 authenticator/go.sum create mode 100644 authenticator/main.go create mode 100755 authenticator/scripts/build.sh create mode 100644 authenticator/server/api/api.go create mode 100644 authenticator/server/api/health.go create mode 100644 authenticator/server/api/health_test.go create mode 100644 authenticator/server/authenticator.go create mode 100644 authenticator/server/authenticator_test.go create mode 100644 authenticator/server/config/config.go create mode 100644 authenticator/server/config/config_test.go create mode 100644 authenticator/server/credmgrs/credmgr.go create mode 100644 authenticator/server/credmgrs/hc_vault.go create mode 100644 authenticator/server/credmgrs/hc_vault_test.go create mode 100644 authenticator/server/credmgrs/local_file.go create mode 100644 authenticator/server/identity/aws.go create mode 100644 authenticator/server/identity/aws_test.go create mode 100644 authenticator/server/identity/provider.go create mode 100644 authenticator/server/metrics/registry.go create mode 100644 authenticator/server/protos/authenticator.pb.go create mode 100644 authenticator/server/protos/authenticator.proto create mode 100644 authenticator/server/requestlogger.go create mode 100644 authenticator/server/requestmetrics.go create mode 100644 authenticator/server/testing/approzium.key create mode 100644 authenticator/server/testing/approzium.pem create mode 100644 authenticator/server/testing/awsutil.go create mode 100644 authenticator/server/testing/ca.cert create mode 100644 authenticator/server/testing/ca.key create mode 100644 authenticator/server/testing/client.key create mode 100644 authenticator/server/testing/client.pem create mode 100644 authenticator/server/testing/prometheus.txt create mode 100644 authenticator/server/testing/secrets.yaml create mode 100644 authenticator/server/testing/testutil.go create mode 100644 docker-compose.test.yml create mode 100644 docker-compose.yml create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/README.md create mode 100644 docs/babel.config.js create mode 100644 docs/docs/architecture.mdx create mode 100644 docs/docs/compatibility.mdx create mode 100644 docs/docs/configuration.mdx create mode 100644 docs/docs/examples.mdx create mode 100644 docs/docs/images/architecture-diagram.png create mode 100644 docs/docs/images/overview-diagram.png create mode 100644 docs/docs/observability.mdx create mode 100644 docs/docs/overview.md create mode 100644 docs/docs/quickstart.mdx create mode 100644 docs/docs/roadmap.mdx create mode 100644 docs/docs/security-model.mdx create mode 100644 docs/docusaurus.config.js create mode 100644 docs/package.json create mode 100644 docs/sidebars.js create mode 100644 docs/src/css/custom.css create mode 100644 docs/src/pages/components/InfoModal/index.js create mode 100644 docs/src/pages/components/InfoModal/styles.module.css create mode 100644 docs/src/pages/index.js create mode 100644 docs/src/pages/styles.module.css create mode 100644 docs/src/theme/CodeBlock/index.js create mode 100644 docs/src/theme/CodeBlock/styles.module.css create mode 100644 docs/src/theme/Footer/index.js create mode 100644 docs/src/theme/Footer/styles.module.css create mode 100644 docs/src/theme/Navbar/index.js create mode 100644 docs/src/theme/Navbar/styles.module.css create mode 100644 docs/static/.nojekyll create mode 100644 docs/static/img/apzm-icon.png create mode 100644 docs/yarn.lock create mode 100644 sdk/python/.flake8 create mode 100644 sdk/python/Makefile create mode 100644 sdk/python/README.md create mode 100644 sdk/python/approzium/__init__.py create mode 100644 sdk/python/approzium/_authenticator.py create mode 100644 sdk/python/approzium/_iam.py create mode 100644 sdk/python/approzium/_misc.py create mode 100644 sdk/python/approzium/_mysql/__init__.py create mode 100644 sdk/python/approzium/_postgres/__init__.py create mode 100644 sdk/python/approzium/_postgres/scram.py create mode 100644 sdk/python/approzium/_protos/authenticator_pb2.py create mode 100644 sdk/python/approzium/_protos/authenticator_pb2_grpc.py create mode 100644 sdk/python/approzium/_socketfromfd.py create mode 100644 sdk/python/approzium/asyncpg/__init__.py create mode 100644 sdk/python/approzium/asyncpg/_asyncpg_connect.py create mode 100644 sdk/python/approzium/asyncpg/pool.py create mode 100644 sdk/python/approzium/mysql/__init__.py create mode 100644 sdk/python/approzium/mysql/connector/__init__.py create mode 100644 sdk/python/approzium/mysql/connector/_connect.py create mode 100644 sdk/python/approzium/mysql/connector/pooling.py create mode 100644 sdk/python/approzium/psycopg2/__init__.py create mode 100644 sdk/python/approzium/psycopg2/_psycopg2_connect.py create mode 100644 sdk/python/approzium/psycopg2/_psycopg2_ctypes.py create mode 100644 sdk/python/approzium/psycopg2/pool.py create mode 100644 sdk/python/docs/Makefile create mode 100644 sdk/python/docs/make.bat create mode 100644 sdk/python/docs/source/api.rst create mode 100644 sdk/python/docs/source/conf.py create mode 100644 sdk/python/docs/source/examples.rst create mode 100644 sdk/python/docs/source/index.rst create mode 100644 sdk/python/docs/source/userguide.rst create mode 100644 sdk/python/examples/asyncpg_connect.py create mode 100644 sdk/python/examples/mysql_connector_connect.py create mode 100644 sdk/python/examples/psycopg2_connect.py create mode 100644 sdk/python/poetry.lock create mode 100644 sdk/python/pyproject.toml create mode 100644 sdk/python/pytest.ini create mode 100644 sdk/python/tests/conftest.py create mode 100644 sdk/python/tests/run_pg2_testsuite.py create mode 100644 sdk/python/tests/test__postgres.py create mode 100644 sdk/python/tests/test_approzium_sdk.py create mode 100644 sdk/python/tests/test_asyncpg_connect.py create mode 100644 sdk/python/tests/test_mysql_connect.py create mode 100644 sdk/python/tests/test_psycopg2_connect.py create mode 100644 ssl/Dockerfile create mode 100755 ssl/gen_cert.sh diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..e8957292 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at product@cyral.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..2f79a78f --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Contributing + +We appreciate community pull requests and have placed this guide here to help you write a complete pull request +in as few iterations as possible. + +A PR that's ready for review has the following components: + +- The code that's being changed. +- Acceptance tests that cover the code's sunny path for all changed fields. +- Updated docs. +- A link to any issues the PR closes, though it isn't required that a PR be related to an open issue. + +Thank you! + +:+1::tada: diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..c616fa35 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..11fc491e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..f3df8420 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,34 @@ +name: lint +on: + push: + branches: [ '*' ] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: gofmt + run: gofmt -s -w . + + - name: Setup Python + uses: actions/setup-python@v1 + with: + python-version: 3.7 + + - name: Install Python lint libraries + run: | + pip install isort==5.0.2 black==19.10b0 flake8==3.8.3 + + - run: cd sdk/python && isort . + - run: cd sdk/python && black . + - run: cd sdk/python && flake8 + + # commit changes + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Automatic lint + commit_options: '--no-verify --signoff' + repository: . + commit_user_name: GitHub Actions Bot diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..2e1dda38 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: test +on: + push: + branches: [ '*' ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Run docker-compose build + run: make dc-build + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Run Go tests + run: make run-in-docker CMD="make run-gotests" + env: + TEST_ASSUMABLE_ARN: ${{ secrets.TEST_ASSUMABLE_ARN }} + + - name: Run Python tests + run: make run-in-docker CMD="make run-pythontests" + env: + TEST_ASSUMABLE_ARN: ${{ secrets.TEST_ASSUMABLE_ARN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c534f35c --- /dev/null +++ b/.gitignore @@ -0,0 +1,217 @@ +.DS_Store + +# Sphinx built documentation +sdk/python/docs/build/ +# Automatically built documentation is below to the path below before serving. +docs/static/api/ +# executables +authenticator/authenticator +main + +ssl/*.key +ssl/*.crt +ssl/*.srl +ssl/*.csr +sdk/python/tests/pg2_testsuite/ + +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.idea/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# Vendored libraries +vendor/ + +# Test resources +.srl + +# Binaries + +authenticator/bin +authenticator/pkg diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..46865829 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,24 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: sdk/python/docs/source/conf.py + + +# Optionally build your docs in additional formats such as PDF +formats: + - pdf + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.7 + install: + - method: pip + path: sdk/python + extra_requirements: + - sqllibs diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..907c723e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +# syntax=docker/dockerfile:1.0-experimental +FROM golang:1.13 AS dev +ENV HOME /root +ENV GOPATH /usr +# enable GOMODULES +ENV GO111MODULE on +ENV CGO_ENABLED 0 +# Nice to haves for development +RUN apt-get update && apt-get install -y iputils-ping vim +# Install protoc-gen-go +RUN go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.3 +# Install protobuf compiler +RUN apt-get install -y unzip +RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.7.0/protoc-3.7.0-linux-x86_64.zip +RUN unzip protoc-3.7.0-linux-x86_64.zip -d protoc3 +RUN mv protoc3/bin/* /usr/local/bin/ +RUN mv protoc3/include/* /usr/local/include/ +# Install Vault CLI for ease of testing Vault out +RUN wget https://releases.hashicorp.com/vault/1.4.2/vault_1.4.2_linux_amd64.zip +RUN unzip vault_1.4.2_linux_amd64.zip +RUN mv vault /usr/local/bin/ +RUN apt-get install -y \ + build-essential \ + libpq-dev \ + python3.7 \ + python3.7-dev \ + python3-pip \ + python3-venv +RUN pip3 install poetry tox +WORKDIR /usr/src/approzium/sdk/python +COPY sdk/python . +RUN poetry run pip install -U pip setuptools +RUN poetry install --extras "sqllibs" +# Build Authenticator Go Binary +WORKDIR /usr/src/approzium/authenticator +COPY authenticator/ . +RUN --mount=type=cache,target=$GOPATH/pkg/mod go build + +FROM alpine:latest AS authenticator-build +WORKDIR /app/ +COPY --from=dev /usr/src/approzium/authenticator/authenticator . +ENTRYPOINT ["./authenticator"] + +FROM authenticator-build AS authenticator-dev +COPY --from=dev /usr/src/approzium/authenticator/server/testing/approzium.pem . +RUN chmod 644 /app/approzium.pem +COPY --from=dev /usr/src/approzium/authenticator/server/testing/approzium.key . +RUN chmod 644 /app/approzium.key +RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* +COPY --from=dev /usr/src/approzium/authenticator/server/testing/ca.cert /usr/local/share/ca-certificates/self-signed-ca.cert +RUN chmod 644 /usr/local/share/ca-certificates/self-signed-ca.cert && update-ca-certificates diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..38d82c86 --- /dev/null +++ b/Makefile @@ -0,0 +1,69 @@ +# Targets that can be run from host machine + +# following lines sets the TEST_BASE_ARN to the value reported by AWS CLI if it is not +# already set as an environment variable +TEST_BASE_ARN?=$(export AWS_PAGER="" && aws sts get-caller-identity --query Arn --output text) + +# Starts a bash shell in the dev environment +dev: + make run-in-docker CMD="bash" +dev-env: dc-build + $(docker_env) docker-compose up +dc-build: ssl/rootCA.key + $(docker_env) docker-compose -f docker-compose.yml -f docker-compose.test.yml build +test: dc-build + make run-in-docker CMD="make run-testsuite" + +# PARAMETERS USED FOR TESTS +TEST_DBADDRS=dbmd5:5432 dbsha256:5432 dbmysqlsha1:3306 +TEST_DB=db +TEST_DBPORT=5432 +TEST_DBPASS=password +TEST_DBUSER=bob + + +### Anything below here is implementation details ### + +# This target just saves a bit of typing +# It takes argument CMD and runs it in the tests service +run-in-docker: + $(docker_env) $(testsuite_env) docker-compose $(dc_files) run tests $(CMD) + +dc_files=-f docker-compose.yml -f docker-compose.test.yml +# Enable Buildkit in docker commands +docker_env=COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 + +vault_secret = { $\ +"password": "$(TEST_DBPASS)", $\ +"iam_arns": [ $\ + "${TEST_ASSUMABLE_ARN}", $\ + "${TEST_BASE_ARN}" $\ +] $\ +} +testsuite_env = TEST_ASSUMABLE_ARN=$(TEST_ASSUMABLE_ARN) TEST_BASE_ARN=$(value TEST_BASE_ARN) $\ + PSYCOPG2_TESTDB=$(TEST_DB) PSYCOPG2_TESTDB_ADDR=$(TEST_DBADDR) $\ + PSYCOPG2_TESTDB_PORT=$(TEST_DBPORT) PSYCOPG2_TESTDB_USER=$(TEST_DBUSER) + + +# Generates self-signed certificates that can be used to run Postgres DBs with SSL +ssl/rootCA.key: + cd ssl && ./gen_cert.sh + +# Following targets are called by the `tests` Docker compose service +enable-vault-path: + vault secrets enable -path=approzium -version=1 kv | true +seed-vault-addr: # call this with "make seed-vault-addr ADDR=foo" + echo '{"$(TEST_DBUSER)": $(vault_secret)}' | \ + vault write approzium/$(ADDR) - +seed-vault-all-addrs: + for ADDR in $(TEST_DBADDRS); do \ + make seed-vault-addr ADDR=$$ADDR; \ + done + +run-testsuite: run-gotests run-pg2tests + +run-gotests: + cd authenticator && CGO_ENABLED=1 go test -v -race -p 1 ./... + +run-pythontests: enable-vault-path seed-vault-all-addrs + cd sdk/python && poetry run pytest --workers auto diff --git a/README.md b/README.md index 338e66c0..e8e4c106 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# approzium \ No newline at end of file +# approzium + +![test](https://github.com/cyralinc/approzium/workflows/test/badge.svg) +![lint](https://github.com/cyralinc/approzium/workflows/lint/badge.svg) +[![Documentation Status](https://readthedocs.org/projects/approzium/badge/?version=latest)](http://approzium.readthedocs.io/?badge=latest) + +Approzium provides SDKs that allow you to authenticate to a database without ever having access to its password. Your +identity is provided through the platform on which you're running. + +---- + +**Please note**: We take Approzium's security and our users' trust very seriously. If you believe you have found a security issue in Approzium, _please responsibly disclose_ by contacting us at [security@cyral.com](mailto:security@cyral.com). + +---- + +We currently support AWS for identity, and have a Python SDK for Postgres drivers. This project is under active development, please +do stay tuned for more identity platforms, databases, and SDK languages. + +## Docs + +See https://approzium.org/ for a Quick Start, or elaboration on the architecture and API. + +## Support + +For questions, please either open a Github issue, or visit us in our public Slack channel. + +To visit us in Slack, use [this invite](https://join.slack.com/t/approzium/shared_invite/zt-fg9bdcfa-H9YFnlg3XeosKyMIYadmcg). +Then venture to [# help-and-questions](https://app.slack.com/client/T013VTLTTJ5/C013FTJPAN9). +Our developers frequent our Slack forum, but are not in it at all times. Please be patient, we will lend assistance as +soon as we can! + +## Developing + +We welcome community contributions! + +We use `docker-compose.yml` to quickly and easily provide you with a development environment that mimics real life. +To spin up an end-to-end development environment based in Docker: + +- Ensure you have [Docker](https://www.docker.com/) installed with Buildkit support (Docker 18.09 or higher) +- In your local environment, run `$ aws configure` and add an access key and secret. +- Run `$ make dc-build`. This will build the authenticator and development Docker images. +- Run `$ docker-compose up`. This will run the authenticator with a Vault backend and will run test database servers (Postgres and MySQL). +- In another window, `$ make dev`. This will start a shell in the development environment. +- You now have a full development and testing environment! +- For example, to use our Python SDK to create an Approzium connection to a Postgres server: + * Create an Approzium path in the test Vault backend: `$ make enable-vault-path` + * Give your AWS-identity access to the test server: `$ make seed-vault-addr ADDR=dbmd5:5432` + * Create a connection: `$ cd sdk/python/examples && poetry run python3 psycopg2_connect.py`. + +### Testing + +Our end-to-end tests take a few minutes to run. Please run them once locally before you submit a PR. + +To run the end-to-end test, from our home directory: +- Run `make test`. That's it! + +## Credits + +This project is brought to you by [Cyral](https://www.cyral.com/), who wishes to give back to the Open Source community. diff --git a/authenticator/Makefile b/authenticator/Makefile new file mode 100644 index 00000000..b33f3907 --- /dev/null +++ b/authenticator/Makefile @@ -0,0 +1,17 @@ +all: server + +dev: + go build && go install + +test: + go test -v -race -p 1 ./... + +server: + go build . + +deps: + cd server && protoc -I protos authenticator.proto --go_out=plugins=grpc:protos && cd - + cd server && protoc -I protos health.proto --go_out=plugins=grpc:protos && cd - + +bin: + @CGO_ENABLED=$(CGO_ENABLED) BUILD_TAGS='$(BUILD_TAGS) ui' sh -c "'$(CURDIR)/scripts/build.sh'" diff --git a/authenticator/README.md b/authenticator/README.md new file mode 100644 index 00000000..0b719ffd --- /dev/null +++ b/authenticator/README.md @@ -0,0 +1,24 @@ +# The Approzium Authenticator + +The Approzium authenticator is a server that stands between a client, and a database it wants access to. It verifies +the client's identity using the _platform_ in which it is running, like by using its AWS identity credentials. Then, it +checks a place where database credentials are stored, like in HashiCorp Vault, builds a connection, and passes the +_connection_ back to the client. So, the client never sees the database password. And thus, the client _can't leak_ +the password. + +## Developing Is Easy! + +We love contributions. To easily develop, in the `authenticator` folder, run `$ make dev`. Then, run the authenticator. + +``` +$ authenticator -dev +``` + +It will start the authenticator up on your `localhost` without TLS. Check that it's up by hitting its API. + +``` +$ curl -v http://localhost:6000/v1/health +``` + +For test data, simply edit the `secrets.yaml` file the authenticator's logs mention, and restart it. Or, use the test +data that's already there. diff --git a/authenticator/approzium.config.yml b/authenticator/approzium.config.yml new file mode 100644 index 00000000..f2523ea9 --- /dev/null +++ b/authenticator/approzium.config.yml @@ -0,0 +1,6 @@ +# host: 127.0.0.0 +# httpport: 6000 +# grpcport: 6001 +# loglevel: info +# logformat: text +# lograw: false diff --git a/authenticator/go.mod b/authenticator/go.mod new file mode 100644 index 00000000..3065a31d --- /dev/null +++ b/authenticator/go.mod @@ -0,0 +1,25 @@ +module github.com/cyralinc/approzium/authenticator + +go 1.13 + +require ( + contrib.go.opencensus.io/exporter/prometheus v0.2.0 + github.com/aws/aws-sdk-go v1.32.5 + github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.3.5 + github.com/google/gofuzz v1.1.0 + github.com/google/uuid v1.1.1 + github.com/hashicorp/vault/api v1.0.4 + github.com/sirupsen/logrus v1.6.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.7.0 + go.opencensus.io v0.22.4 + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 + golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect + golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect + golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 // indirect + google.golang.org/grpc v1.30.0 + gopkg.in/yaml.v2 v2.3.0 +) diff --git a/authenticator/go.sum b/authenticator/go.sum new file mode 100644 index 00000000..be1a6e38 --- /dev/null +++ b/authenticator/go.sum @@ -0,0 +1,465 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +contrib.go.opencensus.io/exporter/prometheus v0.2.0 h1:9PUk0/8V0LGoPqVCrf8fQZJkFGBxudu8jOjQSMwoD6w= +contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go v1.32.5 h1:Sz0C7deIoMu5lFGTVkIN92IEZrUz1AWIDDW+9p6n1Rk= +github.com/aws/aws-sdk-go v1.32.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a h1:yU/FENpkHYISWsQrbr3pcZOBj0EuRjPzNc1+dTCLu44= +github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a/go.mod h1:AEugkNu3BjBxyz958nJ5holD9PRjta6iprcoUauDbU4= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/vault/api v1.0.4 h1:j08Or/wryXT4AcHj1oCbMd7IijXcKzYUGw59LGu9onU= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/sdk v0.1.13 h1:mOEPeOhT7jl0J4AMl1E705+BcmeRs1VmKNb9F0sMLy8= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI= +github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.6 h1:0qbH+Yqu/cj1ViVLvEWCP6qMQ4efWUj6bQqOEA0V0U4= +github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/statsd_exporter v0.15.0 h1:UiwC1L5HkxEPeapXdm2Ye0u1vUJfTj7uwT5yydYpa1E= +github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd h1:r7DufRZuZbWB7j439YfAzP8RPDa9unLkpwQKUYbIMPI= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk= +golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 h1:MRHtG0U6SnaUb+s+LhNE1qt1FQ1wlhqr5E4usBKC0uA= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/authenticator/main.go b/authenticator/main.go new file mode 100644 index 00000000..6c560c23 --- /dev/null +++ b/authenticator/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "flag" + "fmt" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/cyralinc/approzium/authenticator/server" + "github.com/cyralinc/approzium/authenticator/server/config" + log "github.com/sirupsen/logrus" +) + +var devMode bool + +func init() { + flag.BoolVar(&devMode, "dev", false, "run in dev mode") +} + +func main() { + flag.Parse() + + var c config.Config + var err error + if devMode { + // dev mode uses the file back-end + os.Unsetenv("VAULT_ADDR") + c = config.Config{ + Host: "127.0.0.1", + HTTPPort: 6000, + GRPCPort: 6001, + DisableTLS: true, + LogLevel: "debug", + LogFormat: "text", + LogRaw: false, + } + } else { + c, err = config.ParseConfig() + } + if err != nil { + log.Errorf("couldn't parse config: %s", err) + return + } + + logger, err := buildApplicationLogger(c) + if err != nil { + log.Error(err) + return + } + + if err := server.Start(logger, c); err != nil { + logger.Errorf("authenticator ended due to %s", err) + return + } + logger.Info("all ports up and ready to serve traffic") + + // Wait for a shutdown signal. + shutdown := make(chan os.Signal) + signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM) + <-shutdown +} + +func buildApplicationLogger(c config.Config) (*log.Logger, error) { + logLevel, err := log.ParseLevel(strings.ToLower(c.LogLevel)) + if err != nil { + return nil, err + } + logger := log.New() + logger.Level = logLevel + + switch strings.ToLower(c.LogFormat) { + case "text": + logger.SetFormatter(&log.TextFormatter{ + FullTimestamp: true, + DisableLevelTruncation: true, + PadLevelText: true, + }) + case "json": + logger.SetFormatter(&log.JSONFormatter{}) + default: + return nil, fmt.Errorf("unsupported log format: %s", c.LogFormat) + } + return logger, nil +} diff --git a/authenticator/scripts/build.sh b/authenticator/scripts/build.sh new file mode 100755 index 00000000..ad2d6775 --- /dev/null +++ b/authenticator/scripts/build.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# +# This script builds the application from source for multiple platforms. +set -e + +GO_CMD=${GO_CMD:-go} + +# Get the parent directory of where this script is. +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done +DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )" + +# Change into that directory +cd "$DIR" + +# Set build tags +BUILD_TAGS="${BUILD_TAGS:-"approzium"}" + +# Get the git commit +GIT_COMMIT="$(git rev-parse HEAD)" +GIT_DIRTY="$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)" + +# If its dev mode, only build for ourself +if [ "${APPROZIUM_DEV_BUILD}x" != "x" ] && [ "${XC_OSARCH}x" == "x" ]; then + XC_OS=$(${GO_CMD} env GOOS) + XC_ARCH=$(${GO_CMD} env GOARCH) + XC_OSARCH=$(${GO_CMD} env GOOS)/$(${GO_CMD} env GOARCH) +elif [ "${XC_OSARCH}x" != "x" ]; then + IFS='/' read -ra SPLITXC <<< "${XC_OSARCH}" + DEV_PLATFORM="./pkg/${SPLITXC[0]}_${SPLITXC[1]}" +fi + +# Determine the arch/os combos we're building for +XC_ARCH=${XC_ARCH:-"386 amd64"} +XC_OS=${XC_OS:-linux darwin windows freebsd openbsd netbsd solaris} +XC_OSARCH=${XC_OSARCH:-"linux/386 linux/amd64 linux/arm linux/arm64 darwin/386 darwin/amd64 windows/386 windows/amd64 freebsd/386 freebsd/amd64 freebsd/arm openbsd/386 openbsd/amd64 openbsd/arm netbsd/386 netbsd/amd64 solaris/amd64"} + +GOPATH=${GOPATH:-$(${GO_CMD} env GOPATH)} +case $(uname) in + CYGWIN*) + GOPATH="$(cygpath $GOPATH)" + ;; +esac + +# Delete the old dir +echo "==> Removing old directory..." +rm -f bin/* +rm -rf pkg/* +mkdir -p bin/ + +# Build! +# If GOX_PARALLEL_BUILDS is set, it will be used to add a "-parallel=${GOX_PARALLEL_BUILDS}" gox parameter +echo "==> Building..." +gox \ + -osarch="${XC_OSARCH}" \ + -gcflags "${GCFLAGS}" \ + -ldflags "${LD_FLAGS}-X github.com/cyralinc/approzium/sdk/version.GitCommit='${GIT_COMMIT}${GIT_DIRTY}'" \ + -output "pkg/{{.OS}}_{{.Arch}}/approzium" \ + ${GOX_PARALLEL_BUILDS+-parallel="${GOX_PARALLEL_BUILDS}"} \ + -tags="${BUILD_TAGS}" \ + -gocmd="${GO_CMD}" \ + . + +# Move all the compiled things to the $GOPATH/bin +OLDIFS=$IFS +IFS=: MAIN_GOPATH=($GOPATH) +IFS=$OLDIFS + +# Copy our OS/Arch to the bin/ directory +DEV_PLATFORM=${DEV_PLATFORM:-"./pkg/$(${GO_CMD} env GOOS)_$(${GO_CMD} env GOARCH)"} +for F in $(find ${DEV_PLATFORM} -mindepth 1 -maxdepth 1 -type f); do + cp ${F} bin/ + cp ${F} ${MAIN_GOPATH}/bin/ +done + +if [ "${APPROZIUM_DEV_BUILD}x" = "x" ]; then + # Zip and copy to the dist dir + echo "==> Packaging..." + for PLATFORM in $(find ./pkg -mindepth 1 -maxdepth 1 -type d); do + OSARCH=$(basename ${PLATFORM}) + echo "--> ${OSARCH}" + + pushd $PLATFORM >/dev/null 2>&1 + zip ../${OSARCH}.zip ./* + popd >/dev/null 2>&1 + done +fi + +# Done! +echo +echo "==> Results:" +ls -hl bin/ diff --git a/authenticator/server/api/api.go b/authenticator/server/api/api.go new file mode 100644 index 00000000..5a2ebad3 --- /dev/null +++ b/authenticator/server/api/api.go @@ -0,0 +1,74 @@ +package api + +import ( + "crypto/tls" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "time" + + "contrib.go.opencensus.io/exporter/prometheus" + "github.com/cyralinc/approzium/authenticator/server/config" + log "github.com/sirupsen/logrus" +) + +func Start(logger *log.Logger, config config.Config) error { + + if err := loadEndpoints(logger, config); err != nil { + return err + } + + serviceAddress := config.Host + ":" + strconv.Itoa(config.HTTPPort) + server := &http.Server{ + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + } + + if config.DisableTLS { + server.Addr = serviceAddress + go func() { + logger.Fatal(server.ListenAndServe()) + }() + logger.Infof("api starting on http://%s", serviceAddress) + } else { + server.Addr = fmt.Sprintf(":%d", config.HTTPPort) + crt, err := ioutil.ReadFile(config.PathToTLSCert) + if err != nil { + return err + } + key, err := ioutil.ReadFile(config.PathToTLSKey) + if err != nil { + return err + } + cert, err := tls.X509KeyPair(crt, key) + if err != nil { + return err + } + server.TLSConfig = &tls.Config{ + Certificates: []tls.Certificate{cert}, + ServerName: config.Host, + } + + go func() { + logger.Fatal(server.ListenAndServeTLS("", "")) + }() + logger.Infof("api starting on https://%s", serviceAddress) + } + return nil +} + +func loadEndpoints(logger *log.Logger, config config.Config) error { + prometheusHandler, err := prometheus.NewExporter(prometheus.Options{ + Namespace: "approzium", + }) + if err != nil { + return err + } + + // Alphabetical by endpoint. + http.Handle("/v1/health", newHealthChecker(logger, config)) + http.Handle("/v1/metrics/prometheus", prometheusHandler) + + return nil +} diff --git a/authenticator/server/api/health.go b/authenticator/server/api/health.go new file mode 100644 index 00000000..24d52133 --- /dev/null +++ b/authenticator/server/api/health.go @@ -0,0 +1,28 @@ +package api + +import ( + "net/http" + + "github.com/cyralinc/approzium/authenticator/server/config" + log "github.com/sirupsen/logrus" +) + +func newHealthChecker(logger *log.Logger, config config.Config) http.Handler { + return &healthChecker{ + logger: logger, + config: config, + } +} + +type healthChecker struct { + logger *log.Logger + config config.Config +} + +// For most things that use a health check to determine if a service is up, +// like for AWS and Kubernetes for instance, a service is considered unhealthy +// if it returns anything other than a 200. +func (h *healthChecker) ServeHTTP(wr http.ResponseWriter, _ *http.Request) { + h.logger.Debug("server is healthy") + wr.WriteHeader(200) +} diff --git a/authenticator/server/api/health_test.go b/authenticator/server/api/health_test.go new file mode 100644 index 00000000..6dd37073 --- /dev/null +++ b/authenticator/server/api/health_test.go @@ -0,0 +1,21 @@ +package api + +import ( + "testing" + + "github.com/cyralinc/approzium/authenticator/server/config" + testtools "github.com/cyralinc/approzium/authenticator/server/testing" +) + +func TestHealthChecker(t *testing.T) { + checker := newHealthChecker(testtools.TestLogger(), config.Config{ + Host: "127.0.0.1", + GRPCPort: 6001, + }) + testWriter := &testtools.TestResponseWriter{} + checker.ServeHTTP(testWriter, nil) + + if testWriter.LastStatusCodeReceived != 200 { + t.Fatalf("expected 200 but received %d", testWriter.LastStatusCodeReceived) + } +} diff --git a/authenticator/server/authenticator.go b/authenticator/server/authenticator.go new file mode 100644 index 00000000..5e1a5c7e --- /dev/null +++ b/authenticator/server/authenticator.go @@ -0,0 +1,397 @@ +package server + +/* + +This server is stateless - it doesn't currently cache anything, perform +any writes, or have knowledge of other Approzium clusters. Because of this, +it can be highly available simply by running multiple instances. Please +do not add code that caches state unless we are planning to change to +a stateful, clustered design. Thanks! + +*/ + +import ( + "context" + "crypto/hmac" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "io" + "net" + "strings" + + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/cyralinc/approzium/authenticator/server/api" + "github.com/cyralinc/approzium/authenticator/server/config" + "github.com/cyralinc/approzium/authenticator/server/credmgrs" + "github.com/cyralinc/approzium/authenticator/server/identity" + pb "github.com/cyralinc/approzium/authenticator/server/protos" + log "github.com/sirupsen/logrus" + "golang.org/x/crypto/pbkdf2" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/status" +) + +// The initial choice for a max is based on +// https://www.postgresql.org/docs/8.3/pgcrypto.html and +// https://tools.ietf.org/html/rfc7677. +// We want to allow enough iterations to be secure, but +// not so many that the iterations could be used to effectively +// DOS us by sending us looping for a long amount of time. +// The RFC recommends at least 15,000 iterations, so we just +// allow up to 10 times as much in case folks are being extra +// secure. We are open to making this higher or lower based on +// community feedback. +var maxIterations = uint32(15000 * 10) + +// Start begins a GRPC server, and an API server. It hangs indefinitely until +// an error is returned from either, terminating the application. Both servers +// respond to CTRL+C shutdowns. +func Start(logger *log.Logger, config config.Config) error { + if err := api.Start(logger, config); err != nil { + return err + } + svr, err := buildServer(logger, config) + if err != nil { + return err + } + if err := startGrpc(logger, config, svr); err != nil { + return err + } + return nil +} + +func buildServer(logger *log.Logger, config config.Config) (pb.AuthenticatorServer, error) { + // Calls pass through the following layers during handling. + // - First, a layer that captures request metrics. + // - Next, a layer that adds a request ID, creates a request logger, and logs + // all inbound and outbound requests. + // - Lastly, this layer, the authenticator, that handles logic. + authenticator, err := newAuthenticator(logger, config) + if err != nil { + return nil, err + } + + svr, err := newRequestMetrics(newRequestLogger(logger, config.LogRaw, authenticator)) + if err != nil { + return nil, err + } + return svr, nil +} + +func startGrpc(logger *log.Logger, config config.Config, authenticatorServer pb.AuthenticatorServer) error { + serviceAddress := fmt.Sprintf("%s:%d", config.Host, config.GRPCPort) + lis, err := net.Listen("tcp", serviceAddress) + if err != nil { + return err + } + + var grpcServer *grpc.Server + if config.DisableTLS { + grpcServer = grpc.NewServer() + logger.Infof("grpc starting on http://%s", serviceAddress) + } else { + creds, err := credentials.NewServerTLSFromFile(config.PathToTLSCert, config.PathToTLSKey) + if err != nil { + return err + } + grpcServer = grpc.NewServer(grpc.Creds(creds)) + logger.Infof("grpc starting on https://%s", serviceAddress) + } + pb.RegisterAuthenticatorServer(grpcServer, authenticatorServer) + go func() { + logger.Fatal(grpcServer.Serve(lis)) + }() + return nil +} + +func newAuthenticator(logger *log.Logger, config config.Config) (pb.AuthenticatorServer, error) { + credMgr, err := credmgrs.RetrieveConfigured(logger, config.VaultTokenPath) + if err != nil { + return nil, err + } + identityVerifier, err := identity.NewVerifier() + if err != nil { + return nil, err + } + return &authenticator{ + logger: logger, + credMgr: credMgr, + identityVerifier: identityVerifier, + }, nil +} + +type authenticator struct { + // The authenticator's logger lacks context about requests being made + // and should not be used within code that's part of executing a request. + logger *log.Logger + credMgr credmgrs.CredentialManager + identityVerifier identity.Verifier +} + +func (a *authenticator) getPassword(reqLogger *log.Entry, req *pb.PasswordRequest) (string, error) { + // Currently, only AWS identity is supported + awsIdentity := req.GetAws() + if awsIdentity == nil { + return "", fmt.Errorf("AWS auth info is required") + } + // To expedite handling the request, let's verify the caller's identity at the same + // time as getting the password. + verifiedIdentityChan := make(chan *identity.Verified, 1) + verificationErrChan := make(chan error, 1) + go func() { + proof := &identity.Proof{ + ClientLang: req.ClientLanguage, + AwsAuth: req.Aws, + } + verifiedIdentity, err := a.identityVerifier.Get(reqLogger, proof) + if err != nil { + verificationErrChan <- status.Errorf(codes.Unauthenticated, err.Error()) + return + } + verifiedIdentityChan <- verifiedIdentity + }() + + claimedIamArn := awsIdentity.ClaimedIamArn + dbHost := req.GetDbhost() + dbPort := req.GetDbport() + dbUser := req.GetDbuser() + + databaseArn, err := toDatabaseARN(reqLogger, claimedIamArn) + if err != nil { + return "", err + } + password, err := a.getCreds(reqLogger, credmgrs.DBKey{ + IAMArn: databaseArn, + DBHost: dbHost, + DBPort: dbPort, + DBUser: dbUser, + }) + if err != nil { + return "", status.Errorf(codes.InvalidArgument, err.Error()) + } + + // Make sure the arn they claimed they had to get the creds was their actual arn. + select { + case verifiedIdentity := <-verifiedIdentityChan: + match, err := a.identityVerifier.Matches(reqLogger, claimedIamArn, verifiedIdentity) + if err != nil { + return "", err + } + if !match { + return "", status.Errorf(codes.Unauthenticated, fmt.Sprintf("claimed IAM arn %s did not match actual IAM arn of %+v", claimedIamArn, verifiedIdentity)) + } + case err = <-verificationErrChan: + return "", err + } + return password, nil +} + +func (a *authenticator) GetPGMD5Hash(ctx context.Context, req *pb.PGMD5HashRequest) (*pb.PGMD5Response, error) { + // Return early if we didn't get a valid salt. + salt := req.GetSalt() + if len(salt) != 4 { + msg := fmt.Sprintf("expected salt to be 4 bytes long, but got %d bytes", len(salt)) + return nil, status.Errorf(codes.InvalidArgument, msg) + } + + reqLogger := getRequestLogger(ctx) + password, err := a.getPassword(reqLogger, req.GetPwdRequest()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) + } + + dbUser := req.GetPwdRequest().GetDbuser() + // Everything checked out. + hash, err := computePGMD5Hash(dbUser, password, salt) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) + } + return &pb.PGMD5Response{Hash: hash}, nil +} + +func (a *authenticator) GetPGSHA256Hash(ctx context.Context, req *pb.PGSHA256HashRequest) (*pb.PGSHA256Response, error) { + // Return early if we didn't get a valid auth message or salt. + authMsg := req.GetAuthenticationMsg() + if len(authMsg) == 0 { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("authentication message not provided")) + } + + salt := req.GetSalt() + if len(salt) == 0 { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("salt not provided")) + } + + iterations := req.GetIterations() + if iterations > maxIterations { + // Using a very high number of iterations could cause us to loop and a lot of + // those requests could quickly take us down, like a DOS attack. + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("iterations too high, received %d but maximum is %d", iterations, maxIterations)) + } + + reqLogger := getRequestLogger(ctx) + password, err := a.getPassword(reqLogger, req.GetPwdRequest()) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, err.Error()) + } + + saltedPass, err := computePGSHA256SaltedPass(password, salt, int(iterations)) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Could not compute hash %s", err)) + } + + cproof, err := computePGSHA256Cproof(saltedPass, authMsg) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, err.Error()) + } + sproof := computePGSHA256Sproof(saltedPass, authMsg) + return &pb.PGSHA256Response{Cproof: cproof, Sproof: sproof}, nil +} + +func (a *authenticator) GetMYSQLSHA1Hash(ctx context.Context, req *pb.MYSQLSHA1HashRequest) (*pb.MYSQLSHA1Response, error) { + // Return early if we didn't get a valid salt. + salt := req.GetSalt() + if len(salt) != 20 { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("expected salt to be 20 bytes long, but got %d bytes", len(salt))) + } + + reqLogger := getRequestLogger(ctx) + password, err := a.getPassword(reqLogger, req.GetPwdRequest()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) + } + + // Everything checked out. + hash, err := computeMYSQLSHA1Hash(password, salt) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) + } + return &pb.MYSQLSHA1Response{Hash: hash}, nil +} + +func (a *authenticator) getCreds(reqLogger *log.Entry, identity credmgrs.DBKey) (string, error) { + creds, err := a.credMgr.Password(reqLogger, identity) + if err != nil { + return "", fmt.Errorf("password not found for identity %s due to %s, using %s", identity, err, a.credMgr.Name()) + } + return creds, nil +} + +// toDatabaseARN either uses the original ARN to check the database +// for a password, or if it's an assumed role ARN, converts it to a +// role ARN before looking. +func toDatabaseARN(logger *log.Entry, fullIAMArn string) (string, error) { + parsedArn, err := arn.Parse(fullIAMArn) + if err != nil { + return "", err + } + logger.Debugf("received login attempt from %+v", parsedArn) + if !strings.HasPrefix(parsedArn.Resource, "assumed-role") { + // This is a regular arn, so we should return it as-is for use in accessing + // database credentials. + return fullIAMArn, nil + } + // Convert assumed role arns to role arns. + fields := strings.Split(parsedArn.Resource, "/") + if len(fields) < 2 || len(fields) > 3 { + return "", fmt.Errorf("unexpected assume role arn format: %s", fullIAMArn) + } + return fmt.Sprintf("arn:%s:iam::%s:role/%s", parsedArn.Partition, parsedArn.AccountID, fields[1]), nil +} + +func computeMD5(s string, salt []byte) (string, error) { + hasher := md5.New() + if _, err := io.WriteString(hasher, s); err != nil { + return "", err + } + hasher.Write(salt) + hashedBytes := hasher.Sum(nil) + return hex.EncodeToString(hashedBytes), nil +} + +func computePGMD5Hash(user, password string, salt []byte) (string, error) { + firstHash, err := computeMD5(password, []byte(user)) + if err != nil { + return "", err + } + secondHash, err := computeMD5(firstHash, salt) + if err != nil { + return "", err + } + return secondHash, nil +} + +func computePGSHA256SaltedPass(password string, salt string, iterations int) ([]byte, error) { + s, err := base64.StdEncoding.DecodeString(salt) + if err != nil { + return nil, fmt.Errorf("Bad salt %s", err) + } + dk := pbkdf2.Key([]byte(password), s, iterations, 32, sha256.New) + return dk, nil +} + +// assumes a and b are of the same length +func xorBytes(a, b []byte) ([]byte, error) { + if len(a) != len(b) { + return nil, fmt.Errorf("cannot xor slices of unequal lengths, received %d and %d", len(a), len(b)) + } + buf := make([]byte, len(a)) + + for i := range a { + buf[i] = a[i] ^ b[i] + } + + return buf, nil +} + +// SCRAM reference: https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism +func computePGSHA256Cproof(spassword []byte, authMsg string) (string, error) { + mac := hmac.New(sha256.New, spassword) + mac.Write([]byte("Client Key")) + ckey := mac.Sum(nil) + ckeyHash := sha256.Sum256(ckey) + cproofHmac := hmac.New(sha256.New, ckeyHash[:]) + cproofHmac.Write([]byte(authMsg)) + cproof, err := xorBytes(cproofHmac.Sum(nil), ckey) + if err != nil { + return "", err + } + cproof64 := base64.StdEncoding.EncodeToString(cproof) + return cproof64, nil +} + +func computePGSHA256Sproof(spassword []byte, authMsg string) string { + mac := hmac.New(sha256.New, spassword) + mac.Write([]byte("Server Key")) + skey := mac.Sum(nil) + sproofHmac := hmac.New(sha256.New, skey) + sproofHmac.Write([]byte(authMsg)) + sproof := sproofHmac.Sum(nil) + sproof64 := base64.StdEncoding.EncodeToString(sproof) + return sproof64 +} + +func computeMYSQLSHA1Hash(password string, salt []byte) ([]byte, error) { + hasher := sha1.New() + if _, err := io.WriteString(hasher, password); err != nil { + return nil, err + } + firstHash := hasher.Sum(nil) + hasher = sha1.New() + hasher.Write(firstHash) + secondHash := hasher.Sum(nil) + hasher = sha1.New() + hasher.Write(salt) + hasher.Write(secondHash) + thirdHash := hasher.Sum(nil) + finalHash, err := xorBytes(firstHash, thirdHash) + if err != nil { + return nil, err + } + return finalHash, nil +} diff --git a/authenticator/server/authenticator_test.go b/authenticator/server/authenticator_test.go new file mode 100644 index 00000000..61ac152d --- /dev/null +++ b/authenticator/server/authenticator_test.go @@ -0,0 +1,440 @@ +package server + +import ( + "context" + "io/ioutil" + "net/http" + "os" + "reflect" + "strings" + "testing" + "time" + + "github.com/cyralinc/approzium/authenticator/server/api" + "github.com/cyralinc/approzium/authenticator/server/config" + pb "github.com/cyralinc/approzium/authenticator/server/protos" + testtools "github.com/cyralinc/approzium/authenticator/server/testing" + "github.com/google/gofuzz" + vault "github.com/hashicorp/vault/api" + log "github.com/sirupsen/logrus" +) + +var ( + testEnv = &testtools.AwsEnv{} + testLogEntry = func() *log.Entry { + logEntry := log.WithFields(log.Fields{"test": "logger"}) + logEntry.Level = log.FatalLevel + return logEntry + }() + testCtx = context.WithValue(context.Background(), ctxLogger, testLogEntry) +) + +// TestAuthenticator_GetPGMD5Hash issues real STS GetCallerIdentity because at the +// time of writing there were no documented limits. Hitting the real API will allow +// us to catch if it changes. +func TestAuthenticator_GetPGMD5Hash(t *testing.T) { + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + signedGetCallerIdentity, err := testEnv.SignedGetCallerIdentity(t) + if err != nil { + t.Fatal(err) + } + + authenticator, err := buildServer(testtools.TestLogger(), config.Config{}) + if err != nil { + t.Fatal(err) + } + resp, err := authenticator.GetPGMD5Hash(testCtx, &pb.PGMD5HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbmd5", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: testEnv.ClaimedArn(), + }, + }, + Salt: []byte{1, 2, 3, 4}, + }) + if err != nil { + t.Fatal(err) + } + if resp.Hash != "d576ce99165615bb3f4331154ca6660c" { + t.Fatalf("expected %s but received %s", "d576ce99165615bb3f4331154ca6660c", resp.Hash) + } + + // Now use a bad claimed arn and make sure we fail. + resp, err = authenticator.GetPGMD5Hash(testCtx, &pb.PGMD5HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "foo", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: "arn:partition:service:region:account-id:arn-thats-not-mine", + }, + }, + Salt: []byte{1, 2, 3, 4}, + }) + if err == nil { + t.Fatal("using a claimed arn that doesn't belong to me should fail") + } +} + +// TestAuthenticator_GetPGSHA256Hash issues real STS GetCallerIdentity because at the +// time of writing there were no documented limits. Hitting the real API will allow +// us to catch if it changes. +func TestAuthenticator_GetPGSHA256Hash(t *testing.T) { + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + signedGetCallerIdentity, err := testEnv.SignedGetCallerIdentity(t) + if err != nil { + t.Fatal(err) + } + + authenticator, err := buildServer(testtools.TestLogger(), config.Config{}) + if err != nil { + t.Fatal(err) + } + resp, err := authenticator.GetPGSHA256Hash(testCtx, &pb.PGSHA256HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbsha256", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: testEnv.ClaimedArn(), + }, + }, + Salt: "1234", + Iterations: 0, + AuthenticationMsg: "hello, world!", + }) + if err != nil { + t.Fatal(err) + } + if resp.Cproof != "WCRy25VQ5iCiPGQoLt4srzNvMhDDhVo19p72M8KB+cU=" { + t.Fatalf("expected %s but received %s", "WCRy25VQ5iCiPGQoLt4srzNvMhDDhVo19p72M8KB+cU=", resp.Cproof) + } + if resp.Sproof != "/N4NMwnT+TeFI4Ymbaj0nk5sjJQTCrwnvaXhApkjRYo=" { + t.Fatalf("expected %s but received %s", "/N4NMwnT+TeFI4Ymbaj0nk5sjJQTCrwnvaXhApkjRYo=", resp.Sproof) + } + + // Now use a bad claimed arn and make sure we fail. + resp, err = authenticator.GetPGSHA256Hash(testCtx, &pb.PGSHA256HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "foo", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: "arn:partition:service:region:account-id:arn-thats-not-mine", + }, + }, + Salt: "1234", + Iterations: 0, + AuthenticationMsg: "hello, world!", + }) + if err == nil { + t.Fatal("using a claimed arn that doesn't belong to me should fail") + } +} + +// TestAuthenticator_GetPGSHA256Hash issues real STS GetCallerIdentity because at the +// time of writing there were no documented limits. Hitting the real API will allow +// us to catch if it changes. +func TestAuthenticator_GetMYSQLSHA1Hash(t *testing.T) { + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + signedGetCallerIdentity, err := testEnv.SignedGetCallerIdentity(t) + if err != nil { + t.Fatal(err) + } + + authenticator, err := buildServer(testtools.TestLogger(), config.Config{}) + if err != nil { + t.Fatal(err) + } + resp, err := authenticator.GetMYSQLSHA1Hash(testCtx, &pb.MYSQLSHA1HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbmysql", + Dbport: "3306", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: testEnv.ClaimedArn(), + }, + }, + Salt: make([]byte, 20), + }) + if err != nil { + t.Fatal(err) + } + expected := []byte{0x7, 0x20, 0x87, 0xd1, 0x6f, 0xdf, 0xab, 0xc5, 0x5b, 0x16, 0x44, 0xbb, 0x90, 0x42, 0x5, 0xc6, 0xd, 0x50, 0x5f, 0xcf} + if !reflect.DeepEqual(resp.Hash, expected) { + t.Fatalf("expected %#v but received %#v", expected, resp.Hash) + } + + // Now use a bad claimed arn and make sure we fail. + resp, err = authenticator.GetMYSQLSHA1Hash(testCtx, &pb.MYSQLSHA1HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbmysql", + Dbport: "3306", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: "arn:partition:service:region:account-id:arn-thats-not-mine", + }, + }, + Salt: make([]byte, 20), + }) + if err == nil { + t.Fatal("using a claimed arn that doesn't belong to me should fail") + } +} + +func TestToDatabaseARN(t *testing.T) { + // Make sure role session names get stripped for assumed roles because + // users won't be planting creds in databases with session names, since + // they change all the time. + result, err := toDatabaseARN(testLogEntry, "arn:aws:sts::account-id:assumed-role/role-name/role-session-name") + if err != nil { + t.Fatal(err) + } + if result != "arn:aws:iam::account-id:role/role-name" { + t.Fatalf("expected %s but received %s", "arn:aws:iam::account-id:role/role-name", result) + } + + // Leave other arns alone. + result, err = toDatabaseARN(testLogEntry, "arn:aws:sts::123456789012:federated-user/my-federated-user-name") + if err != nil { + t.Fatal(err) + } + if result != "arn:aws:sts::123456789012:federated-user/my-federated-user-name" { + t.Fatalf("expected %s but received %s", "arn:aws:sts::123456789012:federated-user/my-federated-user-name", result) + } +} + +func TestXorBytes(t *testing.T) { + result, err := xorBytes([]byte{0}, []byte{0}) + if err != nil { + t.Fatal(err) + } + expected := []byte{0} + if !reflect.DeepEqual(result, expected) { + t.Fatalf("expected %#v, but received %#v", expected, result) + } + + result, err = xorBytes([]byte{1}, []byte{1}) + if err != nil { + t.Fatal(err) + } + expected = []byte{0} + if !reflect.DeepEqual(result, expected) { + t.Fatalf("expected %#v, but received %#v", expected, result) + } + + result, err = xorBytes([]byte{0, 1, 1}, []byte{0, 1, 1}) + if err != nil { + t.Fatal(err) + } + expected = []byte{0, 0, 0} + if !reflect.DeepEqual(result, expected) { + t.Fatalf("expected %#v, but received %#v", expected, result) + } + + result, err = xorBytes([]byte{1, 1, 1}, []byte{0, 0, 0}) + if err != nil { + t.Fatal(err) + } + expected = []byte{1, 1, 1} + if !reflect.DeepEqual(result, expected) { + t.Fatalf("expected %#v, but received %#v", expected, result) + } +} + +// TestNoRaces is intended to be run via "$ go test -v -race" and will +// fail if a race is detected. +func TestNoRaces(t *testing.T) { + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + + // Get these in advance so they'll be only read. You can't have + // races with objects that are only read. + signedGetCallerIdentity, err := testEnv.SignedGetCallerIdentity(t) + if err != nil { + t.Fatal(err) + } + claimedARN := testEnv.ClaimedArn() + + // Create and start the authenticator as we normally would. + authenticator, err := buildServer(testtools.TestLogger(), config.Config{}) + if err != nil { + t.Fatal(err) + } + + // Try to create a race. + start := make(chan interface{}) + done := make(chan interface{}) + for i := 0; i < 1000; i++ { + go func() { + <-start + // We don't care about the response, we just want to hit as much + // of the authenticator's code as possible. + authenticator.GetPGSHA256Hash(testCtx, &pb.PGSHA256HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbsha256", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: claimedARN, + }, + }, + Salt: "1234", + Iterations: 0, + AuthenticationMsg: "hello, world!", + }) + done <- true + }() + go func() { + <-start + // We don't care about the response, we just want to hit as much + // of the authenticator's code as possible. + authenticator.GetPGMD5Hash(testCtx, &pb.PGMD5HashRequest{ + PwdRequest: &pb.PasswordRequest{ + ClientLanguage: pb.ClientLanguage_GO, + Dbhost: "dbmd5", + Dbport: "5432", + Dbuser: "bob", + Aws: &pb.AWSIdentity{ + SignedGetCallerIdentity: signedGetCallerIdentity, + ClaimedIamArn: testEnv.ClaimedArn(), + }, + }, + Salt: []byte{1, 2, 3, 4}, + }) + done <- true + }() + } + // Close the start chan to fire all these calls at once. + close(start) + + // Wait for them to finish, but in case they deadlock, time out. + timer := time.NewTimer(10 * time.Second) + for i := 0; i < 2000; i++ { + select { + case <-done: + case <-timer.C: + t.Fatal("over ten seconds elapsed") + default: + } + } +} + +// TestFuzzAuthenticator simply fuzzes its two request-receiving +// methods to ensure a panic isn't caused by random values. If +// a panic is produced, the test will fail. +func TestFuzzAuthenticator(t *testing.T) { + if !testtools.ShouldRunAcceptanceTests() { + t.Skip("Skipping because acceptance tests are off") + } + + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + + authenticator, err := buildServer(testtools.TestLogger(), config.Config{}) + if err != nil { + t.Fatal(err) + } + + fuzzer := fuzz.New() + + for i := 0; i < 1000; i++ { + req1 := &pb.PGSHA256HashRequest{} + fuzzer.Fuzz(req1) + authenticator.GetPGSHA256Hash(context.Background(), req1) + + req2 := &pb.PGMD5HashRequest{} + fuzzer.Fuzz(req2) + authenticator.GetPGMD5Hash(context.Background(), req2) + + req3 := &pb.MYSQLSHA1HashRequest{} + fuzzer.Fuzz(req3) + authenticator.GetMYSQLSHA1Hash(context.Background(), req3) + } +} + +func TestFuzzXorBytes(t *testing.T) { + fuzzer := fuzz.New() + for i := 0; i < 1000; i++ { + + var a []byte + fuzzer.Fuzz(&a) + + var b []byte + fuzzer.Fuzz(&b) + + xorBytes(a, b) + } +} + +func TestMetrics(t *testing.T) { + if !testtools.ShouldRunAcceptanceTests() { + t.Skip("Skipping because acceptance tests are off") + } + + // These tests rely upon the file back-end, so unset the Vault addr if it exists. + _ = os.Setenv(vault.EnvVaultAddress, "") + + // Start the API, which includes an endpoint for Prometheus to mine metrics. + config := config.Config{ + Host: "127.0.0.1", + HTTPPort: 6000, + DisableTLS: true, + } + _ = api.Start(testtools.TestLogger(), config) + + // Make some calls to increment the metrics. + svr, err := buildServer(testtools.TestLogger(), config) + if err != nil { + t.Fatal(err) + } + svr.GetPGSHA256Hash(testCtx, &pb.PGSHA256HashRequest{}) + + // See what we get for metrics. + resp, err := http.Get("http://localhost:6000/v1/metrics/prometheus") + if err != nil { + t.Fatal(err) + } + if resp.StatusCode != 200 { + t.Fatalf("expected 200 but received %d", resp.StatusCode) + } + + actualResponse, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + + expectedResponse, err := ioutil.ReadFile("testing/prometheus.txt") + if err != nil { + t.Fatal(err) + } + + if clean(expectedResponse) != clean(actualResponse) { + t.Fatalf("expected %s but received %s", expectedResponse, actualResponse) + } +} + +func clean(b []byte) string { + cleaned := strings.ReplaceAll(string(b), " ", "") + cleaned = strings.ReplaceAll(cleaned, "\n", "") + return cleaned +} diff --git a/authenticator/server/config/config.go b/authenticator/server/config/config.go new file mode 100644 index 00000000..9f56e78b --- /dev/null +++ b/authenticator/server/config/config.go @@ -0,0 +1,158 @@ +package config + +import ( + "errors" + "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +// Config is an object for storing configuration variables set through +// Approzium's environment. +// +// Please see https://approzium.org/configuration for elaboration upon +// each parameter. +type Config struct { + Host string + HTTPPort int + GRPCPort int + + DisableTLS bool + PathToTLSCert string + PathToTLSKey string + + LogLevel string + LogFormat string + LogRaw bool + + VaultTokenPath string + ConfigFilePath string +} + +// ParseConfig returns the parsed config. A pointer is not returned +// because after first parse, the config is immutable. +func ParseConfig() (Config, error) { + config, err := parse() + if err != nil { + return Config{}, err + } + if err := verify(config); err != nil { + return Config{}, err + } + return config, nil +} + +func parse() (Config, error) { + var config Config + setConfigDefaults() + setConfigFlags() + if err := setConfigEnvVars(); err != nil { + return Config{}, err + } + if err := viper.Unmarshal(&config); err != nil { + return Config{}, err + } + if config.ConfigFilePath == "" { + return config, nil + } + viper.SetConfigName("approzium.config") + viper.SetConfigType("yaml") + viper.AddConfigPath(config.ConfigFilePath) + + // Find and read the config file + if err := viper.ReadInConfig(); err != nil { + return Config{}, err + } + if err := viper.Unmarshal(&config); err != nil { + return Config{}, err + } + return config, nil +} + +func verify(config Config) error { + if !config.DisableTLS { + if config.PathToTLSCert == "" { + return errors.New("tls is enabled but no tls cert has been provided") + } + if config.PathToTLSKey == "" { + return errors.New("tls is enabled but no tls key has been provided") + } + } + return nil +} + +func setConfigEnvVars() error { + viper.SetEnvPrefix("approzium") + if err := viper.BindEnv("Host", "APPROZIUM_HOST"); err != nil { + return err + } + if err := viper.BindEnv("HTTPPort", "APPROZIUM_HTTP_PORT"); err != nil { + return err + } + if err := viper.BindEnv("GRPCPort", "APPROZIUM_GRPC_PORT"); err != nil { + return err + } + + if err := viper.BindEnv("DisableTLS", "APPROZIUM_DISABLE_TLS"); err != nil { + return err + } + if err := viper.BindEnv("PathToTLSCert", "APPROZIUM_PATH_TO_TLS_CERT"); err != nil { + return err + } + if err := viper.BindEnv("PathToTLSKey", "APPROZIUM_PATH_TO_TLS_KEY"); err != nil { + return err + } + + if err := viper.BindEnv("LogLevel", "APPROZIUM_LOG_LEVEL"); err != nil { + return err + } + if err := viper.BindEnv("LogFormat", "APPROZIUM_LOG_FORMAT"); err != nil { + return err + } + if err := viper.BindEnv("LogRaw", "APPROZIUM_LOG_RAW"); err != nil { + return err + } + + if err := viper.BindEnv("VaultTokenPath", "APPROZIUM_VAULT_TOKEN_PATH"); err != nil { + return err + } + if err := viper.BindEnv("ConfigFilePath", "APPROZIUM_CONFIG_FILE_PATH"); err != nil { + return err + } + return nil +} + +func setConfigDefaults() { + viper.SetDefault("Host", "127.0.0.1") + viper.SetDefault("HTTPPort", "6000") + viper.SetDefault("GRPCPort", "6001") + + viper.SetDefault("DisableTLS", false) + + viper.SetDefault("LogLevel", "info") + viper.SetDefault("LogFormat", "text") + viper.SetDefault("LogRaw", false) +} + +func setConfigFlags() { + if pflag.Lookup("host") == nil { + // avoid redefining flags because it leads to panic + pflag.String("host", "", "") + pflag.String("httpport", "", "") + pflag.String("grpcport", "", "") + + pflag.String("disabletls", "", "") + pflag.String("tlscertpath", "", "") + pflag.String("tlskeypath", "", "") + + pflag.String("loglevel", "", "") + pflag.String("logformat", "", "") + pflag.Bool("lograw", false, "") + + pflag.String("vaulttokenpath", "", "") + pflag.String("config", "", "") + } + + pflag.Parse() + viper.BindPFlags(pflag.CommandLine) + viper.BindPFlag("configfilepath", pflag.Lookup("config")) +} diff --git a/authenticator/server/config/config_test.go b/authenticator/server/config/config_test.go new file mode 100644 index 00000000..05748846 --- /dev/null +++ b/authenticator/server/config/config_test.go @@ -0,0 +1,47 @@ +package config + +import ( + "os" + "testing" +) + +func TestParseConfig(t *testing.T) { + os.Unsetenv("APPROZIUM_HOST") + os.Unsetenv("APPROZIUM_HTTP_PORT") + os.Unsetenv("APPROZIUM_LOG_LEVEL") + os.Setenv("APPROZIUM_DISABLE_TLS", "true") + config, err := ParseConfig() + if err != nil { + t.Fatal(err) + } + if config.Host != "127.0.0.1" { + t.Fatalf("expected %s, received %s", "127.0.0.1", config.Host) + } + if config.HTTPPort != 6000 { + t.Fatalf("expected %d, received %d", 6000, config.HTTPPort) + } + if config.LogLevel != "info" { + t.Fatalf("expected %s, received %s", "info", config.LogLevel) + } + + os.Setenv("APPROZIUM_HOST", "0.0.0.0") + os.Setenv("APPROZIUM_HTTP_PORT", "6001") + os.Setenv("APPROZIUM_LOG_LEVEL", "debug") + os.Setenv("APPROZIUM_DISABLE_TLS", "true") + config, err = ParseConfig() + if err != nil { + t.Fatal(err) + } + if config.Host != "0.0.0.0" { + t.Fatalf("expected %s, received %s", "0.0.0.0", config.Host) + } + if config.HTTPPort != 6001 { + t.Fatalf("expected %d, received %d", 6001, config.HTTPPort) + } + if config.LogLevel != "debug" { + t.Fatalf("expected %s, received %s", "debug", config.LogLevel) + } + if !config.DisableTLS { + t.Fatal("tls should be disabled") + } +} diff --git a/authenticator/server/credmgrs/credmgr.go b/authenticator/server/credmgrs/credmgr.go new file mode 100644 index 00000000..f1d48a68 --- /dev/null +++ b/authenticator/server/credmgrs/credmgr.go @@ -0,0 +1,152 @@ +package credmgrs + +import ( + "errors" + + "github.com/cyralinc/approzium/authenticator/server/metrics" + log "github.com/sirupsen/logrus" + "go.opencensus.io/metric" + "go.opencensus.io/metric/metricdata" +) + +var ( + ErrNotAuthorized = errors.New("not authorized") + ErrNotFound = errors.New("not found") +) + +type DBKey struct { + IAMArn string + DBHost string + DBPort string + DBUser string +} + +// RetrieveConfigured checks the environment for configured cred +// providers, and selects the first working configuration. +func RetrieveConfigured(logger *log.Logger, vaultTokenPath string) (CredentialManager, error) { + credMgr, err := selectCredMgr(logger, vaultTokenPath) + if err != nil { + return nil, err + } + return newTracker(credMgr) +} + +type CredentialManager interface { + // Name should provide a loggable and error-returnable identifying + // name for the credential manager. + Name() string + + // Password should retrieve the password for a given identity. + // If the identity is not found, an error should be returned. + // IMPORTANT: While the identity given for the password should + // be trusted, we should not assume the identity should have + // access to the database they're requesting it for. It's the + // responsibility of the Password call to ensure that the given + // IAM ARN _should_ have access to the given DB. + Password(reqLogger *log.Entry, identity DBKey) (string, error) +} + +func newTracker(wrapped CredentialManager) (CredentialManager, error) { + numPwAttempts, err := metrics.Registry.AddInt64Cumulative( + "total_password_retrieval_attempts", + metric.WithDescription("The number of times a caller has requested a password from the database to authenticate"), + ) + if err != nil { + return nil, err + } + numPwAttemptsEntry, err := numPwAttempts.GetEntry() + if err != nil { + return nil, err + } + + numPwFailures, err := metrics.Registry.AddInt64Cumulative( + "total_password_retrieval_failures", + metric.WithDescription("The number of times a caller has failed to retrieve a password for any reason"), + ) + if err != nil { + return nil, err + } + numPwFailuresEntry, err := numPwFailures.GetEntry() + if err != nil { + return nil, err + } + + numPwUnauthorized, err := metrics.Registry.AddInt64Cumulative( + "total_password_retrieval_unauthorized", + metric.WithDescription("The number of times a caller has been unauthorized to retrieve a password"), + ) + if err != nil { + return nil, err + } + numPwUnauthorizedEntry, err := numPwUnauthorized.GetEntry() + if err != nil { + return nil, err + } + + pwReqMilliseconds, err := metrics.Registry.AddInt64Gauge( + "total_password_request_milliseconds", + metric.WithDescription("Total password retrieval milliseconds"), + metric.WithUnit(metricdata.UnitMilliseconds), + ) + if err != nil { + return nil, err + } + pwReqMillisecondsEntry, err := pwReqMilliseconds.GetEntry() + if err != nil { + return nil, err + } + return &tracker{ + wrapped: wrapped, + numPwAttempts: numPwAttemptsEntry, + numPwFailures: numPwFailuresEntry, + numPwUnauthorized: numPwUnauthorizedEntry, + pwReqMilliseconds: pwReqMillisecondsEntry, + }, nil +} + +type tracker struct { + wrapped CredentialManager + + numPwAttempts *metric.Int64CumulativeEntry + numPwFailures *metric.Int64CumulativeEntry + numPwUnauthorized *metric.Int64CumulativeEntry + pwReqMilliseconds *metric.Int64GaugeEntry +} + +func (t *tracker) Name() string { + return t.wrapped.Name() +} + +func (t *tracker) Password(reqLogger *log.Entry, identity DBKey) (string, error) { + t.numPwAttempts.Inc(1) + + password, err := t.wrapped.Password(reqLogger, identity) + if err != nil { + t.numPwFailures.Inc(1) + reqLogger.Warnf("failed attempt to retrieve identity %+v due to %s", identity, err) + if err == ErrNotAuthorized { + t.numPwUnauthorized.Inc(1) + } + } + return password, err +} + +func selectCredMgr(logger *log.Logger, vaultTokenPath string) (CredentialManager, error) { + credMgr, err := newHashiCorpVaultCreds(vaultTokenPath) + if err != nil { + logger.Debugf("didn't select HashiCorp Vault as credential manager due to err: %s", err) + } else { + logger.Info("selected HashiCorp Vault as credential manager") + return credMgr, nil + } + + credMgr, err = newLocalFileCreds(logger) + if err != nil { + logger.Debugf("didn't select local file as credential manager due to err: %s", err) + } else { + logger.Info("selected local file as credential manager") + logger.Warn("local file credential manager should not be used in production") + return credMgr, err + } + return nil, errors.New("no valid credential manager available, see debug-level logs for more information") +} diff --git a/authenticator/server/credmgrs/hc_vault.go b/authenticator/server/credmgrs/hc_vault.go new file mode 100644 index 00000000..ae575687 --- /dev/null +++ b/authenticator/server/credmgrs/hc_vault.go @@ -0,0 +1,127 @@ +package credmgrs + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + + vault "github.com/hashicorp/vault/api" + log "github.com/sirupsen/logrus" +) + +// In Vault, a mount path is the path where a secrets engine has been +// mounted. This code supports mounts that have been added the following way: +// "$ vault secrets enable -path=approzium -version=1 kv" +// Someday we may wish to make this path configurable. +const mountPath = "approzium" + +func newHashiCorpVaultCreds(tokenPath string) (CredentialManager, error) { + if addr := os.Getenv(vault.EnvVaultAddress); addr == "" { + return nil, errors.New("no vault address detected") + } + credMgr := &hcVaultCredMgr{ + tokenPath: tokenPath, + } + + // Check that we're able to communicate with Vault by doing a test read. + client, err := credMgr.vaultClient() + if err != nil { + return nil, err + } + if _, err := client.Logical().Read(mountPath); err != nil { + return nil, err + } + return credMgr, nil +} + +type hcVaultCredMgr struct { + tokenPath string +} + +func (h *hcVaultCredMgr) Name() string { + return "HashiCorp Vault" +} + +func (h *hcVaultCredMgr) Password(_ *log.Entry, identity DBKey) (string, error) { + client, err := h.vaultClient() + if err != nil { + return "", err + } + + path := mountPath + "/" + identity.DBHost + ":" + identity.DBPort + secret, err := client.Logical().Read(path) + if err != nil { + return "", err + } + if secret == nil { + return "", fmt.Errorf("nothing exists at this Vault path") + } + if secret.Data == nil { + return "", fmt.Errorf("no response body data returned from Vault") + } + + // Please see tests for examples of the kind of secret data we'd expect + // here. + userData := secret.Data[identity.DBUser] + userDataMap, ok := userData.(map[string]interface{}) + if !ok { + return "", fmt.Errorf("couldn't convert %s to a string, type is %T", userData, userData) + } + + // Verify that the inbound IAM role is one of the IAM roles listed as appropriate. + iamArnsRaw, ok := userDataMap["iam_arns"] + if !ok { + return "", fmt.Errorf("iam_arns not found in %s", userDataMap) + } + iamArns, ok := iamArnsRaw.([]interface{}) + if !ok { + return "", fmt.Errorf("could not convert %s to array, type is %T", iamArnsRaw, iamArnsRaw) + } + authorized := false + for _, iamArnRaw := range iamArns { + iamArn, ok := iamArnRaw.(string) + if !ok { + return "", fmt.Errorf("couldn't convert %s to a string, type is %T", iamArnRaw, iamArnRaw) + } + if iamArn == identity.IAMArn { + authorized = true + break + } + } + if !authorized { + return "", ErrNotAuthorized + } + + // Verification passed. OK to return the password. + passwordRaw, ok := userDataMap["password"] + if !ok { + return "", fmt.Errorf("password not found in %s", userDataMap) + } + password, ok := passwordRaw.(string) + if !ok { + return "", fmt.Errorf("could not convert %s to string, type is %T", passwordRaw, passwordRaw) + } + return password, nil +} + +// vaultClient retrieves a client using either the environmental VAULT_TOKEN, +// or reading the latest token from the token file sink. +func (h *hcVaultCredMgr) vaultClient() (*vault.Client, error) { + // Only use the token sink if there's not already an environmental + // VAULT_TOKEN. + if h.tokenPath != "" && os.Getenv(vault.EnvVaultToken) == "" { + tokenBytes, err := ioutil.ReadFile(h.tokenPath) + if err != nil { + return nil, err + } + // There is no way to directly pass in the token, so we + // must set it in the environment. + os.Setenv(vault.EnvVaultToken, string(tokenBytes)) + defer os.Unsetenv(vault.EnvVaultToken) + } + + // This uses a default configuration for Vault. This includes reading + // Vault's environment variables and setting them as a configuration. + return vault.NewClient(nil) +} diff --git a/authenticator/server/credmgrs/hc_vault_test.go b/authenticator/server/credmgrs/hc_vault_test.go new file mode 100644 index 00000000..146a84e9 --- /dev/null +++ b/authenticator/server/credmgrs/hc_vault_test.go @@ -0,0 +1,149 @@ +package credmgrs + +import ( + "io/ioutil" + "os" + "testing" + + vault "github.com/hashicorp/vault/api" + log "github.com/sirupsen/logrus" +) + +var testLogEntry = func() *log.Entry { + logEntry := log.WithFields(log.Fields{"test": "logger"}) + logEntry.Level = log.FatalLevel + return logEntry +}() + +// To run these tests, first start Vault locally like so: +// "$ vault server -dev -dev-root-token-id=root" +// +// Then, in this application's environment, set: +// VAULT_ADDR=http://localhost:8200 +// VAULT_TOKEN=root +func TestHcVaultCredMgr_WithTokenPath(t *testing.T) { + // Ensure we have the necessary test environment. + addr := os.Getenv(vault.EnvVaultAddress) + if addr == "" { + t.Skip("skipping because VAULT_ADDR is unset") + } + + // Record the original + currentToken := os.Getenv(vault.EnvVaultToken) + + tmpFile, err := ioutil.TempFile(os.TempDir(), "approzium-testing-") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + + text := []byte(currentToken) + if _, err = tmpFile.Write(text); err != nil { + t.Fatal(err) + } + if err := tmpFile.Close(); err != nil { + t.Fatal(err) + } + + // Plant the necessary secrets for this test. + client, err := vault.NewClient(nil) + if err != nil { + t.Fatal(err) + } + // We'll try mounting the secrets engine we need, but it might already be + // mounted, so if there's an error mounting it we'll just ignore it. + _, _ = client.Logical().Write("/sys/mounts/"+mountPath, map[string]interface{}{ + "type": "kv", + "options": map[string]interface{}{ + "version": "1", + }, + }) + if _, err := client.Logical().Write("approzium/127.0.0.1:5432", map[string]interface{}{ + "dbuser1": map[string]interface{}{ + "password": "asdfghjkl", + "iam_arns": []string{ + "arn:aws:iam::accountid:role/rolename1", + "arn:aws:iam::accountid:role/rolename2", + }, + }, + }); err != nil { + t.Fatal(err) + } + + // Unset the environmental Vault token so it must be pulled through the token sink. + defer func() { + os.Setenv(vault.EnvVaultToken, currentToken) + }() + os.Unsetenv(vault.EnvVaultToken) + + // Try to read the creds through the cred manager. + credMgr, err := newHashiCorpVaultCreds(tmpFile.Name()) + if err != nil { + t.Fatal(err) + } + identity := DBKey{ + IAMArn: "arn:aws:iam::accountid:role/rolename2", + DBHost: "127.0.0.1", + DBPort: "5432", + DBUser: "dbuser1", + } + password, err := credMgr.Password(testLogEntry, identity) + if err != nil { + t.Fatal(err) + } + if password != "asdfghjkl" { + t.Fatalf("expected: %s; actual: %s", "asdfghjkl", password) + } +} + +func TestHcVaultCredMgr_WithoutTokenPath(t *testing.T) { + // Ensure we have the necessary test environment. + addr := os.Getenv(vault.EnvVaultAddress) + if addr == "" { + t.Skip("skipping because VAULT_ADDR is unset") + } + + // Plant the necessary secrets for this test. + client, err := vault.NewClient(nil) + if err != nil { + t.Fatal(err) + } + // We'll try mounting the secrets engine we need, but it might already be + // mounted, so if there's an error mounting it we'll just ignore it. + _, _ = client.Logical().Write("/sys/mounts/"+mountPath, map[string]interface{}{ + "type": "kv", + "options": map[string]interface{}{ + "version": "1", + }, + }) + if _, err := client.Logical().Write("approzium/localhost:5432", map[string]interface{}{ + "dbuser1": map[string]interface{}{ + "password": "asdfghjkl", + "iam_arns": []string{ + "arn:aws:iam::accountid:role/rolename1", + "arn:aws:iam::accountid:role/rolename2", + }, + }, + }); err != nil { + t.Fatal(err) + } + + // Try to read the creds through the cred manager. + credMgr, err := newHashiCorpVaultCreds("") + if err != nil { + t.Fatal(err) + } + identity := DBKey{ + IAMArn: "arn:aws:iam::accountid:role/rolename2", + DBHost: "localhost", + DBPort: "5432", + DBUser: "dbuser1", + } + password, err := credMgr.Password(testLogEntry, identity) + if err != nil { + t.Fatal(err) + } + if password != "asdfghjkl" { + t.Fatalf("expected: %s; actual: %s", "asdfghjkl", password) + } +} diff --git a/authenticator/server/credmgrs/local_file.go b/authenticator/server/credmgrs/local_file.go new file mode 100644 index 00000000..6009a740 --- /dev/null +++ b/authenticator/server/credmgrs/local_file.go @@ -0,0 +1,84 @@ +package credmgrs + +import ( + "io/ioutil" + "os" + "runtime" + "strings" + + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +const secretsFileLocation = "/authenticator/server/testing/secrets.yaml" + +// newLocalFileCreds is for dev purposes: read credentials from a local file. +func newLocalFileCreds(logger *log.Logger) (CredentialManager, error) { + creds := make(map[DBKey]string) + type secrets []struct { + Dbhost string `yaml:"dbhost"` + Dbport string `yaml:"dbport"` + Dbuser string `yaml:"dbuser"` + Password string `yaml:"password"` + IamArn string `yaml:"iam_arn"` + } + + // To make sure we can find the secrets file, get the absolute path to + // the file that called this method. This will always be something like + // /Users/yourname/go/src/github.com/approzium/approzium/authenticator/server/credmgrs/credmgr.go + _, filename, _, _ := runtime.Caller(1) + + homeDirPath := strings.TrimSuffix(filename, "/authenticator/server/credmgrs/credmgr.go") + pathToSecrets := homeDirPath + secretsFileLocation + logger.Infof("loading secrets at %q", pathToSecrets) + + var devCreds secrets + yamlFile, err := ioutil.ReadFile(pathToSecrets) + if err != nil { + return nil, err + } + if err = yaml.Unmarshal(yamlFile, &devCreds); err != nil { + return nil, err + } + for _, cred := range devCreds { + key := DBKey{ + IAMArn: replaceEnvVars(cred.IamArn), + DBHost: replaceEnvVars(cred.Dbhost), + DBPort: replaceEnvVars(cred.Dbport), + DBUser: replaceEnvVars(cred.Dbuser), + } + creds[key] = cred.Password + logger.Debugf("added dev credential for host %s", cred.Dbhost) + } + logger.Info("secrets loaded, please restart authenticator to load edits") + return &localFileCredMgr{creds: creds}, nil +} + +type localFileCredMgr struct { + creds map[DBKey]string +} + +func (l *localFileCredMgr) Name() string { + return "local file (dev only)" +} + +func (l *localFileCredMgr) Password(_ *log.Entry, identity DBKey) (string, error) { + creds, ok := l.creds[identity] + if !ok { + return "", ErrNotFound + } + return creds, nil +} + +// replaceEnvVars takes fields that are formatted like ${FOO}, strips +// the $ and brackets, and replaces the env var with its environmental +// value +func replaceEnvVars(field string) string { + if !strings.HasPrefix(field, "$") { + // It's not an env var. + return field + } + field = strings.ReplaceAll(field, "${", "") + field = strings.ReplaceAll(field, "}", "") + return os.Getenv(field) +} diff --git a/authenticator/server/identity/aws.go b/authenticator/server/identity/aws.go new file mode 100644 index 00000000..53a155c9 --- /dev/null +++ b/authenticator/server/identity/aws.go @@ -0,0 +1,205 @@ +package identity + +import ( + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/aws/aws-sdk-go/aws/arn" + pb "github.com/cyralinc/approzium/authenticator/server/protos" + log "github.com/sirupsen/logrus" +) + +// validSTSEndpoints is presented as a variable so it +// can be edited for testing if we need to mock the AWS +// test server. This list is based off of +// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html +var validSTSEndpoints = []string{ + "sts.amazonaws.com", + "sts.us-east-2.amazonaws.com", + "sts.us-east-1.amazonaws.com", + "sts.us-west-1.amazonaws.com", + "sts.us-west-2.amazonaws.com", + "sts.ap-east-1.amazonaws.com", + "sts.ap-south-1.amazonaws.com", + "sts.ap-northeast-2.amazonaws.com", + "sts.ap-southeast-1.amazonaws.com", + "sts.ap-southeast-2.amazonaws.com", + "sts.ap-northeast-1.amazonaws.com", + "sts.ca-central-1.amazonaws.com", + "sts.eu-central-1.amazonaws.com", + "sts.eu-west-1.amazonaws.com", + "sts.eu-west-2.amazonaws.com", + "eu-south-1", + "sts.eu-west-3.amazonaws.com", + "sts.eu-north-1.amazonaws.com", + "sts.me-south-1.amazonaws.com", + "af-south-1", + "sts.sa-east-1.amazonaws.com", +} + +type aws struct{} + +func (a *aws) Get(_ *log.Entry, proof *Proof) (*Verified, error) { + if proof.AwsAuth == nil { + return nil, fmt.Errorf("AWS auth info is required") + } + iamArn, err := a.getAwsIdentity(proof.AwsAuth.SignedGetCallerIdentity, proof.ClientLang) + if err != nil { + return nil, err + } + return &Verified{ + authType: authTypeAws, + iamArn: iamArn, + }, nil +} + +func (a *aws) Matches(_ *log.Entry, claimedIdentity string, verifiedIdentity *Verified) (bool, error) { + return a.arnsMatch(claimedIdentity, verifiedIdentity.iamArn) +} + +// getAwsIdentity takes a signed get caller identity string and executes +// the request to the given AWS STS endpoint. It returns the caller's +// full IAM arn. +func (a *aws) getAwsIdentity(signedGetCallerIdentity string, clientLanguage pb.ClientLanguage) (string, error) { + u, err := url.Parse(signedGetCallerIdentity) + if err != nil { + return "", err + } + + // Ensure the STS endpoint we'll be using is an AWS endpoint, and it's not + // just some random server set up to mimic valid AWS STS responses. + isValidSTSEndpoint := false + for _, validSTSEndpoint := range validSTSEndpoints { + if u.Host == validSTSEndpoint { + isValidSTSEndpoint = true + break + } + } + if !isValidSTSEndpoint { + return "", fmt.Errorf("%s is not a valid STS endpoint", u.Host) + } + + // Ensure the call getting executed is actually the GetCallerIdentity call, + // and not some other call that happens to return the expected XML fields. + query := u.Query() + if query.Get("Action") != "GetCallerIdentity" { + return "", fmt.Errorf("invalid action for GetCallerIdentity: %s", query.Get("Action")) + } + return a.executeGetCallerIdentity(signedGetCallerIdentity, clientLanguage) +} + +func (a *aws) executeGetCallerIdentity(signedGetCallerIdentity string, clientLanguage pb.ClientLanguage) (string, error) { + var resp *http.Response + var err error + switch clientLanguage { + case pb.ClientLanguage_GO: + resp, err = http.Get(signedGetCallerIdentity) + case pb.ClientLanguage_PYTHON: + resp, err = http.Post(signedGetCallerIdentity, "", nil) + case pb.ClientLanguage_LANGUAGE_NOT_PROVIDED: + return "", fmt.Errorf("client language must be provided for AWS authentication") + default: + return "", fmt.Errorf("unsupported SDK type of %d", clientLanguage) + } + if err != nil { + return "", err + } + defer resp.Body.Close() + + respBody, _ := ioutil.ReadAll(resp.Body) + if resp.StatusCode != 200 { + return "", fmt.Errorf("received unexpected get caller identity response %d: %s", resp.StatusCode, respBody) + } + + type GetCallerIdentityResponse struct { + IamArn string `xml:"GetCallerIdentityResult>Arn"` + } + response := GetCallerIdentityResponse{} + if err = xml.Unmarshal(respBody, &response); err != nil { + return "", err + } + return response.IamArn, nil +} + +// arnsMatch compares a claimed arn that the caller states they'll +// have, and an actual arn returned by the AWS get caller identity call. +func (a *aws) arnsMatch(claimedArn, actualArn string) (bool, error) { + if claimedArn == "" || actualArn == "" { + return false, nil + } + if claimedArn == actualArn { + return true, nil + } + + // If they're not immediately equal, check for special situations + // where we would still allow a match. + // We allow role arn to match the assumed role arn folks would have + // for that role. + type WrappedARN struct { + arn.ARN + RoleName string + } + + var assumedRole *WrappedARN + var role *WrappedARN + for _, rawArn := range []string{claimedArn, actualArn} { + parsed, err := arn.Parse(rawArn) + if err != nil { + return false, err + } + wrappedARN := &WrappedARN{ + ARN: parsed, + } + if strings.HasPrefix(wrappedARN.Resource, "assumed-role/") { + fields := strings.Split(wrappedARN.Resource, "/") + // Assumed role resource strings look like "assumed-role/rolename/session", + // but they may not have session on the end. + if len(fields) < 2 || len(fields) > 3 { + return false, fmt.Errorf("received assumed role arn that doesn't match the expected format: %s", rawArn) + } + wrappedARN.RoleName = fields[1] + assumedRole = wrappedARN + continue + } + if strings.HasPrefix(wrappedARN.Resource, "role/") { + fields := strings.Split(wrappedARN.Resource, "/") + // Role resource strings look like "role/rolename". + if len(fields) != 2 { + return false, fmt.Errorf("received role arn that doesn't match the expected format: %s", rawArn) + } + wrappedARN.RoleName = fields[1] + role = wrappedARN + continue + } + } + if assumedRole == nil || role == nil { + // Since we only special case matching role arns with assumed role arns, + // we can conclude that these don't match. + return false, nil + } + + // Compare the role arn and the assumed role arn to ensure they match. + if role.Partition != assumedRole.Partition { + return false, fmt.Errorf("partitions don't match, claimed arn %s, actual arn %s", claimedArn, actualArn) + } + if role.Service != "iam" { + return false, fmt.Errorf("received unexpected service for role: %s", role.String()) + } + if assumedRole.Service != "sts" { + return false, fmt.Errorf("received unexpected service for assumed role: %s", assumedRole.String()) + } + if role.Region != assumedRole.Region { + return false, fmt.Errorf("regions don't match, claimed arn %s, actual arn %s", claimedArn, actualArn) + } + if role.AccountID != assumedRole.AccountID { + return false, fmt.Errorf("account IDs don't match, claimed arn %s, actual arn %s", claimedArn, actualArn) + } + if role.RoleName != assumedRole.RoleName { + return false, fmt.Errorf("role names don't match, claimed arn %s, actual arn %s", claimedArn, actualArn) + } + return true, nil +} diff --git a/authenticator/server/identity/aws_test.go b/authenticator/server/identity/aws_test.go new file mode 100644 index 00000000..4d823a2f --- /dev/null +++ b/authenticator/server/identity/aws_test.go @@ -0,0 +1,73 @@ +package identity + +import ( + "strings" + "testing" + + pb "github.com/cyralinc/approzium/authenticator/server/protos" + testtools "github.com/cyralinc/approzium/authenticator/server/testing" +) + +var testEnv = &testtools.AwsEnv{} + +func TestVerifyService(t *testing.T) { + signedGetCallerIdentity, err := testEnv.SignedGetCallerIdentity(t) + if err != nil { + t.Fatal(err) + } + testCases := []struct { + TestName string + SignedGetCallerIdentity string + ExpectedArn string + ExpectErr bool + }{ + { + TestName: "Sunny path, regular arn", + SignedGetCallerIdentity: signedGetCallerIdentity, + ExpectedArn: testEnv.ClaimedArn(), + ExpectErr: false, + }, + { + TestName: "Empty values", + SignedGetCallerIdentity: "", + ExpectErr: true, + }, + { + TestName: "Malicious base URL injected", + SignedGetCallerIdentity: strings.ReplaceAll(signedGetCallerIdentity, "sts", "somewhere-else"), + ExpectErr: true, + }, + { + TestName: "Different call than GetCallerIdentity", + SignedGetCallerIdentity: strings.ReplaceAll(signedGetCallerIdentity, "GetCallerIdentity", "GetSessionToken"), + ExpectErr: true, + }, + } + a := &aws{} + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + verifiedARN, err := a.getAwsIdentity(testCase.SignedGetCallerIdentity, pb.ClientLanguage_GO) + if testCase.ExpectErr { + if err == nil { + t.Fatal("expected err") + } else { + // We expected an error and received it, so we've succeeded + // and there's nothing else to do here. + return + } + } + if err != nil { + t.Fatal(err) + } + + // We don't expect an error. Let's make sure we got the expected response. + match, err := a.arnsMatch(testCase.ExpectedArn, verifiedARN) + if err != nil { + t.Fatal(err) + } + if !match { + t.Fatalf("expected %s but received %s", testCase.ExpectedArn, verifiedARN) + } + }) + } +} diff --git a/authenticator/server/identity/provider.go b/authenticator/server/identity/provider.go new file mode 100644 index 00000000..c12c5d42 --- /dev/null +++ b/authenticator/server/identity/provider.go @@ -0,0 +1,161 @@ +package identity + +import ( + "errors" + "fmt" + "time" + + "github.com/cyralinc/approzium/authenticator/server/metrics" + pb "github.com/cyralinc/approzium/authenticator/server/protos" + log "github.com/sirupsen/logrus" + "go.opencensus.io/metric" + "go.opencensus.io/metric/metricdata" +) + +type Proof struct { + ClientLang pb.ClientLanguage + AwsAuth *pb.AWSIdentity +} + +type Verified struct { + authType authType + iamArn string +} + +type Verifier interface { + Get(reqLogger *log.Entry, proof *Proof) (*Verified, error) + Matches(reqLogger *log.Entry, claimedIdentity string, verifiedIdentity *Verified) (bool, error) +} + +func NewVerifier() (Verifier, error) { + numVerAttempts, err := metrics.Registry.AddInt64Cumulative( + "total_identity_verification_attempts", + metric.WithDescription("Total attempts to verify caller identity"), + ) + if err != nil { + return nil, err + } + numVerAttemptsEntry, err := numVerAttempts.GetEntry() + if err != nil { + return nil, err + } + + numVerFailures, err := metrics.Registry.AddInt64Cumulative( + "total_identity_verification_failures", + metric.WithDescription("Total failures to verify caller identity"), + ) + if err != nil { + return nil, err + } + numVerFailuresEntry, err := numVerFailures.GetEntry() + if err != nil { + return nil, err + } + + numMatchAttempts, err := metrics.Registry.AddInt64Cumulative( + "total_identity_matching_attempts", + metric.WithDescription("Total checks of whether the identity a caller claims matches their actual identity"), + ) + if err != nil { + return nil, err + } + numMatchAttemptsEntry, err := numMatchAttempts.GetEntry() + if err != nil { + return nil, err + } + + numMatchFailures, err := metrics.Registry.AddInt64Cumulative( + "total_identity_matching_failures", + metric.WithDescription("Total calls where caller claimed an identity that was not their actual identity"), + ) + if err != nil { + return nil, err + } + numMatchFailuresEntry, err := numMatchFailures.GetEntry() + if err != nil { + return nil, err + } + + awsReqMilliseconds, err := metrics.Registry.AddInt64Gauge( + "total_aws_request_milliseconds", + metric.WithDescription("Total AWS request milliseconds"), + metric.WithUnit(metricdata.UnitMilliseconds), + ) + if err != nil { + return nil, err + } + awsReqMillisecondsEntry, err := awsReqMilliseconds.GetEntry() + if err != nil { + return nil, err + } + return &tracker{ + aws: &aws{}, + numVerAttempts: numVerAttemptsEntry, + numVerFailures: numVerFailuresEntry, + numMatchAttempts: numMatchAttemptsEntry, + numMatchFailures: numMatchFailuresEntry, + awsReqMilliseconds: awsReqMillisecondsEntry, + }, nil +} + +type tracker struct { + aws Verifier + + numVerAttempts *metric.Int64CumulativeEntry + numVerFailures *metric.Int64CumulativeEntry + numMatchAttempts *metric.Int64CumulativeEntry + numMatchFailures *metric.Int64CumulativeEntry + awsReqMilliseconds *metric.Int64GaugeEntry +} + +func (t *tracker) Get(reqLogger *log.Entry, proof *Proof) (*Verified, error) { + t.numVerAttempts.Inc(1) + + var verifiedIdentity *Verified + var err error + switch { + case proof.AwsAuth != nil: + verifiedIdentity, err = t.aws.Get(reqLogger, proof) + default: + return nil, errors.New("no identity verification received") + } + if err != nil { + t.numVerFailures.Inc(1) + reqLogger.Warn(fmt.Sprintf("couldn't verify %s: %s", proof, err)) + } else { + reqLogger.Info(fmt.Sprintf("verified %+v", verifiedIdentity)) + } + return verifiedIdentity, err +} + +func (t *tracker) Matches(reqLogger *log.Entry, claimedIdentity string, verifiedIdentity *Verified) (bool, error) { + t.numMatchAttempts.Inc(1) + + var matches bool + var err error + switch verifiedIdentity.authType { + case authTypeAws: + start := time.Now().UTC() + matches, err = t.aws.Matches(reqLogger, claimedIdentity, verifiedIdentity) + t.awsReqMilliseconds.Set(time.Now().UTC().Sub(start).Milliseconds()) + default: + return false, fmt.Errorf("unexpected auth type %d received", verifiedIdentity.authType) + } + if !matches || err != nil { + t.numMatchFailures.Inc(1) + } + if !matches { + reqLogger.Warnf("claimed identity of %s doesn't match verified identity of %+v", claimedIdentity, verifiedIdentity) + } + if err != nil { + reqLogger.Warnf("unable to match claimed identity of %s with verified identity of %+v due to %s", claimedIdentity, verifiedIdentity, err) + } + return matches, err +} + +type authType int + +const ( + authTypeUnknown authType = iota + authTypeAws +) diff --git a/authenticator/server/metrics/registry.go b/authenticator/server/metrics/registry.go new file mode 100644 index 00000000..6464e7d0 --- /dev/null +++ b/authenticator/server/metrics/registry.go @@ -0,0 +1,12 @@ +package metrics + +import ( + "go.opencensus.io/metric" + "go.opencensus.io/metric/metricproducer" +) + +var Registry = func() *metric.Registry { + r := metric.NewRegistry() + metricproducer.GlobalManager().AddProducer(r) + return r +}() diff --git a/authenticator/server/protos/authenticator.pb.go b/authenticator/server/protos/authenticator.pb.go new file mode 100644 index 00000000..55c7eb8d --- /dev/null +++ b/authenticator/server/protos/authenticator.pb.go @@ -0,0 +1,683 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: authenticator.proto + +package approzium_authenticator_protos + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type ClientLanguage int32 + +const ( + ClientLanguage_LANGUAGE_NOT_PROVIDED ClientLanguage = 0 + ClientLanguage_PYTHON ClientLanguage = 1 + ClientLanguage_GO ClientLanguage = 2 +) + +var ClientLanguage_name = map[int32]string{ + 0: "LANGUAGE_NOT_PROVIDED", + 1: "PYTHON", + 2: "GO", +} + +var ClientLanguage_value = map[string]int32{ + "LANGUAGE_NOT_PROVIDED": 0, + "PYTHON": 1, + "GO": 2, +} + +func (x ClientLanguage) String() string { + return proto.EnumName(ClientLanguage_name, int32(x)) +} + +func (ClientLanguage) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{0} +} + +type AWSIdentity struct { + SignedGetCallerIdentity string `protobuf:"bytes,1,opt,name=signed_get_caller_identity,json=signedGetCallerIdentity,proto3" json:"signed_get_caller_identity,omitempty"` + ClaimedIamArn string `protobuf:"bytes,2,opt,name=claimed_iam_arn,json=claimedIamArn,proto3" json:"claimed_iam_arn,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AWSIdentity) Reset() { *m = AWSIdentity{} } +func (m *AWSIdentity) String() string { return proto.CompactTextString(m) } +func (*AWSIdentity) ProtoMessage() {} +func (*AWSIdentity) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{0} +} + +func (m *AWSIdentity) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AWSIdentity.Unmarshal(m, b) +} +func (m *AWSIdentity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AWSIdentity.Marshal(b, m, deterministic) +} +func (m *AWSIdentity) XXX_Merge(src proto.Message) { + xxx_messageInfo_AWSIdentity.Merge(m, src) +} +func (m *AWSIdentity) XXX_Size() int { + return xxx_messageInfo_AWSIdentity.Size(m) +} +func (m *AWSIdentity) XXX_DiscardUnknown() { + xxx_messageInfo_AWSIdentity.DiscardUnknown(m) +} + +var xxx_messageInfo_AWSIdentity proto.InternalMessageInfo + +func (m *AWSIdentity) GetSignedGetCallerIdentity() string { + if m != nil { + return m.SignedGetCallerIdentity + } + return "" +} + +func (m *AWSIdentity) GetClaimedIamArn() string { + if m != nil { + return m.ClaimedIamArn + } + return "" +} + +type PasswordRequest struct { + ClientLanguage ClientLanguage `protobuf:"varint,1,opt,name=client_language,json=clientLanguage,proto3,enum=approzium.authenticator.protos.ClientLanguage" json:"client_language,omitempty"` + Dbhost string `protobuf:"bytes,2,opt,name=dbhost,proto3" json:"dbhost,omitempty"` + Dbport string `protobuf:"bytes,3,opt,name=dbport,proto3" json:"dbport,omitempty"` + Dbuser string `protobuf:"bytes,4,opt,name=dbuser,proto3" json:"dbuser,omitempty"` + Aws *AWSIdentity `protobuf:"bytes,5,opt,name=aws,proto3" json:"aws,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PasswordRequest) Reset() { *m = PasswordRequest{} } +func (m *PasswordRequest) String() string { return proto.CompactTextString(m) } +func (*PasswordRequest) ProtoMessage() {} +func (*PasswordRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{1} +} + +func (m *PasswordRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PasswordRequest.Unmarshal(m, b) +} +func (m *PasswordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PasswordRequest.Marshal(b, m, deterministic) +} +func (m *PasswordRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PasswordRequest.Merge(m, src) +} +func (m *PasswordRequest) XXX_Size() int { + return xxx_messageInfo_PasswordRequest.Size(m) +} +func (m *PasswordRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PasswordRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PasswordRequest proto.InternalMessageInfo + +func (m *PasswordRequest) GetClientLanguage() ClientLanguage { + if m != nil { + return m.ClientLanguage + } + return ClientLanguage_LANGUAGE_NOT_PROVIDED +} + +func (m *PasswordRequest) GetDbhost() string { + if m != nil { + return m.Dbhost + } + return "" +} + +func (m *PasswordRequest) GetDbport() string { + if m != nil { + return m.Dbport + } + return "" +} + +func (m *PasswordRequest) GetDbuser() string { + if m != nil { + return m.Dbuser + } + return "" +} + +func (m *PasswordRequest) GetAws() *AWSIdentity { + if m != nil { + return m.Aws + } + return nil +} + +type PGMD5HashRequest struct { + PwdRequest *PasswordRequest `protobuf:"bytes,1,opt,name=pwd_request,json=pwdRequest,proto3" json:"pwd_request,omitempty"` + Salt []byte `protobuf:"bytes,2,opt,name=salt,proto3" json:"salt,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PGMD5HashRequest) Reset() { *m = PGMD5HashRequest{} } +func (m *PGMD5HashRequest) String() string { return proto.CompactTextString(m) } +func (*PGMD5HashRequest) ProtoMessage() {} +func (*PGMD5HashRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{2} +} + +func (m *PGMD5HashRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PGMD5HashRequest.Unmarshal(m, b) +} +func (m *PGMD5HashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PGMD5HashRequest.Marshal(b, m, deterministic) +} +func (m *PGMD5HashRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PGMD5HashRequest.Merge(m, src) +} +func (m *PGMD5HashRequest) XXX_Size() int { + return xxx_messageInfo_PGMD5HashRequest.Size(m) +} +func (m *PGMD5HashRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PGMD5HashRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PGMD5HashRequest proto.InternalMessageInfo + +func (m *PGMD5HashRequest) GetPwdRequest() *PasswordRequest { + if m != nil { + return m.PwdRequest + } + return nil +} + +func (m *PGMD5HashRequest) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +type PGSHA256HashRequest struct { + PwdRequest *PasswordRequest `protobuf:"bytes,1,opt,name=pwd_request,json=pwdRequest,proto3" json:"pwd_request,omitempty"` + Salt string `protobuf:"bytes,2,opt,name=salt,proto3" json:"salt,omitempty"` + Iterations uint32 `protobuf:"varint,3,opt,name=iterations,proto3" json:"iterations,omitempty"` + AuthenticationMsg string `protobuf:"bytes,4,opt,name=authentication_msg,json=authenticationMsg,proto3" json:"authentication_msg,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PGSHA256HashRequest) Reset() { *m = PGSHA256HashRequest{} } +func (m *PGSHA256HashRequest) String() string { return proto.CompactTextString(m) } +func (*PGSHA256HashRequest) ProtoMessage() {} +func (*PGSHA256HashRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{3} +} + +func (m *PGSHA256HashRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PGSHA256HashRequest.Unmarshal(m, b) +} +func (m *PGSHA256HashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PGSHA256HashRequest.Marshal(b, m, deterministic) +} +func (m *PGSHA256HashRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PGSHA256HashRequest.Merge(m, src) +} +func (m *PGSHA256HashRequest) XXX_Size() int { + return xxx_messageInfo_PGSHA256HashRequest.Size(m) +} +func (m *PGSHA256HashRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PGSHA256HashRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PGSHA256HashRequest proto.InternalMessageInfo + +func (m *PGSHA256HashRequest) GetPwdRequest() *PasswordRequest { + if m != nil { + return m.PwdRequest + } + return nil +} + +func (m *PGSHA256HashRequest) GetSalt() string { + if m != nil { + return m.Salt + } + return "" +} + +func (m *PGSHA256HashRequest) GetIterations() uint32 { + if m != nil { + return m.Iterations + } + return 0 +} + +func (m *PGSHA256HashRequest) GetAuthenticationMsg() string { + if m != nil { + return m.AuthenticationMsg + } + return "" +} + +type MYSQLSHA1HashRequest struct { + PwdRequest *PasswordRequest `protobuf:"bytes,1,opt,name=pwd_request,json=pwdRequest,proto3" json:"pwd_request,omitempty"` + Salt []byte `protobuf:"bytes,2,opt,name=salt,proto3" json:"salt,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MYSQLSHA1HashRequest) Reset() { *m = MYSQLSHA1HashRequest{} } +func (m *MYSQLSHA1HashRequest) String() string { return proto.CompactTextString(m) } +func (*MYSQLSHA1HashRequest) ProtoMessage() {} +func (*MYSQLSHA1HashRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{4} +} + +func (m *MYSQLSHA1HashRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MYSQLSHA1HashRequest.Unmarshal(m, b) +} +func (m *MYSQLSHA1HashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MYSQLSHA1HashRequest.Marshal(b, m, deterministic) +} +func (m *MYSQLSHA1HashRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MYSQLSHA1HashRequest.Merge(m, src) +} +func (m *MYSQLSHA1HashRequest) XXX_Size() int { + return xxx_messageInfo_MYSQLSHA1HashRequest.Size(m) +} +func (m *MYSQLSHA1HashRequest) XXX_DiscardUnknown() { + xxx_messageInfo_MYSQLSHA1HashRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_MYSQLSHA1HashRequest proto.InternalMessageInfo + +func (m *MYSQLSHA1HashRequest) GetPwdRequest() *PasswordRequest { + if m != nil { + return m.PwdRequest + } + return nil +} + +func (m *MYSQLSHA1HashRequest) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +type PGMD5Response struct { + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Requestid string `protobuf:"bytes,2,opt,name=requestid,proto3" json:"requestid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PGMD5Response) Reset() { *m = PGMD5Response{} } +func (m *PGMD5Response) String() string { return proto.CompactTextString(m) } +func (*PGMD5Response) ProtoMessage() {} +func (*PGMD5Response) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{5} +} + +func (m *PGMD5Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PGMD5Response.Unmarshal(m, b) +} +func (m *PGMD5Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PGMD5Response.Marshal(b, m, deterministic) +} +func (m *PGMD5Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_PGMD5Response.Merge(m, src) +} +func (m *PGMD5Response) XXX_Size() int { + return xxx_messageInfo_PGMD5Response.Size(m) +} +func (m *PGMD5Response) XXX_DiscardUnknown() { + xxx_messageInfo_PGMD5Response.DiscardUnknown(m) +} + +var xxx_messageInfo_PGMD5Response proto.InternalMessageInfo + +func (m *PGMD5Response) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +func (m *PGMD5Response) GetRequestid() string { + if m != nil { + return m.Requestid + } + return "" +} + +type PGSHA256Response struct { + Cproof string `protobuf:"bytes,1,opt,name=cproof,proto3" json:"cproof,omitempty"` + Sproof string `protobuf:"bytes,2,opt,name=sproof,proto3" json:"sproof,omitempty"` + Requestid string `protobuf:"bytes,3,opt,name=requestid,proto3" json:"requestid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PGSHA256Response) Reset() { *m = PGSHA256Response{} } +func (m *PGSHA256Response) String() string { return proto.CompactTextString(m) } +func (*PGSHA256Response) ProtoMessage() {} +func (*PGSHA256Response) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{6} +} + +func (m *PGSHA256Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PGSHA256Response.Unmarshal(m, b) +} +func (m *PGSHA256Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PGSHA256Response.Marshal(b, m, deterministic) +} +func (m *PGSHA256Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_PGSHA256Response.Merge(m, src) +} +func (m *PGSHA256Response) XXX_Size() int { + return xxx_messageInfo_PGSHA256Response.Size(m) +} +func (m *PGSHA256Response) XXX_DiscardUnknown() { + xxx_messageInfo_PGSHA256Response.DiscardUnknown(m) +} + +var xxx_messageInfo_PGSHA256Response proto.InternalMessageInfo + +func (m *PGSHA256Response) GetCproof() string { + if m != nil { + return m.Cproof + } + return "" +} + +func (m *PGSHA256Response) GetSproof() string { + if m != nil { + return m.Sproof + } + return "" +} + +func (m *PGSHA256Response) GetRequestid() string { + if m != nil { + return m.Requestid + } + return "" +} + +type MYSQLSHA1Response struct { + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Requestid string `protobuf:"bytes,2,opt,name=requestid,proto3" json:"requestid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MYSQLSHA1Response) Reset() { *m = MYSQLSHA1Response{} } +func (m *MYSQLSHA1Response) String() string { return proto.CompactTextString(m) } +func (*MYSQLSHA1Response) ProtoMessage() {} +func (*MYSQLSHA1Response) Descriptor() ([]byte, []int) { + return fileDescriptor_e86ec39f7c35dea3, []int{7} +} + +func (m *MYSQLSHA1Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MYSQLSHA1Response.Unmarshal(m, b) +} +func (m *MYSQLSHA1Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MYSQLSHA1Response.Marshal(b, m, deterministic) +} +func (m *MYSQLSHA1Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_MYSQLSHA1Response.Merge(m, src) +} +func (m *MYSQLSHA1Response) XXX_Size() int { + return xxx_messageInfo_MYSQLSHA1Response.Size(m) +} +func (m *MYSQLSHA1Response) XXX_DiscardUnknown() { + xxx_messageInfo_MYSQLSHA1Response.DiscardUnknown(m) +} + +var xxx_messageInfo_MYSQLSHA1Response proto.InternalMessageInfo + +func (m *MYSQLSHA1Response) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *MYSQLSHA1Response) GetRequestid() string { + if m != nil { + return m.Requestid + } + return "" +} + +func init() { + proto.RegisterEnum("approzium.authenticator.protos.ClientLanguage", ClientLanguage_name, ClientLanguage_value) + proto.RegisterType((*AWSIdentity)(nil), "approzium.authenticator.protos.AWSIdentity") + proto.RegisterType((*PasswordRequest)(nil), "approzium.authenticator.protos.PasswordRequest") + proto.RegisterType((*PGMD5HashRequest)(nil), "approzium.authenticator.protos.PGMD5HashRequest") + proto.RegisterType((*PGSHA256HashRequest)(nil), "approzium.authenticator.protos.PGSHA256HashRequest") + proto.RegisterType((*MYSQLSHA1HashRequest)(nil), "approzium.authenticator.protos.MYSQLSHA1HashRequest") + proto.RegisterType((*PGMD5Response)(nil), "approzium.authenticator.protos.PGMD5Response") + proto.RegisterType((*PGSHA256Response)(nil), "approzium.authenticator.protos.PGSHA256Response") + proto.RegisterType((*MYSQLSHA1Response)(nil), "approzium.authenticator.protos.MYSQLSHA1Response") +} + +func init() { proto.RegisterFile("authenticator.proto", fileDescriptor_e86ec39f7c35dea3) } + +var fileDescriptor_e86ec39f7c35dea3 = []byte{ + // 576 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x53, 0xdb, 0x6e, 0xd3, 0x40, + 0x10, 0xad, 0x93, 0x12, 0x29, 0x93, 0x6b, 0xb7, 0x50, 0x42, 0x84, 0xaa, 0xca, 0x0f, 0xa8, 0x02, + 0x35, 0xb4, 0x29, 0xe5, 0x05, 0x21, 0x64, 0x35, 0x91, 0x13, 0x29, 0x17, 0xe3, 0x14, 0xaa, 0x3e, + 0x99, 0x6d, 0xbc, 0x38, 0x96, 0x12, 0xaf, 0xbb, 0xbb, 0x51, 0xa0, 0x82, 0x1f, 0xe4, 0x6f, 0xf8, + 0x00, 0x24, 0xe4, 0xf5, 0xe6, 0x4a, 0x44, 0xf2, 0xd4, 0x37, 0xcf, 0x19, 0x9f, 0x39, 0x33, 0x67, + 0x67, 0x60, 0x1f, 0x8f, 0xc5, 0x80, 0x04, 0xc2, 0xef, 0x63, 0x41, 0x59, 0x25, 0x64, 0x54, 0x50, + 0x74, 0x88, 0xc3, 0x90, 0xd1, 0x7b, 0x7f, 0x3c, 0xaa, 0xac, 0x49, 0x73, 0x9d, 0x41, 0xc6, 0xb8, + 0xee, 0x35, 0xdd, 0x28, 0x21, 0xbe, 0xa3, 0x77, 0x50, 0xe6, 0xbe, 0x17, 0x10, 0xd7, 0xf1, 0x88, + 0x70, 0xfa, 0x78, 0x38, 0x24, 0xcc, 0xf1, 0x55, 0xb6, 0xa4, 0x1d, 0x69, 0xc7, 0x69, 0xfb, 0x69, + 0xfc, 0x87, 0x49, 0xc4, 0xa5, 0xcc, 0xcf, 0xc8, 0x2f, 0xa0, 0xd0, 0x1f, 0x62, 0x7f, 0x44, 0x5c, + 0xc7, 0xc7, 0x23, 0x07, 0xb3, 0xa0, 0x94, 0x90, 0x8c, 0x9c, 0x82, 0x9b, 0x78, 0x64, 0xb0, 0x40, + 0xff, 0xad, 0x41, 0xc1, 0xc2, 0x9c, 0x4f, 0x28, 0x73, 0x6d, 0x72, 0x37, 0x26, 0x5c, 0xa0, 0xeb, + 0x88, 0xeb, 0x93, 0x40, 0x38, 0x43, 0x1c, 0x78, 0x63, 0xec, 0x11, 0xa9, 0x96, 0xaf, 0x56, 0x2a, + 0xff, 0x9f, 0xa0, 0x72, 0x29, 0x69, 0x2d, 0xc5, 0xb2, 0xf3, 0xfd, 0xa5, 0x18, 0x1d, 0x40, 0xca, + 0xbd, 0x1d, 0x50, 0x2e, 0x54, 0x2f, 0x2a, 0x8a, 0xf1, 0x90, 0x32, 0x51, 0x4a, 0x4e, 0xf1, 0x28, + 0x8a, 0xf1, 0x31, 0x27, 0xac, 0xb4, 0x3b, 0xc5, 0xa3, 0x08, 0xbd, 0x87, 0x24, 0x9e, 0xf0, 0xd2, + 0xa3, 0x23, 0xed, 0x38, 0x53, 0x7d, 0xb5, 0xa9, 0xa9, 0x05, 0x4f, 0xed, 0x88, 0xa7, 0x7f, 0x83, + 0xa2, 0x65, 0xb6, 0x6b, 0x17, 0x0d, 0xcc, 0x07, 0xd3, 0x99, 0x2d, 0xc8, 0x84, 0x13, 0xd7, 0x61, + 0x71, 0x28, 0xe7, 0xcd, 0x54, 0x5f, 0x6f, 0x2a, 0xbd, 0xe2, 0x9c, 0x0d, 0xe1, 0x64, 0xe6, 0x22, + 0x82, 0x5d, 0x8e, 0x87, 0xf1, 0xa8, 0x59, 0x5b, 0x7e, 0xeb, 0xbf, 0x34, 0xd8, 0xb7, 0xcc, 0x5e, + 0xc3, 0xa8, 0x5e, 0xbc, 0x7d, 0x38, 0xf5, 0x74, 0xac, 0x8e, 0x0e, 0x01, 0x7c, 0x41, 0x18, 0x16, + 0x3e, 0x0d, 0xb8, 0xb4, 0x3a, 0x67, 0x2f, 0x20, 0xe8, 0x04, 0xd0, 0x82, 0x8e, 0x4f, 0x03, 0x67, + 0xc4, 0x3d, 0x65, 0xfd, 0xde, 0x72, 0xa6, 0xcd, 0x3d, 0xfd, 0x07, 0x3c, 0x6e, 0xdf, 0xf4, 0x3e, + 0xb6, 0x7a, 0x0d, 0xe3, 0xec, 0xe1, 0xad, 0x34, 0x20, 0x27, 0x1f, 0xd1, 0x26, 0x3c, 0xa4, 0x01, + 0x27, 0xd1, 0x4f, 0x03, 0xcc, 0x07, 0xea, 0x30, 0xe4, 0x37, 0x7a, 0x0e, 0x69, 0xd5, 0x86, 0xef, + 0x2a, 0x2b, 0xe6, 0x80, 0xfe, 0x25, 0xda, 0x83, 0xf8, 0x31, 0x66, 0x55, 0x0e, 0x20, 0xd5, 0x0f, + 0x19, 0xa5, 0x5f, 0x55, 0x1d, 0x15, 0x45, 0x38, 0x8f, 0x71, 0xb5, 0xba, 0x71, 0xb4, 0xac, 0x90, + 0x5c, 0x55, 0xa8, 0xc3, 0xde, 0xcc, 0xa2, 0xb5, 0x8d, 0x66, 0xb7, 0x69, 0xf4, 0xe5, 0x07, 0xc8, + 0x2f, 0x5f, 0x16, 0x7a, 0x06, 0x4f, 0x5a, 0x46, 0xc7, 0xfc, 0x64, 0x98, 0x75, 0xa7, 0xd3, 0xbd, + 0x72, 0x2c, 0xbb, 0xfb, 0xb9, 0x59, 0xab, 0xd7, 0x8a, 0x3b, 0x08, 0x20, 0x65, 0xdd, 0x5c, 0x35, + 0xba, 0x9d, 0xa2, 0x86, 0x52, 0x90, 0x30, 0xbb, 0xc5, 0x44, 0xf5, 0x4f, 0x02, 0x72, 0xc6, 0xa2, + 0xeb, 0xe8, 0x0e, 0xb2, 0x26, 0x11, 0xb3, 0x33, 0x40, 0xa7, 0x1b, 0xdf, 0x67, 0xe5, 0x62, 0xca, + 0x27, 0x5b, 0x31, 0xa6, 0x53, 0xeb, 0x3b, 0xe8, 0x1e, 0x0a, 0x52, 0x72, 0xbe, 0xfe, 0xe8, 0x7c, + 0x73, 0x8d, 0x7f, 0x8e, 0xa5, 0x7c, 0xba, 0x2d, 0x69, 0x41, 0xfb, 0x27, 0x14, 0x4d, 0x22, 0x96, + 0xd6, 0x15, 0xbd, 0xd9, 0x54, 0x67, 0xdd, 0x76, 0x97, 0xcf, 0xb6, 0x66, 0xcd, 0xe5, 0x6f, 0x53, + 0x32, 0x77, 0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x9c, 0x11, 0x55, 0x17, 0x06, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// AuthenticatorClient is the client API for Authenticator service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type AuthenticatorClient interface { + GetPGMD5Hash(ctx context.Context, in *PGMD5HashRequest, opts ...grpc.CallOption) (*PGMD5Response, error) + GetPGSHA256Hash(ctx context.Context, in *PGSHA256HashRequest, opts ...grpc.CallOption) (*PGSHA256Response, error) + GetMYSQLSHA1Hash(ctx context.Context, in *MYSQLSHA1HashRequest, opts ...grpc.CallOption) (*MYSQLSHA1Response, error) +} + +type authenticatorClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthenticatorClient(cc grpc.ClientConnInterface) AuthenticatorClient { + return &authenticatorClient{cc} +} + +func (c *authenticatorClient) GetPGMD5Hash(ctx context.Context, in *PGMD5HashRequest, opts ...grpc.CallOption) (*PGMD5Response, error) { + out := new(PGMD5Response) + err := c.cc.Invoke(ctx, "/approzium.authenticator.protos.Authenticator/GetPGMD5Hash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authenticatorClient) GetPGSHA256Hash(ctx context.Context, in *PGSHA256HashRequest, opts ...grpc.CallOption) (*PGSHA256Response, error) { + out := new(PGSHA256Response) + err := c.cc.Invoke(ctx, "/approzium.authenticator.protos.Authenticator/GetPGSHA256Hash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authenticatorClient) GetMYSQLSHA1Hash(ctx context.Context, in *MYSQLSHA1HashRequest, opts ...grpc.CallOption) (*MYSQLSHA1Response, error) { + out := new(MYSQLSHA1Response) + err := c.cc.Invoke(ctx, "/approzium.authenticator.protos.Authenticator/GetMYSQLSHA1Hash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AuthenticatorServer is the server API for Authenticator service. +type AuthenticatorServer interface { + GetPGMD5Hash(context.Context, *PGMD5HashRequest) (*PGMD5Response, error) + GetPGSHA256Hash(context.Context, *PGSHA256HashRequest) (*PGSHA256Response, error) + GetMYSQLSHA1Hash(context.Context, *MYSQLSHA1HashRequest) (*MYSQLSHA1Response, error) +} + +// UnimplementedAuthenticatorServer can be embedded to have forward compatible implementations. +type UnimplementedAuthenticatorServer struct { +} + +func (*UnimplementedAuthenticatorServer) GetPGMD5Hash(ctx context.Context, req *PGMD5HashRequest) (*PGMD5Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPGMD5Hash not implemented") +} +func (*UnimplementedAuthenticatorServer) GetPGSHA256Hash(ctx context.Context, req *PGSHA256HashRequest) (*PGSHA256Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPGSHA256Hash not implemented") +} +func (*UnimplementedAuthenticatorServer) GetMYSQLSHA1Hash(ctx context.Context, req *MYSQLSHA1HashRequest) (*MYSQLSHA1Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMYSQLSHA1Hash not implemented") +} + +func RegisterAuthenticatorServer(s *grpc.Server, srv AuthenticatorServer) { + s.RegisterService(&_Authenticator_serviceDesc, srv) +} + +func _Authenticator_GetPGMD5Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PGMD5HashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthenticatorServer).GetPGMD5Hash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/approzium.authenticator.protos.Authenticator/GetPGMD5Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthenticatorServer).GetPGMD5Hash(ctx, req.(*PGMD5HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Authenticator_GetPGSHA256Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PGSHA256HashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthenticatorServer).GetPGSHA256Hash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/approzium.authenticator.protos.Authenticator/GetPGSHA256Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthenticatorServer).GetPGSHA256Hash(ctx, req.(*PGSHA256HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Authenticator_GetMYSQLSHA1Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MYSQLSHA1HashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthenticatorServer).GetMYSQLSHA1Hash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/approzium.authenticator.protos.Authenticator/GetMYSQLSHA1Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthenticatorServer).GetMYSQLSHA1Hash(ctx, req.(*MYSQLSHA1HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Authenticator_serviceDesc = grpc.ServiceDesc{ + ServiceName: "approzium.authenticator.protos.Authenticator", + HandlerType: (*AuthenticatorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetPGMD5Hash", + Handler: _Authenticator_GetPGMD5Hash_Handler, + }, + { + MethodName: "GetPGSHA256Hash", + Handler: _Authenticator_GetPGSHA256Hash_Handler, + }, + { + MethodName: "GetMYSQLSHA1Hash", + Handler: _Authenticator_GetMYSQLSHA1Hash_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "authenticator.proto", +} diff --git a/authenticator/server/protos/authenticator.proto b/authenticator/server/protos/authenticator.proto new file mode 100644 index 00000000..a89e039c --- /dev/null +++ b/authenticator/server/protos/authenticator.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; + +package approzium.authenticator.protos; + +service Authenticator { + rpc GetPGMD5Hash(PGMD5HashRequest) returns (PGMD5Response) {} + rpc GetPGSHA256Hash(PGSHA256HashRequest) returns (PGSHA256Response) {} + rpc GetMYSQLSHA1Hash(MYSQLSHA1HashRequest) returns (MYSQLSHA1Response) {} + /* can add more here */ +} + +message AWSIdentity { + string signed_get_caller_identity = 1; + string claimed_iam_arn = 2; +} + +enum ClientLanguage { + LANGUAGE_NOT_PROVIDED = 0; + PYTHON = 1; + GO = 2; +} + +message PasswordRequest { + ClientLanguage client_language = 1; + string dbhost = 2; + string dbport = 3; + string dbuser = 4; + AWSIdentity aws = 5; + /* can add more here */ +} + +message PGMD5HashRequest { + PasswordRequest pwd_request = 1; + bytes salt = 2; +} + +message PGSHA256HashRequest { + PasswordRequest pwd_request = 1; + string salt = 2; + uint32 iterations = 3; + string authentication_msg = 4; +} + +message MYSQLSHA1HashRequest { + PasswordRequest pwd_request = 1; + bytes salt = 2; +} + +message PGMD5Response { + string hash = 1; + string requestid = 2; +} + +message PGSHA256Response { + string cproof = 1; + string sproof = 2; + string requestid = 3; +} + +message MYSQLSHA1Response { + bytes hash = 1; + string requestid = 2; +} diff --git a/authenticator/server/requestlogger.go b/authenticator/server/requestlogger.go new file mode 100644 index 00000000..f9eccad5 --- /dev/null +++ b/authenticator/server/requestlogger.go @@ -0,0 +1,198 @@ +package server + +import ( + "context" + "encoding/json" + "time" + + pb "github.com/cyralinc/approzium/authenticator/server/protos" + "github.com/getlantern/deepcopy" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +const ( + ctxLogger = "logger" + redactedValue = "********" +) + +// getRequestLogger gets a logger that includes the request ID +// with every line, and a trace ID if it was sent. +func getRequestLogger(ctx context.Context) *log.Entry { + rawLogger := ctx.Value(ctxLogger) + if rawLogger == nil { + return &log.Entry{} + } + logger, ok := rawLogger.(*log.Entry) + if !ok { + return &log.Entry{} + } + return logger +} + +func newRequestLogger(logger *log.Logger, logRaw bool, wrapped pb.AuthenticatorServer) pb.AuthenticatorServer { + return &requestLogger{ + logger: logger, + logRaw: logRaw, + wrapped: wrapped, + } +} + +type requestLogger struct { + // logger is the application-level logger. It holds settings like the log format and level, + // but lacks request-related context. + logger *log.Logger + + // If true, will not redact fields that appear to hold sensitive information. + // Defaults to false. + logRaw bool + + // wrapped is the AuthenticatorServer we're logging requests and responses for. + wrapped pb.AuthenticatorServer +} + +func (l *requestLogger) GetPGMD5Hash(ctx context.Context, req *pb.PGMD5HashRequest) (*pb.PGMD5Response, error) { + requestId, requestLogger, err := l.buildContextualLogger() + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + sanitized := &pb.PGMD5HashRequest{} + if err := deepcopy.Copy(sanitized, req); err != nil { + return nil, err + } + if sanitized.PwdRequest != nil && sanitized.PwdRequest.GetAws() != nil { + sanitized.PwdRequest.GetAws().SignedGetCallerIdentity = redactedValue + } + l.logSanitizedRequest(requestLogger, sanitized) + + resp, respErr := l.wrapped.GetPGMD5Hash(context.WithValue(ctx, ctxLogger, requestLogger), req) + + if resp == nil { + resp = &pb.PGMD5Response{} + } + resp.Requestid = requestId + l.logSanitizedResponse(requestLogger, resp, respErr) + return resp, respErr +} + +func (l *requestLogger) GetPGSHA256Hash(ctx context.Context, req *pb.PGSHA256HashRequest) (*pb.PGSHA256Response, error) { + requestId, requestLogger, err := l.buildContextualLogger() + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + sanitized := &pb.PGSHA256HashRequest{} + if err := deepcopy.Copy(sanitized, req); err != nil { + return nil, err + } + if sanitized.PwdRequest != nil && sanitized.PwdRequest.GetAws() != nil { + sanitized.PwdRequest.GetAws().SignedGetCallerIdentity = redactedValue + } + l.logSanitizedRequest(requestLogger, sanitized) + + resp, respErr := l.wrapped.GetPGSHA256Hash(context.WithValue(ctx, ctxLogger, requestLogger), req) + + if resp == nil { + resp = &pb.PGSHA256Response{} + } + resp.Requestid = requestId + l.logSanitizedResponse(requestLogger, resp, respErr) + return resp, respErr +} + +func (l *requestLogger) GetMYSQLSHA1Hash(ctx context.Context, req *pb.MYSQLSHA1HashRequest) (*pb.MYSQLSHA1Response, error) { + requestId, requestLogger, err := l.buildContextualLogger() + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + sanitized := &pb.MYSQLSHA1HashRequest{} + if err := deepcopy.Copy(sanitized, req); err != nil { + return nil, err + } + if sanitized.PwdRequest != nil && sanitized.PwdRequest.GetAws() != nil { + sanitized.PwdRequest.GetAws().SignedGetCallerIdentity = redactedValue + } + l.logSanitizedRequest(requestLogger, sanitized) + + resp, respErr := l.wrapped.GetMYSQLSHA1Hash(context.WithValue(ctx, ctxLogger, requestLogger), req) + + if resp == nil { + resp = &pb.MYSQLSHA1Response{} + } + resp.Requestid = requestId + l.logSanitizedResponse(requestLogger, resp, respErr) + return resp, respErr +} + +func (l *requestLogger) logSanitizedRequest(requestLogger *log.Entry, req interface{}) { + // Log asynchronously to avoid blocking while lots of JSON conversion takes place. + preciseTime := time.Now().UTC() + go func() { + reqMap, err := toMap(req) + if err != nil { + requestLogger.Warnf("couldn't log request due to %s", err) + return + } + fields := log.Fields{ + "precise_time": preciseTime.Format(time.RFC3339Nano), + } + for k, v := range reqMap { + fields[k] = v + } + requestLogger.WithFields(fields).Info("request") + }() +} + +func (l *requestLogger) logSanitizedResponse(requestLogger *log.Entry, resp interface{}, respErr error) { + // Log asynchronously to avoid blocking while lots of JSON conversion takes place. + preciseTime := time.Now().UTC() + go func() { + respMap, err := toMap(resp) + if err != nil { + requestLogger.Warnf("couldn't log response due to %s", err) + return + } + fields := log.Fields{ + "precise_time": preciseTime.Format(time.RFC3339Nano), + } + for k, v := range respMap { + fields[k] = v + } + if respErr != nil { + fields["error"] = respErr.Error() + requestLogger.WithFields(fields).Error("response") + return + } + requestLogger.WithFields(fields).Info("response") + }() +} + +func (l *requestLogger) buildContextualLogger() (string, *log.Entry, error) { + randomUuid, err := uuid.NewRandom() + if err != nil { + return "", nil, err + } + requestId := randomUuid.String() + + // Create the logger from the application-level one to retain its settings. + requestLogger := l.logger.WithFields(log.Fields{ + "request_id": requestId, + }) + return requestId, requestLogger, nil +} + +func toMap(obj interface{}) (map[string]interface{}, error) { + objJson, err := json.Marshal(obj) + if err != nil { + return nil, err + } + objMap := make(map[string]interface{}) + if err := json.Unmarshal(objJson, &objMap); err != nil { + return nil, err + } + return objMap, nil +} diff --git a/authenticator/server/requestmetrics.go b/authenticator/server/requestmetrics.go new file mode 100644 index 00000000..873a50a7 --- /dev/null +++ b/authenticator/server/requestmetrics.go @@ -0,0 +1,117 @@ +package server + +import ( + "context" + "time" + + "github.com/cyralinc/approzium/authenticator/server/metrics" + pb "github.com/cyralinc/approzium/authenticator/server/protos" + "go.opencensus.io/metric" + "go.opencensus.io/metric/metricdata" +) + +func newRequestMetrics(wrapped pb.AuthenticatorServer) (pb.AuthenticatorServer, error) { + numRequests, err := metrics.Registry.AddInt64Cumulative("total_requests", metric.WithDescription("Total number of requests")) + if err != nil { + return nil, err + } + numRequestsEntry, err := numRequests.GetEntry() + if err != nil { + return nil, err + } + + numResponses, err := metrics.Registry.AddInt64Cumulative( + "total_responses", + metric.WithDescription("Total number of responses"), + ) + if err != nil { + return nil, err + } + numResponsesEntry, err := numResponses.GetEntry() + if err != nil { + return nil, err + } + + numErrResponses, err := metrics.Registry.AddInt64Cumulative( + "total_error_responses", + metric.WithDescription("Total number of error responses"), + ) + if err != nil { + return nil, err + } + numErrResponsesEntry, err := numErrResponses.GetEntry() + if err != nil { + return nil, err + } + + totalReqMs, err := metrics.Registry.AddInt64Gauge( + "total_request_milliseconds", + metric.WithDescription("Total request milliseconds"), + metric.WithUnit(metricdata.UnitMilliseconds), + ) + if err != nil { + return nil, err + } + totalReqMsEntry, err := totalReqMs.GetEntry() + if err != nil { + return nil, err + } + return &requestMetrics{ + wrapped: wrapped, + numRequests: numRequestsEntry, + numResponses: numResponsesEntry, + numErrResponses: numErrResponsesEntry, + reqMilliseconds: totalReqMsEntry, + }, nil +} + +type requestMetrics struct { + wrapped pb.AuthenticatorServer + + numRequests *metric.Int64CumulativeEntry + numResponses *metric.Int64CumulativeEntry + numErrResponses *metric.Int64CumulativeEntry + reqMilliseconds *metric.Int64GaugeEntry +} + +func (m *requestMetrics) GetPGMD5Hash(ctx context.Context, req *pb.PGMD5HashRequest) (*pb.PGMD5Response, error) { + start := time.Now().UTC() + m.numRequests.Inc(1) + + resp, err := m.wrapped.GetPGMD5Hash(ctx, req) + if err != nil { + m.numErrResponses.Inc(1) + } + + m.numResponses.Inc(1) + m.reqMilliseconds.Set(time.Now().UTC().Sub(start).Milliseconds()) + return resp, err +} + +func (m *requestMetrics) GetPGSHA256Hash(ctx context.Context, req *pb.PGSHA256HashRequest) (*pb.PGSHA256Response, error) { + start := time.Now().UTC() + m.numRequests.Inc(1) + + resp, err := m.wrapped.GetPGSHA256Hash(ctx, req) + if err != nil { + m.numErrResponses.Inc(1) + } + + m.numResponses.Inc(1) + m.reqMilliseconds.Set(time.Now().UTC().Sub(start).Milliseconds()) + return resp, err +} + +func (m *requestMetrics) GetMYSQLSHA1Hash(ctx context.Context, req *pb.MYSQLSHA1HashRequest) (*pb.MYSQLSHA1Response, error) { + start := time.Now().UTC() + m.numRequests.Inc(1) + + resp, err := m.wrapped.GetMYSQLSHA1Hash(ctx, req) + if err != nil { + m.numErrResponses.Inc(1) + } + + m.numResponses.Inc(1) + m.reqMilliseconds.Set(time.Now().UTC().Sub(start).Milliseconds()) + return resp, err +} diff --git a/authenticator/server/testing/approzium.key b/authenticator/server/testing/approzium.key new file mode 100644 index 00000000..34365648 --- /dev/null +++ b/authenticator/server/testing/approzium.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/authenticator/server/testing/approzium.pem b/authenticator/server/testing/approzium.pem new file mode 100644 index 00000000..d82cebbf --- /dev/null +++ b/authenticator/server/testing/approzium.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFXDCCA0QCCQDGhVv0O+55WjANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCTkoxETAPBgNVBAoMCENBLCBJbmMuMCAXDTIwMDcwNjE4MDgy +NFoYDzIxMjAwNjEyMTgwODI0WjCBsDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFTATBgNVBAcMDFJlZHdvb2QgQ2l0eTEOMAwGA1UECgwFQ3lyYWwx +EjAQBgNVBAsMCUFwcHJveml1bTEvMC0GA1UEAwwmaHR0cHM6Ly9naXRodWIuY29t +L2FwcHJveml1bS9hcHByb3ppdW0xIDAeBgkqhkiG9w0BCQEWEXByb2R1Y3RAY3ly +YWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0nBe4Rl1nxFw +kq/WPOD6ZydAOC8Ui1E18k8cMwp4hyXjdpFUZDgwvVEypxGbRDPycIeOcy0cLw0U +JtMCtY3AkTp9k1kIiogByq2R5OInLVPOea13wDwqC6vjAnBBGP8HRKDO5566TWgT +8rcdCYXmitTa4E+6gim2wFfnGi+MelB7icP+QMD6xGLSh/p6WnSKBqgA9NcHrRl/ ++ulh7ofbREsBK3xmo2gd1grZgx9XVrEJs5kYrOdbXpUAdoc2yFeIDk2QQBdlN4+x +VZVsTJTSHhykLvCYBddsYFygeDUSBWkYYcAOuovfm/wuHu/5tyzxAh7ph01aO5f+ +o/sb9ZKb9nMO06f47A2FnA+rwD5w4X9x3/cl/64zNU4kM34JipPQYEgyNPeZ3ZLk +5x79/LHw1rnys/QWn1jCLgj7QM45pXx2wjsDBBpNiwzCqzXZCxJLePyr0sMJWbWY +o7rCVXHWET/Iu2oMo3FnolfAYBx0H6uu+O+pUBUCn8AsdNL3JvUDiXVtDJ8V+tXC +WzcIS7Fe3dNlAkT66xYfI27cTRyUjMR4RZvsEZ3wPd/+iwJcoBeT6pwWzGvFODEQ +UAIBLYymjkXqHrdFDx2Vld5Yji3OgYl/ECLRIIeEDdFWa9yjeZyHLKjvQympb5Dl +0h2sE/6wYZlAY1wavLlJeTfvbM46RHUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA +vlqzhPjIo/JsZVJ4h3JSIIjpYpzxk/0VXLaepweRj3MSrJvwI82p7dVrMX7SmtHx +z4Gty41FfdeSTuVNaY73Z1fXwuvp/FXpWvpnmUB1nOBEBQ4GbeQkZKCIn4m+PquV +0xSiDSlNynrjizwytuJZ9ucYxldEhRKzIcKkkefYKjA+qYA6wLIwMSMdNSWMZnb7 +i5G4ro4M8l1Yre+ayNETphoo0byftibL5bfMm4gEnStzzNJeq098yJpWNy6ksHAZ +7fIdJ9zCAxOaRolXBZ0Zrory9iFXMr67s80RgXXpkg6fJK3slW4Ll2yFAkwsnH72 +KEHjwvaHZIlDWK6E0fANB/XyKs0dbREGu1lMMnfdyfVNWO9FePH1uu2n/fs2/wrI +y9Hoj17qMGFQdtJly5t5FRG5gywZpnzQz/2pQehcwKBzUa3eXVPCs4GgecWeBE4o +tHB/cQHQqGha4wXMdS6GcsnH8FdF58kcxo5vnEVTEluEDzFTWFGgrnoHGSCvMiXs +rzNEgzmk5REt5T021Y/okhvrFlYp478KumEoWtYUhcznV8CB81dDzjvMIobR7DrF +xThBSKXfnlih0KoVYUjR5qEKz8JLXRi6PybXIvwPmU5dWBrutumnFug5INd6Pjqa +625XEsmZDIy94sJx7vQNh6MICI0ax3VNWUcxOGPGcF8= +-----END CERTIFICATE----- diff --git a/authenticator/server/testing/awsutil.go b/authenticator/server/testing/awsutil.go new file mode 100644 index 00000000..1530373f --- /dev/null +++ b/authenticator/server/testing/awsutil.go @@ -0,0 +1,56 @@ +package testing + +import ( + "os" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/sts" +) + +const envVarTestRole = "TEST_ASSUMABLE_ARN" + +// This allows us to only get the signedGetCallerIdentity string once, but +// to reuse it throughout tests through the testEnv variable, reducing load +// on AWS. +type AwsEnv struct { + signedGetCallerIdentity string +} + +func (e *AwsEnv) ClaimedArn() string { + return os.Getenv(envVarTestRole) +} + +func (e *AwsEnv) SignedGetCallerIdentity(t *testing.T) (string, error) { + + if os.Getenv(envVarTestRole) == "" { + t.Fatalf("skipping because %s is unset", envVarTestRole) + } + + // If it's cached, return it. + if e.signedGetCallerIdentity != "" { + return e.signedGetCallerIdentity, nil + } + + // If it's uncached, get it, cache it, and return it. + sess, err := session.NewSession() + if err != nil { + return "", err + } + creds := stscreds.NewCredentials(sess, os.Getenv(envVarTestRole)) + + // Create service client value configured for credentials + // from assumed role. + svc := sts.New(sess, &aws.Config{Credentials: creds}) + + req, _ := svc.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{}) + signedGetCallerIdentity, err := req.Presign(time.Minute * 15) + if err != nil { + return "", err + } + e.signedGetCallerIdentity = signedGetCallerIdentity + return e.signedGetCallerIdentity, nil +} diff --git a/authenticator/server/testing/ca.cert b/authenticator/server/testing/ca.cert new file mode 100644 index 00000000..77343f09 --- /dev/null +++ b/authenticator/server/testing/ca.cert @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE2DCCAsACCQDGw4FLXNHU3DANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCTkoxETAPBgNVBAoMCENBLCBJbmMuMCAXDTIwMDcwNjE4MDUy +N1oYDzIxMjAwNjEyMTgwNTI3WjAtMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkox +ETAPBgNVBAoMCENBLCBJbmMuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA1a1V2P18MmxlchP1BAEWIrZdVb1feUZs8oyszEGVZbr25EYWwikT1LMdyZTH +V/J+7xvuoamqcNpsOwgK7B6stQtCqf/uvAoXvCluwef/a1V6EdgXF6heEZRXEiBE +mONRUpfNFwmxohORkOi4RmJoOCUJHaog82JChaGMtpH+VLjHO7jBhz+5AQ36Cmwu +RU89Uas/gNfvC4pQr/0zTcXmQuVsxpZkou1l3j2ZBFEZLS9PDPy3128+vq/CyTCu +MgK9eCzR1xbDhg5m10tHYeC25R9izVDGU1ovDn8dILqZ25SwfekI14iZHg/poWvu +kLht0A+mhJuUIL6HSyr212TzqZH0CnYzvI1wlW3BUFD+ko2rNVeWgVrdmgkgGd1V +gXbQ445Q48HnUQWOg/+ib5kMMV/4R2G5OdcxY1xo8qc930dm5E12N13Hsa5zFRbD +Vqx73akrjbrn2PKCfZC+gJKLfFgnGKNsiyfaPPPTfQHzClj27F/5XqOv7YHre9EL +OI+N2LfoVWGfuzgCRnXyI+CXdhn8v4fO0QbE9gvu6pPxkauueCCTqGr4IisUX0h0 +O4mRp1HmQZbyaITRev6WWAnvMu+JUnYhu0L7FWMC4uk/ZXIM3ymPwmgxwrOyq0bk +53oCh4yurh0IK4AAOhyWYLenMztutTX/ydYUDJFX5Vtt98sCAwEAATANBgkqhkiG +9w0BAQsFAAOCAgEAbbLcmQA8qTVy2D3yYUk1CXo9dBsikw1bj+/ybG0zjGsnzYce +qfiXDqO8p2viL346w5S8BWfroF/o5IZE0p5B4lWHYl9OM6oKqBR+fm4Ng63rkWcN +e4BLSbh6jTmjgS5s73lknQ/gZSRgW/9eA6wJZG1O0QQ9vWXnyUoAaWoi1UHt+JG0 +lwAaOwNBfOfyMZ2VoCItiLRH70TrHJ0VyBDnJYhaE3WeUz6cqJZ9TpGCN8jeDF6E +Tie/mCB1gum9swEJic9HR6bBWNYBjp1Ab5Az00rwJv5oVOazBtQ0sRUxnjlQ4UcF +lBsdSScAEBXu0alvMPx0j79le2XbdNoUKaIXDONIdHwcPQEHi5Isl4nRy+ZyBlcC +JAR1rglL5/C1x03zMyNC1eY84ve7g7XUpjn/X4ivEM5OgjGtUI+CGdtwHDS382QU +QKO3tnSSK/tr7BQd9l1Yg0vJlbdUppsnkRzO7NQf9T8S42WUjQIgvkn4qIauAEyt +EgzcxlcBeAlUGZalX/5V2RzzL3a+T6D1eCQfSyIQfmV+2vvRODzaaXXf0SMYN/iH +lVuRNU83FdcbkJCnoBTMKTQjedE1f0XsWTcONxQGvD0e7Y3c5ATmILX5M2MOvdSw +HYfGC0G+aVYwlk7aSX82hpJX4W6FPolMvy4JQWtbidhFqN+WhDN8DA22SzM= +-----END CERTIFICATE----- diff --git a/authenticator/server/testing/ca.key b/authenticator/server/testing/ca.key new file mode 100644 index 00000000..4bf90eed --- /dev/null +++ b/authenticator/server/testing/ca.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/authenticator/server/testing/client.key b/authenticator/server/testing/client.key new file mode 100644 index 00000000..8ca13187 --- /dev/null +++ b/authenticator/server/testing/client.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/authenticator/server/testing/client.pem b/authenticator/server/testing/client.pem new file mode 100644 index 00000000..b42e179b --- /dev/null +++ b/authenticator/server/testing/client.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFOTCCAyECCQDGhVv0O+55WzANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCTkoxETAPBgNVBAoMCENBLCBJbmMuMCAXDTIwMDcwNjIxMDAy +MloYDzIxMjAwNjEyMjEwMDIyWjCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFTATBgNVBAcMDFJlZHdvb2QgQ2l0eTEOMAwGA1UECgwFQ3lyYWwx +GTAXBgNVBAsMEEFwcHJveml1bSBDbGllbnQxEzARBgNVBAMMCmNsaWVudGNlcnQx +EjAQBgkqhkiG9w0BCQEWA2ZvbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALzWbg8USCYydN1bUyzYuWDTSkf3ZssQ4ijV5SpQoI5cGroOSYFO0qo1wwv/ +T5t7OVSk9aZVINGPJR/NPtD7C8O+dvmYVY0Et2g15UeqVN0B4fKfBc9m2UtIFD3V +m7AZpbZjJLibRSptn2DkbVSlTKJHy5AODH4vGoT21qfM89uuz6tnoKmJb2JE8Mh4 +ArQj89f9i+mrGbA38INDw74+3vd/QIXRUd7r5kiWOVu8oN9nOhU3naqP1sJJyCqk +SS8QqoXMAbk8lm88IvM0+ykwFEqrd5+p+q4/MAsmsEp+oxU7AKixQLqcsZRtjYMs +J1IIh7jWGoNmG1c3lWj4SUAx54J6NY9E9icvFz9TCE9Ksz7InCgb4IgzYCoFNRhc +Udlygyjn1mHnrrNUDmaKGExB7j95z5Z/p1hzoy3Tviq+kd7GR0MFymwzjP83Qp7s +RKz/WdrAuYWwwSowYGbaB6eP6/REw6Vwr0vjYR4sAB9EQAweH5Vn1adcsMpYdbbx +mbhKMykEyUWSYmWeGrQxB6rDx3If01XonfdCDY3hRb4TbbHYO0Hn8z107k/Cg3s0 +oF4GnOS2/LRNln+x0DasCo2SGoBMnZh5aMj+9VYsB4UrqQoEfGrBLP3kRjGkVDS5 +j/nU9etyoMG9EQzd6X/hqaalpUR6HQwvztwyGfx/PQrpFHI9AgMBAAEwDQYJKoZI +hvcNAQELBQADggIBAEM/2eJ8OsMfACZ59xJn7kXsnpVtEEd/VssVJJv0KJ5w79CP +CUiNwp1GGShgS6WVEdyhLGxqxlpC+ndyI6zWhuLA95GLtPmitakvo0XlFPvavi5E +0kzd4B7fBNK8WNYPxDAs1eYJ6WiBqK7hsE9xyYS+eqKAed1/18cLCnSdWOst1rQj +WgOy92QV7QcH8Aywzy4g33wNRxWMjCKelUK1SKEJmrAQ7h9ZA392s/mqSfoE1CB6 +6tSibiu3f21mKunMMgw5zBMWPySDDt8I+dSxLK0eDYyLT9e3s67oJ++o/40yubxa +ThKSzCUglDOmXUDfip7/1a55r3+ks4XCbwK363ZjdOmzn7E6phnhq+yCnaU3dcK3 +pM7XzxBCQbUrWmdIxHHU4sEXfSBDVOm63D6HQiUK++ZatMGGipz4h4mMRogs8yRm +B/7q2IGJT2Kkn/xi43vdhCtffRqB2jiIEOzlxeur5eibqy9qreRO7Oos961RsPEo +++QZDEiE8Qmm35HF2IbQtks+yBNeZ80p/5c+OTinCoXXI0I2aSQqZHfEufud3sVw +xfsskMmrz4lTd7UUUEW2kjCIMOlQUtm5HV8D6kR23rcRQRE5nPMZcYtxlf1DfsOw +YWGrR3OFaOxyC+eFVithdxSIjqtoAYRnOuiMRyrYDIgU2gpbSGy+PDTHdJyJ +-----END CERTIFICATE----- diff --git a/authenticator/server/testing/prometheus.txt b/authenticator/server/testing/prometheus.txt new file mode 100644 index 00000000..2b4c2a1e --- /dev/null +++ b/authenticator/server/testing/prometheus.txt @@ -0,0 +1,39 @@ +# HELP approzium_total_aws_request_milliseconds Total AWS request milliseconds +# TYPE approzium_total_aws_request_milliseconds gauge +approzium_total_aws_request_milliseconds 0 +# HELP approzium_total_error_responses Total number of error responses +# TYPE approzium_total_error_responses counter +approzium_total_error_responses 1 +# HELP approzium_total_identity_matching_attempts Total checks of whether the identity a caller claims matches their actual identity +# TYPE approzium_total_identity_matching_attempts counter +approzium_total_identity_matching_attempts 0 +# HELP approzium_total_identity_matching_failures Total calls where caller claimed an identity that was not their actual identity +# TYPE approzium_total_identity_matching_failures counter +approzium_total_identity_matching_failures 0 +# HELP approzium_total_identity_verification_attempts Total attempts to verify caller identity +# TYPE approzium_total_identity_verification_attempts counter +approzium_total_identity_verification_attempts 0 +# HELP approzium_total_identity_verification_failures Total failures to verify caller identity +# TYPE approzium_total_identity_verification_failures counter +approzium_total_identity_verification_failures 0 +# HELP approzium_total_password_request_milliseconds Total password retrieval milliseconds +# TYPE approzium_total_password_request_milliseconds gauge +approzium_total_password_request_milliseconds 0 +# HELP approzium_total_password_retrieval_attempts The number of times a caller has requested a password from the database to authenticate +# TYPE approzium_total_password_retrieval_attempts counter +approzium_total_password_retrieval_attempts 0 +# HELP approzium_total_password_retrieval_failures The number of times a caller has failed to retrieve a password for any reason +# TYPE approzium_total_password_retrieval_failures counter +approzium_total_password_retrieval_failures 0 +# HELP approzium_total_password_retrieval_unauthorized The number of times a caller has been unauthorized to retrieve a password +# TYPE approzium_total_password_retrieval_unauthorized counter +approzium_total_password_retrieval_unauthorized 0 +# HELP approzium_total_request_milliseconds Total request milliseconds +# TYPE approzium_total_request_milliseconds gauge +approzium_total_request_milliseconds 0 +# HELP approzium_total_requests Total number of requests +# TYPE approzium_total_requests counter +approzium_total_requests 1 +# HELP approzium_total_responses Total number of responses +# TYPE approzium_total_responses counter +approzium_total_responses 1 \ No newline at end of file diff --git a/authenticator/server/testing/secrets.yaml b/authenticator/server/testing/secrets.yaml new file mode 100644 index 00000000..d814b846 --- /dev/null +++ b/authenticator/server/testing/secrets.yaml @@ -0,0 +1,21 @@ +--- +- dbhost: dbmd5 + dbport: 5432 + dbuser: bob + password: password + iam_arn: ${TEST_ASSUMABLE_ARN} +- dbhost: dbsha256 + dbport: 5432 + dbuser: bob + password: password + iam_arn: ${TEST_ASSUMABLE_ARN} +- dbhost: dbmysql + dbport: 3306 + dbuser: bob + password: password + iam_arn: ${TEST_ASSUMABLE_ARN} +- dbhost: foo + dbport: 5432 + dbuser: bob + password: password + iam_arn: arn:partition:service:region:account-id:arn-thats-not-mine diff --git a/authenticator/server/testing/testutil.go b/authenticator/server/testing/testutil.go new file mode 100644 index 00000000..ea132469 --- /dev/null +++ b/authenticator/server/testing/testutil.go @@ -0,0 +1,43 @@ +package testing + +import ( + "net/http" + "os" + + log "github.com/sirupsen/logrus" +) + +const EnvVarAcceptanceTests = "APPROZIUM_ACC" + +func ShouldRunAcceptanceTests() bool { + return os.Getenv(EnvVarAcceptanceTests) != "" +} + +func TestLogger() *log.Logger { + logger := log.New() + logger.Level = log.FatalLevel + return logger +} + +type TestResponseWriter struct { + HeaderToReturn http.Header + + LastWriteInputReceived []byte + WriteIntToReturn int + WriteErrToReturn error + + LastStatusCodeReceived int +} + +func (t *TestResponseWriter) Header() http.Header { + return t.HeaderToReturn +} + +func (t *TestResponseWriter) Write(input []byte) (int, error) { + t.LastWriteInputReceived = input + return t.WriteIntToReturn, t.WriteErrToReturn +} + +func (t *TestResponseWriter) WriteHeader(statusCode int) { + t.LastStatusCodeReceived = statusCode +} diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 00000000..6769be55 --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,34 @@ +# Defines environment for running the testsuite +version: '3.5' +services: + tests: + build: + context: ./ + target: dev + volumes: + - .:/usr/src/approzium + - ~/.aws/:/root/.aws/:ro + working_dir: /usr/src/approzium/ + command: make run-testsuite + environment: + - APPROZIUM_HOST=0.0.0.0 + - APPROZIUM_DISABLE_TLS=false + - APPROZIUM_PATH_TO_TLS_CERT=/app/approzium.pem + - APPROZIUM_PATH_TO_TLS_KEY=/app/approzium.key + - TEST_CERT_DIR=/usr/src/approzium/authenticator/server/testing + - VAULT_ADDR=http://vault:8200 + - VAULT_TOKEN=root + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + - TEST_ASSUMABLE_ARN + - TEST_BASE_ARN + - PSYCOPG2_TESTDB + - PSYCOPG2_TESTDB_HOST + - PSYCOPG2_TESTDB_PORT + - PSYCOPG2_TESTDB_USER=bob + depends_on: + - authenticator + - dbmd5 + - dbsha256 + - dbmysqlsha1 + - vault diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..6b897e16 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,47 @@ +# Defines common services used for development purposes +# set COMPOSE_DOCKER_CLI_BUILD=1 +# set DOCKER_BUILDKIT=1 +version: '3.5' + +x-test-variables: &test-variables + POSTGRES_PASSWORD: 'password' + POSTGRES_USER: 'bob' + POSTGRES_DB: 'db' +services: + dbsha256: + build: ssl + image: approzium_postgres_ssl + command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key + environment: + <<: *test-variables + POSTGRES_INITDB_ARGS: '--auth-host=scram-sha-256' + POSTGRES_HOST_AUTH_METHOD: 'scram-sha-256' + dbmd5: + build: ssl + image: approzium_postgres_ssl + command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key + environment: *test-variables + dbmysqlsha1: + image: mysql:5.7 + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_DATABASE=db + - MYSQL_USER=bob + - MYSQL_PASSWORD=password + vault: + image: "vault:latest" + environment: + - VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 + - VAULT_DEV_ROOT_TOKEN_ID=root + entrypoint: vault server -dev + authenticator: + build: + context: ./ + target: authenticator-dev + environment: + - APPROZIUM_HOST=0.0.0.0 + - APPROZIUM_DISABLE_TLS=true + - VAULT_ADDR=http://vault:8200 + - VAULT_TOKEN=root + depends_on: + - vault diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..b2d6de30 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..dd96f0db --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,23 @@ +website-dev: + yarn install + yarn start + +website-build: + yarn install + yarn build + +# this target is meant to run only in the Netlify docs environment +# since we cannot use `sudo` there, we cannot `sudo apt-get install libpq-dev`, +# and thus we cannot install `psycopg2`. Thus, we remove it from the package dependencies +# before we attempt to generate the documentation. +# the rest of the target installs and runs sphinx, and copies its output to the Gatsby static folder +python-docs: + pip3 install poetry + (cd ../sdk/python/ && sed -i '/psycopg2/d' pyproject.toml) || true + (cd ../sdk/python/ && rm poetry.lock ) || true + (cd ../sdk/python/ && poetry install) || true + (cd ../sdk/python/ && poetry add psycopg2-binary) || true + (cd ../sdk/python/ && poetry add sphinx) || true + cd ../sdk/python/ && poetry run make -C docs/ html + mkdir -p static/api + cp -r ../sdk/python/docs/build/html static/api/python diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..a6c441a8 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,24 @@ +# Approzium Docs +This is the code for [approzium.org](https://approzium.org) which documents the [Approzium](https://github.com/cyralinc/approzium) project. + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. diff --git a/docs/babel.config.js b/docs/babel.config.js new file mode 100644 index 00000000..e00595da --- /dev/null +++ b/docs/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/docs/architecture.mdx b/docs/docs/architecture.mdx new file mode 100644 index 00000000..1870af0b --- /dev/null +++ b/docs/docs/architecture.mdx @@ -0,0 +1,15 @@ +--- +title: Architecture +--- + +import Image from '@theme/IdealImage'; + +The Approzium platform consists of a number of different components: + +* **service** - Cloud service/app that needs access to a database. It is running on a platform that provides cloud IAM services. +* **database** - the database that the service wants to connect to. +* **IAM Credentials Manager** - IAM service provided by the cloud platform the service is using. It handles requests such as verifying the service's identity. In AWS, this is the [STS](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html). +* **authenticator** - Approzium service that interfaces with the SDK and with the secrets manager. This service verifies the service's identity, retrieves the credentials from the secrets manager, and calculates the authentication challenge response. + +Here is the connection sequence for Approzium: + diff --git a/docs/docs/compatibility.mdx b/docs/docs/compatibility.mdx new file mode 100644 index 00000000..40ceb181 --- /dev/null +++ b/docs/docs/compatibility.mdx @@ -0,0 +1,15 @@ +--- +title: Compatibility +--- + +## Client Libraries +- Python + - psycopg2 + - asyncpg + - MySQL Connector +- Go + - lib/pq (coming soon!) + +## Secrets Managers +- Vault +- AWS Secrets Manager (coming soon!) diff --git a/docs/docs/configuration.mdx b/docs/docs/configuration.mdx new file mode 100644 index 00000000..b6567296 --- /dev/null +++ b/docs/docs/configuration.mdx @@ -0,0 +1,35 @@ +--- +title: Configuration +--- + +| Name, shorthand | Environment variable | Default | Description | +|--------------------|----------------------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| --host | APPROZIUM_HOST | 127.0.0.1 | | +| --httpport | APPROZIUM_HTTP_PORT | 6000 | Port for HTTP(S) API endpoints. | +| --grpcport | APPROZIUM_GRPC_PORT | 6001 | Port for authenticator endpoint for clients. | +| --disabletls | APPROZIUM_DISABLE_TLS | false | When false, Approzium comes up as an `"https"` server. When `"true"` disables TLS, and plain "http" is used. Setting to `"true"` means the Approzium authentication server will send database connection information in plain text, making it vulnerable to [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). **Do not set to `"true"` in production environments.** | +| --tlscertpath | APPROZIUM_PATH_TO_TLS_CERT | | The path to the TLS certificate the Approzium authentication server has been issued to prove its identity. Curious about how to generate a valid cert? See [this walkthrough](https://itnext.io/practical-guide-to-securing-grpc-connections-with-go-and-tls-part-1-f63058e9d6d1). This certificate would correspond to the `service.pem` generated in the walkthrough. However, ideally this would not be a certificate issued by your own [Certificate Authority (CA)](https://en.wikipedia.org/wiki/Certificate_authority), and instead it might be issued by your company's internal CA and/or a widely recognized one. However, even a self-created CA is better than none. | +| --tlskeypath | APPROZIUM_PATH_TO_TLS_KEY | | The path to the TLS key the Approzium authentication server can use to prove its identity. In the above walkthrough, this would correspond to the `service.key`. | +| --loglevel | APPROZIUM_LOG_LEVEL | info | Supported selections are "trace", "debug", "info", "warn", "error", "fatal", and "panic". Upper case may be used. | +| --logformat | APPROZIUM_LOG_FORMAT | text | Also supports "json". | +| --lograw | APPROZIUM_LOG_RAW | false | Approzium's logs mask sensitive data. Setting to "true" activates raw logs, so no sensitive values will be masked. For example, if set to "true", the AWS signed_get_caller_identity string will be fully included in logs, presenting an opportunity for a viewer to impersonate another. Should only be set to "true" in environments where logs are carefully guarded. | +| --vaulttokenpath | APPROZIUM_VAULT_TOKEN_PATH | | Optional, if set it will cause the latest Vault token to always be pulled from the given file. | +| --config | APPROZIUM_CONFIG_FILE_PATH | | Optional, set it to path containing a YAML config file called `approzium.config.yml` | + +Approzium uses the following precedence order. Each item takes precedence over the item below it: + + - command line flags + - environment variables + - config file + - defaults + +# Approzium Vault Backend + +Approzium supports Vault for storing database credentials. To use Vault, at a minimum, the `VAULT_ADDR` +must be set. Either the `VAULT_TOKEN` or `APPROZIUM_VAULT_TOKEN_PATH` must be set, with the `VAULT_TOKEN` +taking precedence. We recommend using the `APPROZIUM_VAULT_TOKEN_PATH` with the Vault agent, as described +[here](https://learn.hashicorp.com/vault/identity-access-management/vault-agent-aws), because that approach +will allow the Vault token to be refreshed by the Vault agent, rather than eventually expiring. + +Additional Vault configuration is supported, as described +[here](https://www.vaultproject.io/docs/commands#environment-variables). diff --git a/docs/docs/examples.mdx b/docs/docs/examples.mdx new file mode 100644 index 00000000..4accd132 --- /dev/null +++ b/docs/docs/examples.mdx @@ -0,0 +1,98 @@ +--- +title: Examples +--- + +## Python Examples + +### Postgres Drivers + +#### Psycopg2 + +```py title="sdk/python/examples/psycopg2_connect.py" +import approzium +from approzium.psycopg2 import connect +from approzium.psycopg2.pool import ThreadedConnectionPool + +auth = approzium.AuthClient("authenticator:6001", disable_tls=True) +approzium.default_auth_client = auth +dsn = "host=dbmd5 dbname=db user=bob" +conn = connect(dsn) +print("Connection Established") + +conns = ThreadedConnectionPool(1, 5, dsn) +conn = conns.getconn() +print("Connection Pool Established") +``` + +#### Asyncpg + +```py title="sdk/python/examples/asyncpg_connect.py" +import asyncio + +from approzium import Authenticator +from approzium.asyncpg import connect +from approzium.asyncpg.pool import create_pool + +auth = Authenticator("authenticator:6001", disable_tls=True) + + +async def run(): + conn = await connect(user="bob", database="db", host="host", authenticator=auth) + print("Connection Established!") + await conn.fetch("""SELECT 1""") + await conn.close() + + pool = await create_pool(user="bob", database="db", host="host", authenticator=auth) + print("Connection Established!") + async with pool.acquire() as conn: + await conn.fetch("""SELECT 1""") + + +loop = asyncio.get_event_loop() +loop.run_until_complete(run()) +``` + +### MySQL Drivers + +#### MySQL Connector + +```py title="sdk/python/examples/mysql_connector_connect.py" +import approzium +from approzium.mysql.connector import connect +from approzium.mysql.connector.pooling import MySQLConnectionPool + +auth = approzium.AuthClient("authenticator:6001", disable_tls=True) +conn = connect(user="bob", authenticator=auth, host="dbmysql", use_pure=True) +print("Connection Established") + +cur = conn.cursor() +cur.execute("SELECT 1") +result = next(cur) +print(result) + +cnxpool = MySQLConnectionPool( + pool_name="mypool", pool_size=3, user="bob", host="dbmysql", authenticator=auth +) +print("Connection Pool Established") +conn = cnxpool.get_connection() +cur = conn.cursor() +cur.execute("SELECT 1") +print(result) +``` + +## Using TLS + +```py title="sdk/python/examples/mysql_connector_connect.py" +import approzium +from approzium.mysql.connector import connect +from approzium.mysql.connector.pooling import MySQLConnectionPool + +auth = approzium.AuthClient( + "authenticator:6001", + tls_config=approzium.TLSConfig( + trusted_certs=environ.get("TEST_CERT_DIR") + "/approzium.pem", + client_cert=environ.get("TEST_CERT_DIR") + "/client.pem", + client_key=environ.get("TEST_CERT_DIR") + "/client.key", + ), +) +``` diff --git a/docs/docs/images/architecture-diagram.png b/docs/docs/images/architecture-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..bce78b5c4e49a42f228644264d04e430f7a80219 GIT binary patch literal 142844 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�}k(uYx!8vRvgsTiHzLO|D|t(WQi z6O<&5oiu!1*^Hz1(hUb4MXcLTmPC$_c9#v-i}Hg@C~hMr%mIV@g=B~x7$b`cQas9- zp`3AsfMWrg!Mq01l+;HWPv-*!nF=g4E9|c#_k2*iJ5)@$mYaoLhNL-AT5Q^;h&-8? zid2RfRGIWCj477Mt20o@&Vji`cHGrzjV-X{vWhW*OTs(gaE@U?fCT$1@#}nKeIQ!t zrku)ThR|G^#ZQ5HRyL*?^If7N4A=g?P{Lt20I0+tyU&Z!caR+PU`RKRi*g%elB|># z!(^{~{fKa!UzzfQa4+O86bky@&ohR~>wDo0h0tT@x^5=94MwIT9nC2Cc4x6CGoMP` z-x4I?Dt#8)gUlF9!AQqJ4NLxo`UgdFn_BJSTue*oNGq-HZEy5Ce(~0~Or|&ATTB;y zDUn({UkS;nyrJNr_VMskf7Cq9$EPMM#5U8b&Nhs!G1G9Fy3IYCQ$I4)mNDn{+@5EW zi~xZ&xExk-GQI8IF%ticNTAySPKcP{*O9w3o);Be$0^o6=T4JwP}dJvWK}?%mDSmBgJ}>5Cid zjH0Vyd4gEsdyr$S0ao$LiLlCb9OKK_dpE`TWq!BDuNquNr-wP_Tx?8Yl89juQonid zCkVUyrr$Np?iLV)hINjxWUke5sbTlt`50}5-?J;O$G}xOd?a6YVS{L)TD&J2;B~Kz zqaw$vO_QQbtCk89VwL|$hN{5vDrh@(PlK*nQAweTpyZbH=#E`daVLSRZb0RSG1`K@2TR}ME=%z*BwXk@$Ulwx5-Q;XwW0FvR(C`>7BIf--WYU>)`>-l3 zrt;Ye!E+XeU3C^t*Cs@&NVF4^OsRM6tYd`_Sk#Kwo6jGh;17o+8{nb1uz!CyWzM7M zga2x*EUQ&!s;a7LRcbSR(vNR!@+ytR*RIW85<3nh&%`7m92Zn(9rNWtcEe{KXdOrB z+3ww=QI>cmB=1l*@~{Ab)I-n)_R=I~e7-c@ckq32y3SWuMM0Y#OJcy^f{9izN)Iy$ z8tD2eRTAqD34C2jgm|mkr0^*2O^p{9OgkT7A2V4q?0p>nDWo6p827}EO-CvSL-ze# zzc!npjb6Lz(zipW#VtA0Yku~H{zNuA9Uk_}oT-b?;;yf1Kevsao)M@$wVxvF&$lBN z<!9vP0Gc^uyvaYWf(&}9dOOa&l#SYF0 z>7z1csp4~A9y#u0bG^Mdb#Dnf!iUWG3xz&)yq5l1UH#^y&o=9JJ!rLPnx-Vcxy^Lh z&M#S?S2UR0W>EIoz}@hA(dh8cu5X7sZ!ao7KD%~uiGJYTX%%uYlMqeAog9ZtV5h|p z+QoJDI__J2vnnqn_}m#eV&H%ScV{Q~weD$Y*?Q#}FYn~^$r&E)L})_zt_hfx|N1ynH$cK4(y80hPFSz znT}(wD-TQ4M=|%RbGQ|CDQY~T@DOxHxsi4`%eU|I z9gl*(@EB&uxUN(bpKX*RqtW`CiNkeII_#p&ec^9ptUYk0xjU-I(=XDub6G$k`Lb4X z_Ijn8gKb>X^dh}n%_J>+g@uYlFYU+HS0(fC=`8~i-mO}Y)ZPug?|fn>t9c+?uZ%Bv z4`vEBx>(TNI993~G)?Mvhrck8Q$4Z{BoW|`@@`i~2mb+&{-LNbm`qqzJ^T~klY6jv zSeAAk+_=*bi-~p-GI@F!U$$onabi!OpaeG-mWX7Zy*~GIXw}lW7Rzg=GN_82FYR+f z4Xk{1ECgYb)Z$>sa6XVaup@X5fn<=_I^kcR*lp56Qu-pQdnHrtPij9zO+G1k<~V)w z)72y;%`O|87axW4BadywfR|bTnW6Z|#|C!8XC|bz&I?PJ(T){NBiyDv{>a~+ErEU>{z}Jw=GSIM4`&Pc5U}- z7{h%NQ=LcKGioPl2X4^X==Ly}>WVf*VG7yU}*!%Q0b;)XjHRtp=;>42X$RxAF)Bvk?~w9!6Q_4$(sskgm! z1e$klo-oFIQLY<%0TbgFSvxXZe4G4lv`Z!bUGkx`u4 zUC>rUt~C(^%$F1mn`u4cmYh&6rV`MH9|>Z0@JuNvLX~_!5QRBWMTVbviv3u!?G27- zKS!BWrsCx@q0{@axEhYnmO73W2ft)Kf!Rzyp0VoNqXP32cv`73{y5hF9^Khlxha2^ zd@TD(k@*!ov~D{? zHr$Va>cO-C)M2e*f#_ZGVplu$D!^_jSJ80QNv%u${sQV+Bn@+ofMAX`HEkovah4^H zJmD=wLqtJihQvn(BnaP4ve8@%bxl2P62IngTCOW1Ud(J!ov*h>4jUzZZhFk z%3ZK=#!(2+_)4)Y+Gj@%YHBx?*&NE*gjJ2Zpvv3xik&zx(~qNpb64H*=A+fhmj8TB zL1ECrz$@Kw$DWV1_0|sRb?NpYBiUI@HuokM+ zN+jI4vz45x0-V>$>-Hbb^!zK8vjtrGw(~bV@!lFPccUV6_c~tc#JwtaCu5_%6??g4 z5z-i3(mJJI81=Eb-X%k&US~9K@h$?ZWv(jWg9m@@0$gX^0m))74W{fYWMX2WH$i-) z_TedkyySXn4MAP4Ub(UDK&5y?}EU8u4K5IwD9wTY|iJC^xbRLf5uroMaK4)w z`J6fX)sUG6fhzB9u%1jTesF9EkxN+V_RQQSb>ok$n&Hkv`5hj zPJgWs5qW)Xukb{={a1DMC(%8g&2JLoX$Fb;-xU#J!x%2G$X;b(Sk^T=T54-fkF5J| z_-n6;23}s`eEmaCXP(EBt9WPaS~=Q_ zTihSq%UX(v$15zJu!L};EjgwrGTDvWer~*E>+Z2aB{Hq^QD-uJ;QL>F`xn>HJfGjh z8+Mlc1XCbCvVV_btU-W}A2G1HNqsBlOgweELpbgm#cb|N3N)MRsbPl}+)j4ItOAy| zMy8Kl*AuC5Nyf{0Sy4oFvlu^7O+T-uq|eJrFTPc*zIy6o|X@qWLunke)BWXgY6^t^K?~lFzw+%r8#8`0mZqNYAsU%zAPH!R5ub=YHTTlH|l+U!t+@wP(B2%Y)#I_1R z-iruuyfu>WHL}%h_YY&E4eyFhlYF}|Yxx2!-eU>2j@yuXmJ)^hf869DxOLx!KS3&i zUjqPYBUjy=PC>mpDA05C7MT3|e5oxU6yW%(0kGcbOPNd{X!#feT5mq!2Yp7u={nt+ zN?F?dnc~9>ZbO-^7F*Vf^@13+DQg!s;HH4j*giAP0n0NN=1V2CX*%Bmu0Uy~v zGS@|PE__6qLL2iKoGGgJCa5GUU?2)vfOrcy=LJ&0m*vbd=(Xy)&5JdKth@n zv7qq9#YOB2X(7OknlRFHMUDqLD#d!fE~gWQRzgNZb_NFN>HsyK*=|!F5&krdOJ+95 zXr|*WxgejLJMpGvrDC{yt+;3cXO-JOJ*0vR@7@5f=Y@H7F13IRV!q?CysGAbz$9 z*XJZ;H&juDG1>ZI1TIg$x!qh!fJ+sQ!%FOG@hROqTuR z9rP7Gyt-l5X+el$H42G!m~~pkk@MAm>m=|DcG%go-hCp?z{9z_t^eJHo0S=qi_9Q~ z>2oi(6d6LN+-(zLnN7d$T+08=>1w7ONRz~gV%Gm!H99ud4Mx&D2N&t-bjpQ-;q)5M z%gV}D@12ktk9rR0Vr)rmB`1?}fvSeIk7v7sC5Eyrj&TtYhEEorz`&ylz3-3bGeCDf zTJ1dqRRNt~@Cx}+)5xL>`02!CG*#~XSf)0j8A9nb1cQ)4MS!QBv+hdg@% zpL^E82B!+wkMA)m(y;yWdaw6I9Jd{_dmO0ku-KTYD7fHYv78rVp`KCK=<`dJ@=&!f zIQv8jV>~+o&R)>J@u7Qy*>0TE>X}Yp@!yQ@25BOi+;CZvh@qDon6Hrx*$N=w=t`H4 z(F5uv`63@&T=XW!K4~o1BrtA&O_sctD_CxBV%hhaBKe{)&y27Alc3roWg3oBw3$%` zBU@h-UXF-Q&AI4DLGKxjU>@GBbEsXIA z-Tk9tIzu0SkZr%7XX;-UED$a;>|K$F+ZVIXH!M5=-r7{2KN+a9@(#!M-}MaFaFmJ0U<@P*(5G)=f#(B^rt3mZhhQ+UDiv@@8(d+^fJAN48cAi$=0n zTfx*Kc=U-Xyyz6m&_k_#W*?sit}5%GTx7p8>sF^<-@xFtsHk_9aWslaZ(mFhMAS^n+<+K!oW;Gw>zWM$L$(Y5-^1Si@gAOvzIU?ZN^A`9LiE~sfzE_ zwCsREwdhqKd7nWeW;=4P;>6g@WL8@v&l<%(*s?H*)bZuFb#vVx2Ol7;Qv>&k`QN{5 zXdHNGV!Vk=n`vscm6NY31J|u+sp8p-uQ#e-xL=YQB-nL7^JMf1j$D)U5*Va4~o z848h^uc51f-jAxq3%?{xQuU%}lOk}EqSI}!2-5bkGcEZ0>Fs}6N_7`%=@Hs7-75XX zO9JYpG{Gaxy2Y26?cDT!4x8&3#%l3L>4<15PjwyX7Cnwughizob85t>yK~r5b zIl&?I4<5>fWNHwdEd@g|j*9aex03iL@-i+XK3b|U2A{fmjjZdLU}WoxSnUUU+uhl3 zn4%71+EcGEo>`x{v&A)Z^p16ogR}yq4ZhfuKZ>zZS2u$z@K;s$r?e8-W%|{)b$;ON~iQEz8wsy?V4i zqGwC_`SJSuf#qVlzv`1e8Cy^dA=TESI#t%9YBAeHx(NDX!LCK!V>W041_$)k65|cj zT~IOA%)iAY|Hsp*5W%j8nVvrqr=8Y_R`b-0_sxhSBOh28(_=tvu?Dn!cu(ecit}tk z31_HeT{LB@K}h$HJ_Ns!;|q?tmzLbmn;-mRN0maPEAL#CIg)HLWSHIFi#h15BFNMn(ldYfHJbUuDH5-_S2lZy^$`2(SaUBl13XQ$f9Mao$f)*WJns(p z&bkViFW`pxDY#u-r1*_*vUs7UVICU-5eo>HqkbpDZ5JX{b!uFJ z9Aov1bNJWtA0nn|pl&Kd%sv_~w^ku7H@F?caouHSF#}zoBU=&x_VzSSFtJ!(hLB6{ z(~tLqf!`p%s^|ZRVlU!(3~g}Nn%^O_-o>Ye*9!WduMd15_DVhzkLz-XH4!FdgRg$# zrPuOPEUm58^2tAsU=-Gf&r@~JX*xerNJEyGC!9O|TkpnK=RmDWwogkgVE zus<2+O#ZFyKjmSEB6t){Lh9+MBk$psSi0n!H^6U;n(InT36iF3;s;+nunNo2@2EWM zsGmO3ZxkvM!9vel*L#)vw>bGvcYEFvA$TzbJci{?DiX)O!&5$E1QYEgE^5fgRThJZbbVzgHtt%8+?@ z!2Ka(hIdDrG&8lc$l`OXCv(fYJmxlu`q96>;V-4B%_0AK7snyy^T(4NhW^`K8az%*!S3hp9{odb&@HPx##WXrDi+T6qMx;+ zP^0hN$`=M*FFXHy7*zz-OFra`mn{;58FzAAN3lrDGfozmvHXvvHvb_<9$WB{LS{$d zMqNQy83OdO0+${tC2IZr%uZdbc-+>pz2VeQqxA*;Mw2U>lRECmX5lx)8I%FUp*451 zvn!jv8cOI+hZir^0oR&MY2dXaIv``A#X&{f0YY!n1KlA+e5^pRIq4RJ?9P5GR>p(Bjs6Fzu}JM}Fu3?cGw|<6fC?ED*cH zVV3?bi+Goplp2l!Qk+ZVKC0<>;Ju-Z<%819?z`Ov@2j(mn+TnSGRU2DXI(ZXxca3d znv|h-@9*LaVaFjA++nl=>f|um`C_}9@6gOCuQ_iBTu(mDX{@o){4Qc~Co-C+iA|&< zqgk)+*80SHtC!=ojEu}NC#Y@sOF{nc(-oBE7I>11Damsr&$_}j6s+pjk-NhZY8g`6 z+&SnO%+$&3f!Se$ZE$)YO{a2hZ(DnDpJ-*%q#!IN{|@5yGHKn4{nu#nuSGB3N04j( zSlX$nk*Zm~lLeg1u2f3GZ@}=qC~>5Cv2mlGHsYkh5 zCGzQWPI>-B4xd1Ommb$m>APp>r2V#2*+bm_&`_zL?!j!@*ZYl>VN`9k3w%@3x(*#4 zm2W>G?&=BI75gsUkVMh@FuOHQ@8KW1ip087d&gSkV#7yN^CE}fy3DhkVz5Fo{Fu7u zv4uvNp1ywB7VgGx94gBi@I}qG4?#4ifBWh4;hDo~cheaT9;8qK6V)drvh z2*zks^EI*V8p|>Fs;(8B6zkk4dig1~x23zUxh71jfmu34YJ+FBM#zhNUekP~ZW| zLKFNl{tODb6wdbLwK_99?}UZTY@UIE z&)uRPg4%cJ`J+LYX~~ZQr-@h-I5^Sga8Gc!Y9=X)EeC+b<^U(X-?k{_VweqWWN_RN zQ*g+g-NS`xJ5+@qhrog|{B96fu+7(v6}7NHDm&DHncRAz2i5`rZ0$B+UcIfhmpbW^Ns4Z{;rYGU9E#TD&*z8G&1}exk(!v>67K#oHw>VvI zVU)};dp76-6^tea;F^iigTe~DWM4fn6Mgj literal 0 HcmV?d00001 diff --git a/docs/docs/images/overview-diagram.png b/docs/docs/images/overview-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd5b9267a1a1541106694635f295a548957d134 GIT binary patch literal 86212 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 literal 0 HcmV?d00001 diff --git a/docs/docs/observability.mdx b/docs/docs/observability.mdx new file mode 100644 index 00000000..ff3a0185 --- /dev/null +++ b/docs/docs/observability.mdx @@ -0,0 +1,83 @@ +--- +title: Observability +--- + +One of Approzium's primary goals is a high level of security-oriented observability. + +## Logging + +Every database authentication request is assigned a `request_id`, which is included in all logs generated by the request. +We recommend you set "`APPROZIUM_LOG_FORMAT=json`" and "`APPROZIUM_LOG_LEVEL=info`" when running Approzium. This will result +in the following: + +- Logs will be outputted in a JSON format that's easily consumable by log viewing tools such as the ELK stack and DataDog. +- The `request_id` field may easily be searched for a request's full lifecycle. +- If the caller's identity for the `request_id` was confirmed, it will be logged. +- Any malicious-looking activity that occurred in the request will be logged at the `WARN` level. + +## Metrics + +Metrics are exposed at the `/v1/metrics/prometheus` endpoint. + +### Performance-Centric Metrics + +These metrics help understand performance. The number of requests, responses, and error responses help describe the load +Approzium is under. Total request milliseconds is an end-to-end metric regarding how long Approzium handles a request. +The other request milliseconds are for helping to understand where Approzium's request time is being spent. We do execute +some requests in parallel to minimize request time, so the sum of sub-request time may exceed total request time. + +The AWS request being executed is the `get_caller_identity` call. The password request is where we call your configured +back-end (HashiCorp Vault, for example) to retrieve passwords that will be used to build database connections. + +Total requests and total error responses can be considered significant to security because if an attacker is attempting +to [DOS](https://en.wikipedia.org/wiki/Denial-of-service_attack) or [fuzz](https://owasp.org/www-community/Fuzzing) +Approzium, these will rise at an unexpectedly high level. + +| METRIC | IS SECURITY RELATED | TYPE | DESCRIPTION | +|-------------------------------------------------|---------------------|---------|-----------------------------------------------------------------------------------------| +| approzium_total_requests | yes | counter | Total number of requests | +| approzium_total_responses | no | counter | Total number of responses | +| approzium_total_error_responses | yes | counter | Total number of error responses | +| approzium_total_request_milliseconds | no | gauge | Total request milliseconds | +| approzium_total_aws_request_milliseconds | no | gauge | Total AWS request milliseconds | +| approzium_total_password_request_milliseconds | no | gauge | Total password retrieval milliseconds | + +### Security-Centric Metrics + +These metrics are focused on understanding whether your system may be under attack. + +When the Approzium SDK attempts to gain a database connection, it must send the Approzium server a few things: + +1. The identity it claims to be. This is sent in advance so Approzium can minimize request time by getting database creds + while simultaneously confirming the caller's identity. It will only return the connection if they match. +2. Proof of its actual identity. For example, for AWS, a signed get caller identity request is sent, which includes a + cryptographically signed string that AWS can use to confirm the caller's identity. +3. The database to which it wants access. The database requested is fully at the caller's discretion, but they must have + been granted access in advance to receive it. + +So, when an attacker begins trying to get something they shouldn't, the following metrics will be incremented. + +| METRIC | IS SECURITY RELATED | TYPE | DESCRIPTION | +|-------------------------------------------------|---------------------|---------|-----------------------------------------------------------------------------------------| +| approzium_total_identity_matching_attempts | maybe | counter | Total checks of whether the identity a caller claims matches their actual identity | +| approzium_total_identity_matching_failures | yes | counter | Total calls where caller claimed an identity that was not their actual identity | +| approzium_total_identity_verification_attempts | maybe | counter | Total attempts to verify caller identity | +| approzium_total_identity_verification_failures | yes | counter | Total failures to verify caller identity | +| approzium_total_password_retrieval_attempts | maybe | counter | The number of times a caller has requested a password from the database to authenticate | +| approzium_total_password_retrieval_failures | yes | counter | The number of times a caller has failed to retrieve a password for any reason | +| approzium_total_password_retrieval_unauthorized | yes | counter | The number of times a caller has been unauthorized to retrieve a password | + +If the caller is attempting to get around **1**, claiming to be someone they're not, `approzium_total_identity_matching_failures` +will rise. We also provide `approzium_total_identity_matching_attempts` in case you prefer to observe this as a ratio. + +If the caller is attempting to get around **2**, providing invalid proof of their identity, `approzium_total_identity_verification_failures` +will rise. We also provide `approzium_total_identity_verification_attempts` in case you prefer to observe this as a ratio. + +If the caller is attempting to get around **3**, requesting access to a database they shouldn't have, `approzium_total_password_retrieval_unauthorized` +will rise. However, there's a potential second vector here - they could be simply combing to see whether _values exist_ for other +databases. That's why we also provide `approzium_total_password_retrieval_failures`, which will rise in such a case. These both +also offer `approzium_total_password_retrieval_attempts` if a ratio is preferred. + +## Tracing + +Coming soon! diff --git a/docs/docs/overview.md b/docs/docs/overview.md new file mode 100644 index 00000000..6a520cf0 --- /dev/null +++ b/docs/docs/overview.md @@ -0,0 +1,57 @@ +--- +title: Overview +--- + +import Image from '@theme/IdealImage'; + +## Introduction +Approzium enables developers to improve the observability and security of their applications. It allows applications to connect to databases without requiring access to credentials, and emits logs, metrics and traces with enriched information about their runtime execution context. It is built as a lightweight open source library with multi-language and multi-cloud support. + +Approzium eliminates blind spots in the diagnosis and tracing of complex performance problems within autoscaled microservices running on modern orchestration frameworks such as Kubernetes and AWS ECS (Elastic Container Service). For example, all instances of an autoscaled microservice look alike from a database’s perspective. This makes it harder to attribute performance issues resulting from misbehaving queries, buggy service code and faulty cloud VMs to a specific microservice instance. + +By providing richer execution context about each microservice instance, such as the service’s IAM role info, the EC2 instance id and hostname where it’s running, or its container/task id in dockerized environments, Approzium allows DevOps teams to quickly trace and resolve performance issues. This context is added to the existing logs, metrics and traces already being emitted by the microservice. + +Additionally, Approzium addresses common security vulnerabilities in how applications typically connect to a database. For example, here's how you might typically connect to your database currently: + +```python +from psycopg2 import connect + +conn = connect("host=1.2.3.4 user=user1 password=verySecurePassword") +``` + +Whether database credentials are stored in the application code itself (as in this example), or in a secrets manager such as Hashicorp Vault, allowing applications direct access to credentials exposes them to leaks through inadvertent application logging, application compromise, or theft of secrets manager API keys. + +Approzium solves this problem by leveraging the cloud providers’ security infrastructure to authenticate the applications using IAM roles, instead, thus abstracting database credentials away from them. Here's what the same code would look like with Approzium 😎 + +```python +import approzium +from approzium.psycopg2 import connect + +approzium.default_auth_client = approzium.AuthClient('authenticator:6001') +conn = connect("host=1.2.3.4 user=user1") # Look ma, no password! +``` + +With the _password_ attribute removed from the `connect()` API, applications no longer need to know the actual database credentials in order to connect to them while administrators can still retain control over which applications are allowed access through the use of IAM roles. + +Approzium integrates with popular secrets managers such as Hashicorp Vault and AWS Secrets Manager for the storage of database credentials, and uses OpenTelemetry to make it easy to integrate with a wide variety of observability products, such as Prometheus/Grafana, ELK, Datadog and New Relic. + +Approzium is developed by the engineering team at Cyral and is available under the Apache 2.0 license, free for anyone to use and develop. + +## Overview +Approzium comprises two components that are deployed independently -- an SDK that runs as part of the application code, and a standalone service called the Authenticator with which the SDK interacts on behalf of the application. A single Authenticator instance can support multiple applications, which may be set up optionally as an auto scaling group for load balancing purposes. + + + +Together, the SDK and Authenticator provide observability and security benefits to the application. The SDK has the ability to query infrastructure metadata services native to the various cloud platforms, and to orchestration frameworks such as Kubernetes to generate rich execution time context about the application. SDK APIs make it easy for developers to enrich their existing logs, metrics and traces with the context. + +From a security perspective, the SDK also generates an application fingerprint that serves as its identity. While the actual mechanism depends on the cloud platform, the fingerprinting is primarily based on using an IAM role assigned to the application to generate a cryptographically verifiable signature for it. On AWS, for instance, Approzium SDK generates a signed GetCallerIdentity API request by requesting temporary credentials from the Security Token Service (STS). The signed request is sent to the Authenticator, which verifies its validity and authenticity by presenting it to STS. + +The Authenticator service, in addition to authenticating applications, also computes responses to database challenges needed by the applications in order to connect to the databases. It is built with extensibility in mind to support multiple databases and their respective authentication methods. It delegates all credentials storage and management to popular secrets managers such as Hashicorp Vault and AWS Secrets Manager. By doing so, it ends up being a simple stateless service making it easy to handle failures and scale using auto scaling groups, Kubernetes daemon sets and ECS tasks. + +## Next Steps +- You can get started with Approzium [here](quickstart). +- Learn how it works by checking out the [architecture](architecture). +- Visit our [GitHub](https://github.com/cyralinc/approzium) to download and play with it. PRs welcome! + +We hope you enjoy it! 🤗 + diff --git a/docs/docs/quickstart.mdx b/docs/docs/quickstart.mdx new file mode 100644 index 00000000..cd0b20b4 --- /dev/null +++ b/docs/docs/quickstart.mdx @@ -0,0 +1,73 @@ +--- +title: Quickstart +--- + +This guide will show you how to: +- Deploy the Authenticator. +- Store database credentials in Vault to be retrieved by the Authenticator. +- Connect to a Postgres database through the Approzium Python SDK. + +## Deploying the Authenticator +Get the Authenticator binary [here](https://github.com/approzium/approzium/tree/develop/authenticator), then run it with +the environment variables `VAULT_ADDR` and `VAULT_TOKEN` set. These are example values, in real life we'd expect Vault to +be run elsewhere. +```shell +export VAULT_ADDR=http://localhost:8200 +export VAULT_TOKEN=root +./authenticator +``` + +For availability, we recommend running the Authenticator in a long-running environment (such as an EC2 instance) rather +than in a short-lived environment (like in AWS Lambda). + +### Storing Credentials in Vault +The Authenticator expects credentials for a single database user as a secret stored against the database user as the key. +The secret contains the database password and a set of IAM roles allowed to access the credentials in the following structure. +```shell +cat dbuser1-creds.json +{ + "dbuser1": { + "password": "asdfghjkl", + "iam_arns": [ + "arn:aws:iam::accountid:role/rolename1", + "arn:aws:iam::accountid:role/rolename2" + ] + } +} +``` + +For database access to be granted to a caller, the caller's exact `iam_arn` must be listed, _unless_ the caller has assumed a role. +For assumed roles, either the role ARN or the assumed role ARN may be used to grant access. + +Enable Vault KV Version 1 (see [Vault documentation](https://www.vaultproject.io/docs/secrets/kv/kv-v1) for more information). +```shell +vault secrets enable -path=approzium -version=1 kv +``` + +Put the secret at path `approzium/` with your database user as the key. +```shell +vault write approzium/1.2.3.4:5432 @dbuser1-creds.json +``` + +## SDK Usage +Install the SDK in your client. +```shell +pip3 install approzium +``` + +Connect to your database as follows. (Note: TLS should **not** be disabled in production environments, +see [our Python guide](/languages-python) for how to configure them.) +```python +from approzium import AuthClient +from approzium.psycopg2 import connect + +# create an Authenticator client +auth = AuthClient('authenticator:6001', disable_tls=True) + +# connect using Approzium's connect method without providing a password +conn = connect("host=1.2.3.4 user=dbuser1 dbname=mydbhost", authenticator=auth) + +# use the connection as you typically would. very cool! +cur = conn.cursor() +cur.execute('SELECT 1') +``` diff --git a/docs/docs/roadmap.mdx b/docs/docs/roadmap.mdx new file mode 100644 index 00000000..b136a6d6 --- /dev/null +++ b/docs/docs/roadmap.mdx @@ -0,0 +1,25 @@ +--- +title: Roadmap +edit: false +--- + +## Integrations +- Secrets Engines + - AWS Secrets Manager + - Kubernetes Secrets +- Databases + - PG SDKs + - [lib/pq](https://godoc.org/github.com/lib/pq) (Go) + - [asyncpg](https://magicstack.github.io/asyncpg/current/) (Python) **P1** + - [JDBC](https://jdbc.postgresql.org/) (Java) + - MySQL SDKs + - python **P1** +- SDK Features + - tracing **P0** + - OpenTelemetry (OpenTracing) + +## Authenticator +- fluentd/filebeat to push connection request logs to Elastic/Datadog/SIEM **P0** +- publish OpenTelemetry (OpenCensus) metrics **P0** + - connection counter (tags: userID, ip) +- high availability deployment diff --git a/docs/docs/security-model.mdx b/docs/docs/security-model.mdx new file mode 100644 index 00000000..86d68cf6 --- /dev/null +++ b/docs/docs/security-model.mdx @@ -0,0 +1,26 @@ +--- +title: Security Model +--- + +Approzium’s security model aims to **prevent**, **attribute**, and **observe** database credential leaks. Also, as a security-oriented application, all features are secure by default. + +Please note, Approzium is under active development. As such, some of the features discussed are still brewing. However, this Security Model describes our direction and tenants. We appreciate your patience! + +## Prevention +Applications are poor at keeping secrets. An application that’s starting up may log its configuration, including a database username and password, or return it as part of an error response. Many companies use logging solutions that propagate logs in near-real-time, so a leaked password configured to expire in 15 minutes may still be viewed and used in 5 or less. + +Approzium gives **zero trust to the client**. Clients using the Approzium SDK never receive the database password, nor is the password ever in the client’s memory. This makes it impossible for a client to leak database credentials. + +## Attribution +Many applications use the same username and password across multiple instances. This makes it difficult to attribute a particular query to a particular instance. If a data exfiltration is occurring, who is exfiltrating it? + +The Approzium SDK exposes client-side identity information for logging by pulling it directly from the client’s enclosing environment. Server-side, Approzium logs the actual identity of all callers along with request IDs. This makes it possible to tie clients to their local (unverified) identities, clients to the calls they make, and calls to their actual (verified) identities. + +By supporting tracing, this concept of identity can be extended end-to-end. + +## Observation +It’s good to prevent data breaches, but if one is in progress, you need to know so you can intervene. + +Metrics are a forethought with Approzium. Approzium emits normal application metrics, but it also emits metrics on events that may indicate concerning activity. Metrics can be used to view failed authentication attempts, error responses, and claimed identities that don’t match actual identities. + +Exposing this information allows you to alert on suspicious activity. Your database authentication attempts are no longer opaque, they are easily viewable. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js new file mode 100644 index 00000000..c361d2c4 --- /dev/null +++ b/docs/docusaurus.config.js @@ -0,0 +1,56 @@ +module.exports = { + title: 'Approzium', + tagline: 'The tagline of my site', + url: 'https://approzium.com', + baseUrl: '/', + favicon: 'img/apzm-icon.png', + organizationName: 'cyralinc', + projectName: 'approzium', + themeConfig: { + navbar: { + title: 'Approzium', + logo: { + alt: 'Approzium Logo', + src: 'img/apzm-icon.png', + }, + links: [ + { + to: 'docs/', + activeBasePath: 'docs', + label: 'Documentation', + position: 'right', + }, + { + href: 'https://github.com/approzium/approzium', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'light', + copyright: `Copyright © ${new Date().getFullYear()} Cyral, Inc.`, + }, + }, + plugins: [ + '@docusaurus/plugin-ideal-image', + ], + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // It is recommended to set document id as docs home page (`docs/` path). + homePageId: 'overview', + sidebarPath: require.resolve('./sidebars.js'), + // Please change this to your repo. + editUrl: + 'https://github.com/facebook/docusaurus/edit/master/website/', + }, + theme: { + customCss: require.resolve('./src/css/custom.css'), + }, + }, + ], + ], +}; diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..c975ba99 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,44 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "description": "Documentation for the Approzium project", + "version": "2.0.0-rc.41", + "keywords": [ + "approzium", + "documentation", + "help", + "usage", + "docs" + ], + "repository": { + "type": "git", + "url": "https://github.com/cyralinc/approzium.git" + }, + "scripts": { + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy" + }, + "dependencies": { + "@docusaurus/core": "^2.0.0-alpha.58", + "@docusaurus/plugin-ideal-image": "^2.0.0-alpha.39", + "@docusaurus/preset-classic": "^2.0.0-alpha.58", + "clsx": "^1.1.1", + "react": "^16.8.4", + "react-dom": "^16.8.4" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} \ No newline at end of file diff --git a/docs/sidebars.js b/docs/sidebars.js new file mode 100644 index 00000000..2c76a633 --- /dev/null +++ b/docs/sidebars.js @@ -0,0 +1,22 @@ +module.exports = { + someSidebar: [ + 'overview', + 'quickstart', + 'architecture', + 'examples', + 'security-model', + 'configuration', + 'observability', + 'compatibility', + { + 'Client Libraries': [ + { + type: 'link', + label: 'Python', + href: 'https://approzium.readthedocs.io/en/latest/' + }, + ], + }, + 'roadmap', + ], +}; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css new file mode 100644 index 00000000..b65e26d3 --- /dev/null +++ b/docs/src/css/custom.css @@ -0,0 +1,60 @@ +/* stylelint-disable docusaurus/copyright-header */ + +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ + +@import url('https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap'); +:root { + --ifm-color-primary: #3b56a7; + --ifm-color-primary-dark: #354d96; + --ifm-color-primary-darker: #32498e; + --ifm-color-primary-darkest: #293c75; + --ifm-color-primary-light: #415fb8; + --ifm-color-primary-lighter: #4664be; + --ifm-color-primary-lightest: #5f79c7; + --ifm-code-font-size: 95%; + --ifm-font-family-base: 'Titillium Web', sans-serif; + --ifm-footer-background-color: var(--ifm-background-color); +} + +:root[data-theme='dark'] { + --ifm-color-primary: var(--ifm-color-primary-lightest) +} + +html[data-theme='dark'] { + --ifm-background-color: #242526; +} + +.docusaurus-highlight-code-line { + background-color: rgb(72, 77, 91); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +a[href^="https://approzium.readthedocs.io/"]::after { + content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==); + padding-right: 13px; +} + +a { + font-weight: 600; +} + +code { + border: 1px solid var(--ifm-font-color-base); + color: var(--ifm-font-color-base); + border-radius: .2rem; + font-size: .9rem; + padding: .15rem; + margin: .05rem; +} + +.pagination-nav__link { + border-color: var(--ifm-font-color-base); +} \ No newline at end of file diff --git a/docs/src/pages/components/InfoModal/index.js b/docs/src/pages/components/InfoModal/index.js new file mode 100644 index 00000000..d2f87ba8 --- /dev/null +++ b/docs/src/pages/components/InfoModal/index.js @@ -0,0 +1,78 @@ +import React, { useState, useEffect } from 'react' +import clsx from 'clsx' +import CodeBlock from '@theme/CodeBlock' +import styles from './styles.module.css' + + +const info = { + 'observability': { + description: 'Approzium provides rich execution context derived from cloud infrastructure metadata services, thus eliminating blind spots in the diagnosis and tracing of complex performance problems within autoscaled microservice environments.', + codeHighlight: '{15-22}', + }, + 'security': { + description: 'Approzium enables applications to connect to databases without requiring access to credentials, thus preventing leaks through inadvertent application logging, application compromise, or theft of secrets manager API keys.', + codeHighlight: '{7-9}', + } +} + +const codeSample = `from approzium import AuthClient +from approzium.psycopg2 import connect + +# create an Authenticator client +auth = AuthClient('authenticator:6001') + +# connect using Approzium's connect method without a password +conn = connect("host=1.2.3.4 user=dbuser1 dbname=mydbhost", + authenticator=auth) + +# use the connection as you typically would. very cool! +cur = conn.cursor() +cur.execute('SELECT 1') + +# attribute your database connections to a unique identity +auth.attribution_info() +# { +# 'authenticator_address': 'localhost:6001', +# 'iam_arn': '', +# 'authenticated': true, +# 'num_connections': 1, +# } +` + +function InfoModal() { + const [selectedCategory, setSelectedCategory] = useState('observability') + + const selectObservability = () => setSelectedCategory('observability') + const selectSecurity = () => setSelectedCategory('security') + + const selectedInfo = info[selectedCategory] + + return ( +
+
+
+ + +
+

{selectedInfo.description}

+
+ + {codeSample} + +
+ ) +} + +export default InfoModal; \ No newline at end of file diff --git a/docs/src/pages/components/InfoModal/styles.module.css b/docs/src/pages/components/InfoModal/styles.module.css new file mode 100644 index 00000000..6616cb13 --- /dev/null +++ b/docs/src/pages/components/InfoModal/styles.module.css @@ -0,0 +1,83 @@ +.container { + display: flex; + justify-content: center; + margin: 1rem; +} + +.textModal { + display: flex; + flex-direction: column; + border: solid 1px var(--ifm-font-color-base); + box-shadow: 2px 2.5px 0px var(--ifm-font-color-base); + margin-right: 2rem; +} + +.selectorContainer { + display: flex; +} + +.selector { + background-color: transparent; + border: none; + width: 100%; + font-family: var(--ifm-font-family-base); + font-weight: 600; + font-size: 1.5rem; + color: var(--ifm-font-color-base); + padding: 1rem 0px; +} + +.selector:focus { + outline: none; + box-shadow: none; +} + +.selector:hover { + font-weight: 600; +} + +.leftSelector { + border-right: solid 1px var(--ifm-font-color-base); +} + +.notSelected { + border-bottom: solid 1px var(--ifm-font-color-base); + font-weight: 500; +} + +.description { + font-family: var(--ifm-font-family-base); + font-size: 1.25rem; + max-width: 40rem; + padding: 2rem; +} + +@media screen and (max-width: 966px) { + .container { + flex-direction: column; + padding: 1.5rem; + } + .textModal { + margin: 0; + margin-bottom: 1.5rem; + } +} + +@media screen and (max-width: 414px) { + .container { + flex-direction: column; + padding: 1.5rem; + margin: 0rem; + } + .textModal { + margin: 0; + margin-bottom: 1.5rem; + } + .selector { + font-size: 1.25rem; + } + .description { + font-size: 1rem; + padding: 1.25rem; + } +} \ No newline at end of file diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js new file mode 100644 index 00000000..bc884bde --- /dev/null +++ b/docs/src/pages/index.js @@ -0,0 +1,45 @@ +import React from 'react'; +import clsx from 'clsx'; +import Layout from '@theme/Layout'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import styles from './styles.module.css'; +import InfoModal from './components/InfoModal' + +function Home() { + const context = useDocusaurusContext(); + const { siteConfig = {} } = context; + return ( + +
+
+
+ +

{siteConfig.title}

+

+ Enhance the observability and security
of your database applications. +

+
+
+ + Get Started + +
+
+
+
+ +
+
+ ); +} + +export default Home; diff --git a/docs/src/pages/styles.module.css b/docs/src/pages/styles.module.css new file mode 100644 index 00000000..20507a6f --- /dev/null +++ b/docs/src/pages/styles.module.css @@ -0,0 +1,84 @@ +/* stylelint-disable docusaurus/copyright-header */ + +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + padding: 1rem; + max-height: 100vh; +} + +.icon { + margin-top: 3rem; + margin-bottom: 1rem; + width: 20rem; +} + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; + background-color: var(--ifm-background-color); +} + +@media screen and (max-width: 966px) { + .heroBanner { + padding: 2rem; + } +} + +.main { + background-color: var(--ifm-background-surface-color); +} + +.heroTitle { + color: var(--ifm-font-color-base); + font-size: 4rem +} + +.heroSubtitle { + color: var(--ifm-font-color-base); + font-size: 1.25rem; +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} + +.getStarted { + border-radius: 0; + border: 1px solid var(--ifm-font-color-base); + box-shadow: 2px 2.5px 0px var(--ifm-font-color-base); + margin: 1rem; +} + +@media screen and (max-width: 414px) { + .container { + height: 75vh; + /* max-height: 75vh; */ + /* padding: 0; */ + } + .icon { + margin-top: 1rem; + /* margin-bottom: .5rem; */ + max-width: 15rem; + } + .heroTitle { + font-size: 3rem + } + .heroSubtitle { + font-size: 1rem; + } + .getStarted { + margin-top: 3rem; + } +} \ No newline at end of file diff --git a/docs/src/theme/CodeBlock/index.js b/docs/src/theme/CodeBlock/index.js new file mode 100644 index 00000000..173a303f --- /dev/null +++ b/docs/src/theme/CodeBlock/index.js @@ -0,0 +1,246 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ + +import React, { useEffect, useState, useRef } from 'react'; +import clsx from 'clsx'; +import Highlight, { defaultProps } from 'prism-react-renderer'; +import copy from 'copy-text-to-clipboard'; +import rangeParser from 'parse-numeric-range'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import usePrismTheme from '@theme/hooks/usePrismTheme'; + +import styles from './styles.module.css'; + +const highlightLinesRangeRegex = /{([\d,-]+)}/; +const getHighlightDirectiveRegex = ( + languages = ['js', 'jsBlock', 'jsx', 'python', 'html'], +) => { + // supported types of comments + const comments = { + js: { + start: '\\/\\/', + end: '', + }, + jsBlock: { + start: '\\/\\*', + end: '\\*\\/', + }, + jsx: { + start: '\\{\\s*\\/\\*', + end: '\\*\\/\\s*\\}', + }, + python: { + start: '#', + end: '', + }, + html: { + start: '', + }, + }; + // supported directives + const directives = [ + 'highlight-next-line', + 'highlight-start', + 'highlight-end', + ].join('|'); + // to be more reliable, the opening and closing comment must match + const commentPattern = languages + .map( + (lang) => + `(?:${comments[lang].start}\\s*(${directives})\\s*${comments[lang].end})`, + ) + .join('|'); + // white space is allowed, but otherwise it should be on it's own line + return new RegExp(`^\\s*(?:${commentPattern})\\s*$`); +}; +// select comment styles based on language +const highlightDirectiveRegex = (lang) => { + switch (lang) { + case 'js': + case 'javascript': + case 'ts': + case 'typescript': + return getHighlightDirectiveRegex(['js', 'jsBlock']); + + case 'jsx': + case 'tsx': + return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']); + + case 'html': + return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']); + + case 'python': + case 'py': + return getHighlightDirectiveRegex(['python']); + + default: + // all comment types + return getHighlightDirectiveRegex(); + } +}; +const codeBlockTitleRegex = /title=".*"/; + +export default ({ children, className: languageClassName, metastring, landingPage }) => { + const { + siteConfig: { + themeConfig: { prism = {} }, + }, + } = useDocusaurusContext(); + + const [showCopied, setShowCopied] = useState(false); + const [mounted, setMounted] = useState(false); + // The Prism theme on SSR is always the default theme but the site theme + // can be in a different mode. React hydration doesn't update DOM styles + // that come from SSR. Hence force a re-render after mounting to apply the + // current relevant styles. There will be a flash seen of the original + // styles seen using this current approach but that's probably ok. Fixing + // the flash will require changing the theming approach and is not worth it + // at this point. + useEffect(() => { + setMounted(true); + }, []); + + const button = useRef(null); + let highlightLines = []; + let codeBlockTitle = ''; + + const prismTheme = usePrismTheme(); + + if (metastring && highlightLinesRangeRegex.test(metastring)) { + const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1]; + highlightLines = rangeParser + .parse(highlightLinesRange) + .filter((n) => n > 0); + } + + if (metastring && codeBlockTitleRegex.test(metastring)) { + codeBlockTitle = metastring + .match(codeBlockTitleRegex)[0] + .split('title=')[1] + .replace(/"+/g, ''); + } + + let language = + languageClassName && languageClassName.replace(/language-/, ''); + + if (!language && prism.defaultLanguage) { + language = prism.defaultLanguage; + } + + // only declaration OR directive highlight can be used for a block + let code = children.replace(/\n$/, ''); + if (highlightLines.length === 0 && language !== undefined) { + let range = ''; + const directiveRegex = highlightDirectiveRegex(language); + // go through line by line + const lines = children.replace(/\n$/, '').split('\n'); + let blockStart; + // loop through lines + for (let index = 0; index < lines.length;) { + const line = lines[index]; + // adjust for 0-index + const lineNumber = index + 1; + const match = line.match(directiveRegex); + if (match !== null) { + const directive = match + .slice(1) + .reduce((final, item) => final || item, undefined); + switch (directive) { + case 'highlight-next-line': + range += `${lineNumber},`; + break; + + case 'highlight-start': + blockStart = lineNumber; + break; + + case 'highlight-end': + range += `${blockStart}-${lineNumber - 1},`; + break; + + default: + break; + } + lines.splice(index, 1); + } else { + // lines without directives are unchanged + index += 1; + } + } + highlightLines = rangeParser.parse(range); + code = lines.join('\n'); + } + + const handleCopyCode = () => { + copy(code); + setShowCopied(true); + + setTimeout(() => setShowCopied(false), 2000); + }; + + return ( + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( + <> + {codeBlockTitle && ( +
+ {codeBlockTitle} +
+ )} +
+ +
+
+ {tokens.map((line, i) => { + if (line.length === 1 && line[0].content === '') { + line[0].content = '\n'; // eslint-disable-line no-param-reassign + } + + const lineProps = getLineProps({ line, key: i }); + + if (highlightLines.includes(i + 1)) { + lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`; + } + + return ( +
+ {line.map((token, key) => ( + + ))} +
+ ); + })} +
+
+
+ + )} +
+ ); +}; diff --git a/docs/src/theme/CodeBlock/styles.module.css b/docs/src/theme/CodeBlock/styles.module.css new file mode 100644 index 00000000..a55cce17 --- /dev/null +++ b/docs/src/theme/CodeBlock/styles.module.css @@ -0,0 +1,66 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.codeBlockContent { + position: relative; +} + +.codeBlockTitle { + border-top-left-radius: var(--ifm-global-radius); + border-top-right-radius: var(--ifm-global-radius); + border-bottom: 1px solid var(--ifm-color-emphasis-200); + font-family: var(--ifm-font-family-monospace); + font-weight: bold; + padding: 0.75rem var(--ifm-pre-padding); + width: 100%; +} + +.codeBlock { + overflow: auto; + border-radius: var(--ifm-global-radius); +} + +.codeBlockLandingPage { + border-radius: 0; + font-size: .95rem; +} + +.codeBlockWithTitle { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.copyButton { + background: rgba(0, 0, 0, 0.3); + border: none; + border-radius: var(--ifm-global-radius); + color: var(--ifm-color-white); + cursor: pointer; + opacity: 0; + outline: none; + padding: 0.4rem 0.5rem; + position: absolute; + right: calc(var(--ifm-pre-padding) / 2); + top: calc(var(--ifm-pre-padding) / 2); + visibility: hidden; + transition: opacity 200ms ease-in-out, visibility 200ms ease-in-out, bottom 200ms ease-in-out; +} + +.codeBlockTitle:hover+.codeBlockContent .copyButton, .codeBlockContent:hover>.copyButton { + visibility: visible; + opacity: 1; +} + +.codeBlockLines { + font-family: var(--ifm-font-family-monospace); + font-size: inherit; + line-height: var(--ifm-pre-line-height); + white-space: pre; + float: left; + min-width: 100%; + padding: var(--ifm-pre-padding); +} \ No newline at end of file diff --git a/docs/src/theme/Footer/index.js b/docs/src/theme/Footer/index.js new file mode 100644 index 00000000..3be3c049 --- /dev/null +++ b/docs/src/theme/Footer/index.js @@ -0,0 +1,128 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import { useLocation } from 'react-router-dom'; + +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import styles from './styles.module.css'; + +function FooterLink({ to, href, label, prependBaseUrlToHref, ...props }) { + const toUrl = useBaseUrl(to); + const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true }); + + return ( + + {label} + + ); +} + +const FooterLogo = ({ url, alt }) => ( + {alt} +); + +function Footer() { + const context = useDocusaurusContext(); + const { siteConfig = {} } = context; + const { themeConfig = {} } = siteConfig; + const { footer } = themeConfig; + + const { copyright, links = [], logo = {} } = footer || {}; + const logoUrl = useBaseUrl(logo.src); + + if (!footer) { + return null; + } + + const location = useLocation(); + const showBorder = location.pathname != '/' + + return ( +
+ ); +} + +export default Footer; diff --git a/docs/src/theme/Footer/styles.module.css b/docs/src/theme/Footer/styles.module.css new file mode 100644 index 00000000..b9f41248 --- /dev/null +++ b/docs/src/theme/Footer/styles.module.css @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.footerLogoLink { + opacity: 0.5; + transition: opacity 0.15s ease-in-out; +} + +.footerLogoLink:hover { + opacity: 1; +} + +.footerBorder { + border-top: 1px solid var(--ifm-toc-border-color); +} \ No newline at end of file diff --git a/docs/src/theme/Navbar/index.js b/docs/src/theme/Navbar/index.js new file mode 100644 index 00000000..daa43808 --- /dev/null +++ b/docs/src/theme/Navbar/index.js @@ -0,0 +1,349 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { useCallback, useState, useEffect } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import { useLocation } from 'react-router-dom'; + +import SearchBar from '@theme/SearchBar'; +import Toggle from '@theme/Toggle'; +import useThemeContext from '@theme/hooks/useThemeContext'; +import useHideableNavbar from '@theme/hooks/useHideableNavbar'; +import useLockBodyScroll from '@theme/hooks/useLockBodyScroll'; +import useWindowSize, { windowSizes } from '@theme/hooks/useWindowSize'; +import useLogo from '@theme/hooks/useLogo'; + +import styles from './styles.module.css'; + +// retrocompatible with v1 +const DefaultNavItemPosition = 'right'; + +function NavLink({ + activeBasePath, + activeBaseRegex, + to, + href, + label, + activeClassName = 'navbar__link--active', + prependBaseUrlToHref, + ...props +}) { + const toUrl = useBaseUrl(to); + const activeBaseUrl = useBaseUrl(activeBasePath); + const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true }); + + return ( + + activeBaseRegex + ? new RegExp(activeBaseRegex).test(location.pathname) + : location.pathname.startsWith(activeBaseUrl), + } + : null), + })} + {...props}> + {label} + + ); +} + +function NavItem({ + items, + position = DefaultNavItemPosition, + className, + ...props +}) { + const navLinkClassNames = (extraClassName, isDropdownItem = false) => + clsx( + { + 'navbar__item navbar__link': !isDropdownItem, + dropdown__link: isDropdownItem, + }, + extraClassName, + styles.navbarItem, + ); + + if (!items) { + return ; + } + + return ( +
+ e.preventDefault()} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.target.parentNode.classList.toggle('dropdown--show'); + } + }}> + {props.label} + +
    + {items.map(({ className: childItemClassName, ...childItemProps }, i) => ( +
  • + +
  • + ))} +
+
+ ); +} + +function MobileNavItem({ items, position: _position, className, ...props }) { + // Need to destructure position from props so that it doesn't get passed on. + const navLinkClassNames = (extraClassName, isSubList = false) => + clsx( + 'menu__link', + { + 'menu__link--sublist': isSubList, + }, + extraClassName, + ); + + if (!items) { + return ( +
  • + +
  • + ); + } + + return ( +
  • + + {props.label} + +
      + {items.map(({ className: childItemClassName, ...childItemProps }, i) => ( +
    • + +
    • + ))} +
    +
  • + ); +} + +// If split links by left/right +// if position is unspecified, fallback to right (as v1) +function splitLinks(links) { + const leftLinks = links.filter( + (linkItem) => (linkItem.position ?? DefaultNavItemPosition) === 'left', + ); + const rightLinks = links.filter( + (linkItem) => (linkItem.position ?? DefaultNavItemPosition) === 'right', + ); + return { + leftLinks, + rightLinks, + }; +} + +function Navbar() { + const { + siteConfig: { + themeConfig: { + navbar: { title, links = [], hideOnScroll = false } = {}, + disableDarkMode = false, + }, + }, + isClient, + } = useDocusaurusContext(); + const [sidebarShown, setSidebarShown] = useState(false); + const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false); + + const { isDarkTheme, setLightTheme, setDarkTheme } = useThemeContext(); + const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll); + const { logoLink, logoLinkProps, logoImageUrl, logoAlt } = useLogo(); + + useLockBodyScroll(sidebarShown); + + const showSidebar = useCallback(() => { + setSidebarShown(true); + }, [setSidebarShown]); + const hideSidebar = useCallback(() => { + setSidebarShown(false); + }, [setSidebarShown]); + + const onToggleChange = useCallback( + (e) => (e.target.checked ? setDarkTheme() : setLightTheme()), + [setLightTheme, setDarkTheme], + ); + + const windowSize = useWindowSize(); + + useEffect(() => { + if (windowSize === windowSizes.desktop) { + setSidebarShown(false); + } + }, [windowSize]); + + const { leftLinks, rightLinks } = splitLinks(links); + + const location = useLocation(); + const hideBorder = location.pathname == '/' + + return ( + + ); +} + +export default Navbar; diff --git a/docs/src/theme/Navbar/styles.module.css b/docs/src/theme/Navbar/styles.module.css new file mode 100644 index 00000000..5b416c8d --- /dev/null +++ b/docs/src/theme/Navbar/styles.module.css @@ -0,0 +1,51 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +@media screen and (max-width: 997px) { + .displayOnlyInLargeViewport { + display: none !important; + } +} + +.navbarTitle { + font-size: 1.5rem; +} + +.navbarItem { + font-weight: 600; + font-size: 1.2rem; + padding-left: 1rem; + padding-right: 1rem; +} + +@media (max-width: 768px) { + .hideLogoText { + display: none; + } +} + +.navbarHideable { + transition: top 0.2s ease-in-out; +} + +.navbarHidden { + top: calc(var(--ifm-navbar-height) * -1) !important; +} + +.darkModeToggle { + margin-left: 1rem; + margin-right: 1rem; +} + +.navbar { + box-shadow: none; + border-bottom: 1px solid var(--ifm-toc-border-color); +} + +.hideBorder { + border-bottom: none; +} \ No newline at end of file diff --git a/docs/static/.nojekyll b/docs/static/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/static/img/apzm-icon.png b/docs/static/img/apzm-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7a13583fc6a59b3f91f78a542b001a48172cc3e8 GIT binary patch literal 11511 zcmY*<1ymi)vh_K*OK?8~cRRQQ3Ber#1lQp1dTZ$7LUAwwwRj<)7MR^HSBtj$r0Dvkb`C0j0M!q*c1i1I(OFHk`yMXyFA}0a>R7WE} z8^FHzK}M3wasYq_H2?q!1OOi2O^^csz?l^QIMN3I_>uttJiGK3C4u*WKoboqQ#m;R z{kx6;fCYX4K)-9i_ZTbY_K(lM zC3F_>e;Bi%{)>*xg8r}W_m5k=#rFKWK(v$8bOZp9vHod5Kx#VvJDaAts)mz>oGhP_ ztu?cOv8|yAvzxWuKVARH z6hUIP4kjQ@W-v4BMZRdnASostj%uU`S|HCiDCh#xh|FQii zjsVL)!T;A}{+;Q+tnaA`AqlYj_p}Ki$@b7_0s!=GQlCXs-GHawi19k&&1ap39CzvC z0+>NC4g?NivgB=GdIQ!R{TM3U&uw`2U8U!OHx;{TPdYkxg6j@p>PgTZYNT#Bp+yLR z`cQ~@Gn6qPpnrta(BdJRV7fWF+WFHR?~`$6+}Vy(ru-eRo5ju9a_dp0fx7p8W#{W- zDVNfmnksT#gS2xELz%1#Y{_nB6YQBrD_7Ah`1MydtPuWu#Mx`zO`ssgr{_3y#&drA z-zs>enJs0dywM8CV7MSAb!YxV1+Dn-Ep?mUF;@u+Wq)eu*qrRnQ;BTs1`5-+98;XW zs(Y!uanap)7$9c%DT~f7i4HK56Ulve`-wE<%T_R|?Y{DO>WuY=eQwh{N6QOk_s?S= zM`NFqml}QDkPLIaZ0@zLTAo*qyppeM*jn!=t$O;+{!Ho4-{$fr$5AS44a~0e;j70J z@=EcbjETe&2Z_#)3k5xq>gydQ`?GWC0$C4-^8Ma8;KCfWL0*MkYG@Fz556+?-%LXU zWqF0tt24j98{83lyiAP^^>Y!9I9D~LXbSFQN zIkJ6NZRq5}iE{yi)#N!+=Tr5UC#>8a(|y$1XQ+3tlyFgb2{1nL2HKydVP=2IroQ3! zZLm0OLinvV8BxPc9scaN(!hy|lAx&s_lqMn@YBvh&EDbg(I;p3nPyN@ac z=YRx(1kE`rt%Z7fMFUk`DnC(<3!k7_CX+JV=fldk18=u!KFYjfj}# zVg1o#a>kkKc?^ErO3^jIKzmrr2`j*=-r#6adZHqEgP7A5mPKK*-j)dP<3CXzEvc7% zY3371SmxMHe%(IK$oR?Szkp>PnQvN3hXmW3s!SouU!DPt{-^%gKV(I3t$N~vhfF7H zC-(sllN4Q&f!y(JN7c)dag{;;nDxp&Zmv>=L#ndp_w;GKn}GUmy6^o$RwWjtlqLqn zOC^9v>>Ru|AF_ryPg;C$I>8t;< z#1%3Cw|-b1RLf62%MvtpA;aM+5Nly=ZF13EK|kZh#1`hW8jF`2e0igy39Et-zS7|H zvCHlOiHxhD6vjIS>OE@8(^BT0#ON?5M;GARTPC{vP^!wRdH_nP z^f!LSVzhMpnUgUL-%PyeC1akNxVo-#v|$c%l*}KCv@?*}(5wQXy`rN5y>wq69PlbF z)~Su|(`;;A!5bEx!}JdRW~h8k`kO5O)p&?{y^|x+YJ+#{Wo^F9%BL2CYXUcI)F$od z;fD`mGq+#B*6m!1op}0$?j1r?s1J?GYh#`3lkpXZYx1d&{mLc;k=P6ISn1@fskZ?g zEae(kMA?B4KRhcu*QK!f1DWS<1i*oy*rN>2mx|U0k-we;Nt`XwF*P!p`u`r#V zm|0O$_+D;w9dC=dT6+fD!`zGsHca)jW;Ts73@;O3guQjtBJLKIA37CBnLa3A;U;1} z;mqu#nQQ5(JhhVbeGqxmI8yp07@0pe5Mz1+-3pa@R2KoS58|ikiF!C)FZZ&2veo+5 zf-Y^@ZrHCrf3QrU;Uv&~27QSCnWfmp;Zy_ITd4~>h7Vv(q}D6@9rA}!Ufl)6`n$@!TRP({STG=@**O;9XAf1xjl@M3(`3FPg$<2%z-F_XIH|gWa z&QlZYrGv0k1yX8k>Um$-r+ORpTobc}MfwCQji6#@1=`)``wYv(&J1<>czor z(uJN5+2lGeDJ;2lcF~DW->){g*40Xrg~hhjB#Iqe;gl4y^mI?-#x>Vdn+VF3%bb3w z_Tk?~4>e|>vb#E0?|1f)vw@^>Us{k-H$4o9du(*qxfa;s`K1$$nwXXr2DGmUsWaxwuiyy3z%pdASLhVQ0F}cbo)FZXS!W2^#@(jc#vG?P?1i;48H%yds*dBSfWJ`PJz_AbXx%I<5~jw09+ z{5*icEE{|n3zu=>Yk2gosV9;wI`$LGFfh<^otN?-S8^99_+fxrDNrNYiIm!dOSk#3 zeZ0IL8Cj9ZFeeX33>Ra6Ca-Zg#*g$hSwc+^MbomPEidWut{vp5Qkt*m10~`P-xOuJ zg`t|TkOTBa4Xzi=9d10Zw*sfUGEHCk=at{~m`Mp1#@~JK5*Bus;`_ZEP)pb6jg)5#mPxnOyoOT;{?6cG?}A=0~Y6=3qy=t?l6fl5(=MZ8IvT| z26%qtmJY8=>N5#0K1(ICd(DWqRIgn68;^+!o}=~FXd-^m2el6MpF{crvsJz2E(GVFG~pd%sIp}SVszR zEZ6yXxN5}KU{`v`(jm|8Cfra3mASVLGew`HfBF;JSQZvD5PRN$J)@L;4556j#ZukM z)%C4#y1_wLPFTx4?d8pD+h{@n??}>l^<_8_nc~jzO$Mu2YVt zpMn4D9+5p>N_Swa8fOm$_%3PX)xkL=?y>$b6z=Pkm~Cv=g5qnD#@4>MjJFW+SLUyr zyIN5nS@6k!<4)0oA$8DKt*WP<#~(9yuAAA=nz0Q`P4-?pv(d*+9Gf^0z$`!8A?iO zw6E_(mBytJUr|I38CN0Rchchfz*XNcX@dQ2wYWB?I$uO;_{`X%v{*%g2{w&{JX0<3#Y$TJ zV_0C_N2ODC8J@S8hVq1MB^qL{J4j+x$L+DD)*5m2Gc|j(E2WvuQY{VT+L3n7Q5`ni zQql$$UUwf`psjGQf!mJ$4VsE^%F_WZ8Y@f$go4gl$X8u$R+m_{=%PEA)zm{-+WBtQ z?!rkxugTL6M6(@{pS!vg8&esmPjh|Dwm2M-KYA&D9R);{&s5dZdtBp_;roHo+a${w zpPzi4&Vro^C0qr(v4@is=cKOWV+hAmuIJ&ALxB+05)VPDNd{3;|MovsG@lfTC+G!# zK1WE|yB%zl{ey?3ZN75&181705ywlQN9$BVAz`P>eWNbk&O+uld|3A|h;ZusqJM=( zdd!l2MjdQ+k3s4=0`Uk?@sty3Ovo z|1i*5O*u3g;R7;#HoR!~GLXr^yNG6ZgES$`gtuK!+~3rq>a2&dL&bWDM;>S0nz2Eo zJTUS)5Oe^i{};hG=htj}eoSQ#Sgy45tefdB{d$_}NlPnXRcZrEC$l<{`;v)!KK0`t zIm^azv@dgSKSc&jlydRDouzAvVc$O@e@DXTy##&}T>rHf zKw{xSFDy29S#|ijJ=5)_c-><-gSy2Ug+_b8G#Zy}*DXy{$2F97m*B&9HT%=BmM*Mf z0D-s!IVf|M)4DMYQysL8GQ`cns>*x^Mc>b2J1KnUFp}ArL7F?%Xie9FIIe^pa!J^U zz9;*2D2t9m6eibJStGHVDlqR={b@LAh4fI$dyqKo0CW1LZ`SVQGV8n|Clc# z!7~+Ty-i^=K$h;e;hnbvuNqnK#YqfCl3zdh?^w`6#p=`VR8C%8u*ewyp5gDW1rJ_Y zE2HFtk2EsjBU7oHQyt{^$o+uYz}!htmEr70Hl81!tdT!`|K5NkGTB?&<`e~L#dNi2 z=!d6m@ckYjrJZLqcRi1l-HNX^sz65|A;(c)H$VkbVQ*R#W`_NxBZmI=<#rjlBlPmJ zu+e7mQkkddm*vtphgbl-i|HNJFUHcEFcz&zO1WRX_;ngC=lTXs64ZpXWDWU_+*j*}fZ+0#azF67rnjD=M(ZG}wL- zb`^&^#9A;K{BhdGI#uBObi21qrrTbJdU#(Vsh*hia5B&!15c?FLMD(1J#gj*yTM5N zhQ3W(@~TOWGzV6kbfI0w&I@*3*x&#>qzCsWa`TZ$8=Ry#enD}FhBiX9D=fo^R2dkS z*PLxEjRxD5<%k5R>$@{%nKh=IikvFNO4f=zM& zvDHaZTI3LW+`zqx!syB4Pl9W-=#U>j!EXj@1N-6g+^8yjd2k7+W*Wzq=F1ilFZ)>r z5`tQMnhZUFA0B)&voG@?Uh3L-uR&DIKE;7=#x8I?DtTz5ke@IQ{q+O(Av6Nel3&Ci zP8mOOcrq%`JJ=*!&wT4D&iGQu>Fywx6s^<%<*w@#OEVW z;Kea~Nkn(prtV!0SkgO}En-cf!@j6r#?mo_^TULEx@actlSkmPAt}eAds9e6FpB4rXp{ulfIz4(-PTq5cMLF`v41BAHD8M?* zds?8_qmeo8?JCi|RySt!5#Hs^I0J*23HYX(UzZ-)o*JwB#?nRhv!TbOdvoB7gjua#0L) zg_{S&g||GgvEv8X;hHK*fc}zdyJ8T-;h4aKn$u0bqS9@AZS%0lUrr&|Fw{(MHNIz` z5yw_u*v>{GY!v@;slY9Iu1<_B=V4{$Fu8b{mq%U(q+-=Z$=QY9Mx(kcHQgxE&{hUe z;yAsuMR7bxnxN6h(JIobCUY2s z3F&qaPsQNT1SE~PE6zE655KKgk_qA37N&!&ki@mA3mXg1Sv9#wMwKaOO%wIo;2y@!%yf8yUnmX{`Gxn@=Z`07ws@o0&@4zWNuD zYuT|~00ruw>~Jyn;P@_f2$Ju_hy)N+#s;Lk(b&!KarspWWHxONz2o#1eAkvJPWZxTM%)4L(&>RCOo)RNNuXwp1rSkk_+YT8|nn zq$xTw?a2rbl===t<^|NYP5U_q0;8^B<~3#1!B1@)*Y9UUPDlBWRNf_Fw79)HCYW987cPwu`=>=1tv?PFZvpqDY^IiP3n42v_xsd2!`HT0S5&#NKM zgYp|39=zh}P{g15%T`Y@>bSk4XLcZ4)dh@lQMla95?gL~8iQAxD3{&L(uUn^u$#CF zP8TeHup^EzlEsX3^x=&po46ziO$``X`q|q04b%g?TL}!3nvsp*#A1GkH+nH68=PED z)?q_7{W60%3e@d4so>a%To)QKc6njoFPDC;wt8;vo+y;aI`*b=X4}l1Ttf#FAtzdc z`^p9;q}smz^$YBdXIZeLOpm5!iM9gARYk$BqYh1q9ym7{O>LTwPJ6iY2D^PnckY-J zyA+!oB^jLK34z*ALb_e~5FQ2D z&MrR|QN_=AshSbA)4S4Qz~LBwVX|bUyTsnc*w(gM6SZ5epRLkXn$Z^@qot7eJ<6UC zu^DazU2>b9j0K&N8;8Iw9mi(i6j&MR@P5ArZdrC_B~GsqIMWyS&G)=WH)k0ebwdWP zVybXIhAJZjT!fxxivh7g|AzjsKOBuPB0I(_L~%c_e?Al8NL1wVH4p_wAywgc0QAVP zH~7*D-yKl2IK?UFq)y84)s!`dHV|8f{0J}%@XD!Np^i#1^T?r*xH$tWdi zb;71s=Ve&s1$srx?+6)qq+2gMulBUR3m)E%c6}U}6|$c;s7I{XLA+q(%cB>& zKL*Q@Am9w$Z42k8HR9jUC^>(qf_a%{XxVW>beebViYDxJ7RkqVT`trRI=B1@j14(- z$AQEV>*-d|pvyf$G9iwk@GUJyBCTKok<OU+<zmzVawp{L+0>SpXt>C;?!Tw99^%=)PmP zCFw`-O!Jz?%LP_#8^qy`1`mum7bXo`?lW3k73jcvGY3*ljXoO<$wP_nS zA~Q!~K?BG|F{hRL9dc9>G)oKg5ox$LfNEhtBYnV(P2#jr)4F!;&P1kFP3 z7!_!7@}vpKutSoOzKBO)ts9uCsL3IcMZy7mH1N^l^;=M8*67)L`CWd_swBro$S%I7 z&SCr!sF?woEwbU2oFb8+WptwsnBVppeteFB4n;1qI)4A+h`Q`gh3eFOQ)@n4q6vn6 zO0X#SZdxz4=%3R)R021^(O$J9BeJ4(;1*f(R-Qe&MVT}>zHf=)5`cU(tiAe~t1F2h zSRe{Y8A7>#Pl|`$>Q=1HMT`#ABMc_R9}AJ-{bSrB1v@tJl}V1LBo?j6Vhtbj%l8^y zDt`F1>V)rTN*7@-tY0CEnnTuY^CM7UB7OXz;{rIkU;($~QHGUT^4?L6h+WZ1RF^z6 z06Y|UG}^F*q{oLA=8>Pk{kF{^J{F*2`U~lD>DfM!)ye`zd4FDUtM1zZUvxDqvE-_N zP6ag7J%QCFzgt2u%Wh0ua6y6pYMy`a3L@j4oyN=+j~vGG5{8uqdn8&Vp4iaL6W!y} z0vk?91T@-?JrP{k+tzsGMw&TL7Y*{r8S_W{&;b_^=s6k;_SosyC4@-rMNmZ=Lk4z% zF@HSfs0DNtQ+HW4_I~C8o6fI@plwQJF|N~n)ATGZcWM`dl=W ze^gqog^O1*_55DIV2($0{j;5=k7~1!9G_VkWqpX~JzUrXn?{df2P_~$_51WLy#S+> z9l~*t{4^T6(oPv2C7S?Bw{8+|r0*hob=D$01Z=1@?PpGV9$d#JdqdX!pjlB9)eMKy z28e)ZN(OFfb-C~~I*cuIcL)#E()vGt>~2=39ob|;K7pXYo>X8^M&R!Su6e`}p*!q> z$9^)lXD&%T1m`U3luPfXhjJcfJ-mirKfdiZ{PGMa`5KTdSV&;h6qe7M@k6xu&_&2r==)Rq)C@OXmMG?(hm;MS0W7Lf>v%{VrUAaT_va2Bt1$n29OCl9q;03r-Z zr~x%nKH4e%`uyKPW8n*+%ke1{B=uK4j#L{u!J)lbjI5(^=*y zd%S-b^%rudP3NO&mpX5ApN0t#*}k7!xmikZPva$$V+6b_>#@I&RkH?FYnWpw*kE@5*Im9gt{-aAN;l4>WL$ z(!t`Sn=CQNfnPv|Yenqp6`z)mclIcognALeLEht@xZ_Wy#gcT+M#6tD5HT01X5qg! z#4-X}3_khmpF^4P8$*5m?fs!wnsPn9qy^KWLEzL3)#dYen?pmZ%??ua656mcpKI)j zd6VCSs6~e3b_%uU14VmP*?EEUj3=g$VW6i2Dl`?%f*YmHhv)4kM*WAO*rhSJIpK`U z0JvUU+0gW{cC7%ML6dvu5jgOtw#OV`8QmLS4q>Io%f{Cj6C%5`;*r9i<3xYFe)Xc$ zz#x9_`s=e_AOQ&IZA}h6e_@swtm_!bweP){fd5c%-PH#wh7U=ZD%-zRw4b)}UQc}4 zdX+0@a(|>_Id-^v53#EFw&XAcw1Tvgp=NT!?#>-HlVwP7R@o{AWBqBD-<7@Zm~_A7 zjX_aJ1j2`gj09Xe&Gb$MU|4s1*>|oOK@@ONh-;+X%7M_Vq^jl2Dg`z#4)7XmTC=rBcP$5{ZUkUW*tkxr%$9En=kI?dosG1 zjVAD^a!gDvp!thri{o{1?*J}bV@P_s4?mkmVb_y#M$p97h$|LH0 zb4SNsYGRbZ76X0J36EUG&0@|Ninn^g5!uD%RGZoeV4TNNd;0VD)dmbgBZR@#>Y%7* z=+<=fgUhO3;4ArH?(mn(ZTs;bjxSb^R`{7=Gl4;K?u8QON3x5@#OHQJQEsFzeCxTb zt@IAzI``7ObuQ$?J3{L%2A0TNaeoZx&+agz)CNxZ!zd2qJWeYX%r?q_ThWkaBmWT+ zuhqeAd;w#(JLY|T!e^WNwQb5!*Juj+!{n7L$&NcS?KA)HsuX^4Qx{C-#>c2_c7mqSq$r4l)}kt*_@C>aBLyqz})+!Z=DQ$?7}wA+H7oJUmpA z$hLZtg7_6JnZ4sfoup&$pUB1>g0(%~BJuVg87atZUB!PvdkGH>z}vF|Y>O-h z){5!wU1sgl(Rv)Te;T&O&qt?+womA3=dV9~%WKoy#ZnMz9923w*Y7`o@^WsNe2pYd zcA>61Pp$NhCd~pzlv=G>pW7oQnk4hz^MntIv$LaYwe#E)MD?Y^ZR(OD?5j`~WT;7~ z;LUY!p%+TKQD?sH#W`R!2&AD(JhKZ6NSWPpgx0Y#Ek6Hy`gNpB`m&nmnW)K+8r@7(Cm{j z`k_l1c7+yxGo<>bUPvSxnGbevVk!tN&GcFUPZ1V&duBM1{6KB6=8RC*^6vR?Sw_MY z&PT*&_gOympXWZ{!*d4*=?py~ls8_aB9FMkGGbr_98>LMJEH}*bsubIpg_zq&m z1#c23zmQB);=5*VE^LZu@FatvzbO_azo*#I7Zu(RTE4cD8TIK_PrZ?tM>ADAs#0Up zF4x!2`{~1pag(+ZF=+*^e=|xcB|$|1zNFQ`F7JZNVw_1^SKPgloTJ^&u}cbM|H;plJdJ58pY#yWRR*a&aJlHXBo{1AO)Ebv zuNe{+ZwW(Z$-+zGiY)5D7`S?D%B0dW&RQ?U^Z-L`V=i62mBB`I9|iIz!5U6SF^czA z+38t5s9i^RogAuaUxW$zd2f_R{8?pBpn7<Pg5uAR!i zU_oOJ5-2TDXKHh7Mi+y73N)Er2UfbhIY*^)bd3vI zCIM=VAqU*YpO}T_#>|zTX~lU$>b$= zJ1N8=r1k_QqW7LJ#SsWltinixV!cl}Cjij_0?$h;mZ9cwX$xRqKOJ##c|LNH{PPDg OKuTQxbA_nB|NjF{vcKK{ literal 0 HcmV?d00001 diff --git a/docs/yarn.lock b/docs/yarn.lock new file mode 100644 index 00000000..34d99193 --- /dev/null +++ b/docs/yarn.lock @@ -0,0 +1,10296 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/compat-data@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.4.tgz#706a6484ee6f910b719b696a9194f8da7d7ac241" + integrity sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.6.tgz#d9aa1f580abf3b2286ef40b6904d390904c63376" + integrity sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.6" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.6" + "@babel/parser" "^7.9.6" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.6" + "@babel/types" "^7.9.6" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/core@^7.7.5", "@babel/core@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.4.tgz#780e8b83e496152f8dd7df63892b2e052bf1d51d" + integrity sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.10.4", "@babel/generator@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.4.tgz#e49eeed9fe114b62fa5b181856a43a5e32f5f243" + integrity sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng== + dependencies: + "@babel/types" "^7.10.4" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-builder-react-jsx-experimental@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.4.tgz#d0ffb875184d749c63ffe1f4f65be15143ec322d" + integrity sha512-LyacH/kgQPgLAuaWrvvq1+E7f5bLyT8jXCh7nM67sRsy2cpIGfgWJ+FCnAKQXfY+F0tXUaN6FqLkp4JiCzdK8Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-compilation-targets@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== + dependencies: + "@babel/compat-data" "^7.10.4" + browserslist "^4.12.0" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz#2d4015d0136bd314103a70d84a7183e4b344a355" + integrity sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz#f037ad794264f729eda1889f4ee210b870999092" + integrity sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.4" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz#40a1cd917bff1288f699a94a75b37a1a2dbd8c7c" + integrity sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A== + dependencies: + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-member-expression-to-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz#7cd04b57dfcf82fce9aeae7d4e4452fa31b8c7c4" + integrity sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz#ca1f01fdb84e48c24d7506bb818c961f1da8805d" + integrity sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-plugin-utils@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.4.tgz#59b373daaf3458e5747dece71bbaf45f9676af6d" + integrity sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz#fce8bea4e9690bbe923056ded21e54b4e8b68ed5" + integrity sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== + dependencies: + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-split-export-declaration@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1" + integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helpers@^7.10.4", "@babel/helpers@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.10.4", "@babel/parser@^7.9.4", "@babel/parser@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64" + integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA== + +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz#4b65abb3d9bacc6c657aaa413e56696f9f170fc6" + integrity sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz#7a093586fcb18b08266eb1a7177da671ac575b63" + integrity sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.9.5" + +"@babel/plugin-proposal-object-rest-spread@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz#50129ac216b9a6a55b3853fdd923e74bf553a4c0" + integrity sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.4" + +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz#750f1255e930a1f82d8cdde45031f81a0d0adff7" + integrity sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-private-methods@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" + integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.4.tgz#2f55e770d3501e83af217d782cb7517d7bb34d25" + integrity sha512-oSAEz1YkBCAKr5Yiq8/BNtvSAPwkp/IyUnwZogd8p+F0RuYQQrLeRUzIQhueQTTBy/F+a40uS7OFKxnkRvmvFQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz#a670d1364bb5019a621b9ea2001482876d734787" + integrity sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-for-of@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-modules-amd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz#cb407c68b862e4c1d13a2fc738c7ec5ed75fc520" + integrity sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA== + dependencies: + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== + dependencies: + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz#8f576afd943ac2f789b35ded0a6312f929c633f9" + integrity sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ== + dependencies: + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== + dependencies: + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + +"@babel/plugin-transform-new-target@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-object-super@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + +"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.9.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz#7b4d137c87ea7adc2a0f3ebf53266871daa6fced" + integrity sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-react-constant-elements@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.4.tgz#0f485260bf1c29012bb973e7e404749eaac12c9e" + integrity sha512-cYmQBW1pXrqBte1raMkAulXmi7rjg3VI6ZLg9QIic8Hq7BtYXaWuZSxsr2siOMI6SWwpxjWfnwhTUrd7JlAV7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-react-display-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz#b5795f4e3e3140419c3611b7a2a3832b9aef328d" + integrity sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-react-jsx-development@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz#6ec90f244394604623880e15ebc3c34c356258ba" + integrity sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ== + dependencies: + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-jsx-self@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz#cd301a5fed8988c182ed0b9d55e9bd6db0bd9369" + integrity sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-jsx-source@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.4.tgz#86baf0fcccfe58084e06446a80858e1deae8f291" + integrity sha512-FTK3eQFrPv2aveerUSazFmGygqIdTtvskG50SnGnbEUnRPcGx2ylBhdFIzoVS1ty44hEgcPoCAyw5r3VDEq+Ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" + integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== + dependencies: + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-pure-annotations@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz#3eefbb73db94afbc075f097523e445354a1c6501" + integrity sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-runtime@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.4.tgz#594fb53453ea1b6f0779cceb48ce0718a447feb7" + integrity sha512-8ULlGv8p+Vuxu+kz2Y1dk6MYS2b/Dki+NO6/0ZlfSj5tMalfDL7jI/o/2a+rrWLqSXvnadEqc2WguB4gdQIxZw== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-spread@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz#4e2c85ea0d6abaee1b24dcfbbae426fe8d674cff" + integrity sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz#e6375407b30fcb7fcfdbba3bb98ef3e9d36df7bc" + integrity sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.4.tgz#8b01cb8d77f795422277cc3fcf45af72bc68ba78" + integrity sha512-3WpXIKDJl/MHoAN0fNkSr7iHdUMHZoppXjf2HJ9/ed5Xht5wNIsXllJXdityKOxeA3Z8heYRb1D3p2H5rfCdPw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.10.4" + +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.9.0", "@babel/preset-env@^7.9.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.4.tgz#fbf57f9a803afd97f4f32e4f798bb62e4b2bef5f" + integrity sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw== + dependencies: + "@babel/compat-data" "^7.10.4" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.10.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.10.4" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.10.4" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.10.4" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.9.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.4.tgz#92e8a66d816f9911d11d4cc935be67adfc82dbcf" + integrity sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.10.4" + "@babel/plugin-transform-react-jsx" "^7.10.4" + "@babel/plugin-transform-react-jsx-development" "^7.10.4" + "@babel/plugin-transform-react-jsx-self" "^7.10.4" + "@babel/plugin-transform-react-jsx-source" "^7.10.4" + "@babel/plugin-transform-react-pure-annotations" "^7.10.4" + +"@babel/preset-typescript@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.10.4.tgz#7d5d052e52a682480d6e2cc5aa31be61c8c25e36" + integrity sha512-SdYnvGPv+bLlwkF2VkJnaX/ni1sMNetcGI1+nThF1gyv6Ph8Qucc4ZZAjM5yZcE/AKRXIOTZz7eSRDWOEjPyRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-typescript" "^7.10.4" + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99" + integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.4", "@babel/template@^7.8.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/traverse@^7.10.4", "@babel/traverse@^7.9.0", "@babel/traverse@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.4.tgz#e642e5395a3b09cc95c8e74a27432b484b697818" + integrity sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.10.4", "@babel/types@^7.4.4", "@babel/types@^7.9.5", "@babel/types@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee" + integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@docusaurus/core@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-alpha.58.tgz#3d9c5540c14c31ac55fc8fa4778e4c4e82fbe993" + integrity sha512-7VW7IQKTxTIeCXxzraLdTqRtYSmEG2ZJDt07z26NjK+17XyNQc0IoJs7M3xhjzaeP0s/CpYe5Yl+pgp6TIXqoA== + dependencies: + "@babel/core" "^7.9.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.9.0" + "@babel/preset-env" "^7.9.0" + "@babel/preset-react" "^7.9.4" + "@babel/preset-typescript" "^7.9.0" + "@babel/runtime" "^7.9.2" + "@docusaurus/utils" "^2.0.0-alpha.58" + "@endiliey/static-site-generator-webpack-plugin" "^4.0.0" + "@svgr/webpack" "^5.4.0" + babel-loader "^8.1.0" + babel-plugin-dynamic-import-node "^2.3.0" + cache-loader "^4.1.0" + chalk "^3.0.0" + chokidar "^3.3.0" + commander "^4.0.1" + copy-webpack-plugin "^5.0.5" + core-js "^2.6.5" + css-loader "^3.4.2" + del "^5.1.0" + eta "^1.1.1" + express "^4.17.1" + fs-extra "^8.1.0" + globby "^10.0.1" + html-minifier-terser "^5.0.5" + html-tags "^3.1.0" + html-webpack-plugin "^4.0.4" + import-fresh "^3.2.1" + lodash.has "^4.5.2" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + mini-css-extract-plugin "^0.8.0" + nprogress "^0.2.0" + null-loader "^3.0.0" + optimize-css-assets-webpack-plugin "^5.0.3" + pnp-webpack-plugin "^1.6.4" + portfinder "^1.0.25" + postcss-loader "^3.0.0" + postcss-preset-env "^6.7.0" + react-dev-utils "^10.2.1" + react-helmet "^6.0.0-beta" + react-loadable "^5.5.0" + react-loadable-ssr-addon "^0.2.3" + react-router "^5.1.2" + react-router-config "^5.1.1" + react-router-dom "^5.1.2" + semver "^6.3.0" + shelljs "^0.8.4" + std-env "^2.2.1" + terser-webpack-plugin "^2.3.5" + wait-file "^1.0.5" + webpack "^4.41.2" + webpack-bundle-analyzer "^3.6.1" + webpack-dev-server "^3.11.0" + webpack-merge "^4.2.2" + webpackbar "^4.0.0" + +"@docusaurus/mdx-loader@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-alpha.58.tgz#ff38d401261cc6ee1ba8d845a7b636c80a54c8ac" + integrity sha512-g/uqzaoaRkwuPmjOB7/p58vNFLev9yE3FdkVfD19mSHyaMaKAzWGUiJxkaxPFtxCs4mwFWk7tJKSLY+B8MjS2Q== + dependencies: + "@babel/parser" "^7.9.4" + "@babel/traverse" "^7.9.0" + "@mdx-js/mdx" "^1.5.8" + "@mdx-js/react" "^1.5.8" + escape-html "^1.0.3" + fs-extra "^8.1.0" + github-slugger "^1.3.0" + gray-matter "^4.0.2" + loader-utils "^1.2.3" + mdast-util-to-string "^1.1.0" + remark-emoji "^2.1.0" + stringify-object "^3.3.0" + unist-util-visit "^2.0.2" + +"@docusaurus/plugin-content-blog@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-alpha.58.tgz#a3cc381b5080eecc76bc2f1248b1ddd64c049807" + integrity sha512-2Pn15pwPdnmKLAvNd4bk2XclnGtGYCpfAECypm9tBql6W6MShy0qOHH3JGLY8dQIMySsCkuC3jCl26EwXNgARw== + dependencies: + "@docusaurus/mdx-loader" "^2.0.0-alpha.58" + "@docusaurus/utils" "^2.0.0-alpha.58" + feed "^4.1.0" + fs-extra "^8.1.0" + globby "^10.0.1" + loader-utils "^1.2.3" + lodash.kebabcase "^4.1.1" + reading-time "^1.2.0" + remark-admonitions "^1.2.1" + +"@docusaurus/plugin-content-docs@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-alpha.58.tgz#8c73472c81abe18c3a3b4534bf1e88ec7367cf20" + integrity sha512-+PHqften1daJXBxUZTN5pMIRP7NwGU7reO4QX0iy7Qp1Wqs63KPY/nSeM7dtxKCYtU+yWkLogvFlicARVqRU9A== + dependencies: + "@docusaurus/mdx-loader" "^2.0.0-alpha.58" + "@docusaurus/utils" "^2.0.0-alpha.58" + execa "^3.4.0" + fs-extra "^8.1.0" + globby "^10.0.1" + import-fresh "^3.2.1" + loader-utils "^1.2.3" + lodash.flatmap "^4.5.0" + lodash.groupby "^4.6.0" + lodash.pick "^4.4.0" + lodash.pickby "^4.6.0" + remark-admonitions "^1.2.1" + shelljs "^0.8.4" + +"@docusaurus/plugin-content-pages@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-alpha.58.tgz#772cc8a628a602e92388d718bc30599edefe847f" + integrity sha512-4LJn2CB83ZCkM4+0qNQWdm4gA2Og3QzmUfSqYOifTmsVsHuLSAqa5zRkkSSsZ244r+ya4e7nmS7nMd7kfK+v4w== + dependencies: + "@docusaurus/types" "^2.0.0-alpha.58" + "@docusaurus/utils" "^2.0.0-alpha.58" + globby "^10.0.1" + +"@docusaurus/plugin-debug@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-alpha.58.tgz#f9e799caaff305587b69871eb63a1a2734c54faa" + integrity sha512-w7sEUzuavp5N4TxgJus1TLFwRkypvg9+mRYZN+mgV05WF3ft+aDTToWeYNZq/8FoC1IEwkezOpPpaWtG4UWM7Q== + dependencies: + "@docusaurus/types" "^2.0.0-alpha.58" + "@docusaurus/utils" "^2.0.0-alpha.58" + +"@docusaurus/plugin-google-analytics@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-alpha.58.tgz#5586f843a518250f9f8ca1178fa77533971bef42" + integrity sha512-R4I8j+XJkOl7fz8+lRnQKr8YP4zrG6dWBNZ66JquUwL6jmaavq1VRVavm7/s5Wr/vYLcpEWjynHViwDdVLegoQ== + +"@docusaurus/plugin-google-gtag@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-alpha.58.tgz#6c43bd7d23ffb68cf4616041fe2c660d9c9b74ce" + integrity sha512-t+B6K2/EvRofygDK5edeQAg2l069aU7H3sViG/3USpJSaY9bWNWRKjZk6BEOypC+mCW6g5HQgewQZ/bTkV+aDA== + +"@docusaurus/plugin-ideal-image@^2.0.0-alpha.39": + version "2.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-ideal-image/-/plugin-ideal-image-2.0.0-alpha.39.tgz#5848f9b519ac0b6303a0812a6e8665c712228844" + integrity sha512-mkRTyC1gCr06M5m7GeKyNNz8ULSFN7gcpjuRZHdJqrmCF69qHGH+oL71Zy2Dz5R3e+Mvd/gwA0wjp+lrMYCi2g== + dependencies: + "@endiliey/lqip-loader" "^3.0.2" + "@endiliey/react-ideal-image" "^0.0.11" + "@endiliey/responsive-loader" "^1.3.2" + react-waypoint "^9.0.2" + sharp "^0.22.1" + +"@docusaurus/plugin-sitemap@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-alpha.58.tgz#5a4134167f8003b0351f80271e49e0fe1daa44ba" + integrity sha512-OS3XZG1S/USyZxSZ4e2pputW3sOl/hxvK+EAs51eOi/fYyVgO4BmFpcsoP17a5d1Cnxf8gumOkS6bLRDaG8KyQ== + dependencies: + "@docusaurus/types" "^2.0.0-alpha.58" + sitemap "^3.2.2" + +"@docusaurus/preset-classic@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-alpha.58.tgz#d7a48793aeca5a91bc10a04f9e99f861fea65171" + integrity sha512-XGXC5NcAkRUKpm4aho6moThPtLarGSouWW1xfYMQlT4dY6RG/FFt8n5viMXzGwOfA/H9B/s0sZpqHDw8U4FUCg== + dependencies: + "@docusaurus/plugin-content-blog" "^2.0.0-alpha.58" + "@docusaurus/plugin-content-docs" "^2.0.0-alpha.58" + "@docusaurus/plugin-content-pages" "^2.0.0-alpha.58" + "@docusaurus/plugin-debug" "^2.0.0-alpha.58" + "@docusaurus/plugin-google-analytics" "^2.0.0-alpha.58" + "@docusaurus/plugin-google-gtag" "^2.0.0-alpha.58" + "@docusaurus/plugin-sitemap" "^2.0.0-alpha.58" + "@docusaurus/theme-classic" "^2.0.0-alpha.58" + "@docusaurus/theme-search-algolia" "^2.0.0-alpha.58" + +"@docusaurus/theme-classic@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-alpha.58.tgz#698447fb6a634cdfc8a01f1a71ba4f24005265e4" + integrity sha512-GvpzpsL3jTxm/3sPna7wOJaAauCha+uLZ33x/XOMKrfN02E2BLkaRphRyCliw1vvLXB3rJPlHyvBdKCTOVXaNw== + dependencies: + "@mdx-js/mdx" "^1.5.8" + "@mdx-js/react" "^1.5.8" + clsx "^1.1.1" + copy-text-to-clipboard "^2.2.0" + infima "0.2.0-alpha.12" + parse-numeric-range "^0.0.2" + prism-react-renderer "^1.1.0" + prismjs "^1.20.0" + prop-types "^15.7.2" + react-router-dom "^5.1.2" + react-toggle "^4.1.1" + +"@docusaurus/theme-search-algolia@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-alpha.58.tgz#1686922a208003ca248635f74fe84158084fb4ed" + integrity sha512-Iug5mET733Yx46E04BfJjz4+AvxzalRo8G4ZmOjePTMiKQpE1ee39Ypbwj77c8XxEadOcZC4mJtfxB3L1RqlBA== + dependencies: + algoliasearch "^3.24.5" + algoliasearch-helper "^3.1.1" + clsx "^1.1.1" + docsearch.js "^2.6.3" + eta "^1.1.1" + +"@docusaurus/types@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-alpha.58.tgz#d7b0264e79549790c42d2781998b437bb573a294" + integrity sha512-OSkxoLwWJMhEHa4s6SXVCjfGwYm21yF6ZggoUo6kz+qqslTgF/JcPCVF9Y1Hf6bJJxUisi+ZHrHKEC6k4pphPA== + dependencies: + "@types/webpack" "^4.41.0" + commander "^4.0.1" + querystring "0.2.0" + +"@docusaurus/utils@^2.0.0-alpha.58": + version "2.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-alpha.58.tgz#9a7a43dcc6b7cb47228e0ca83c777402b5ee8c4a" + integrity sha512-hBhdQCyVT15mH7RE5yuDBuhwbUnM4beKq2JLvRuZS4FoNu7T2S4OGusUAtTnNZEruoUv2QTkt+GrsRDKYi2fCA== + dependencies: + escape-string-regexp "^2.0.0" + fs-extra "^8.1.0" + gray-matter "^4.0.2" + lodash.camelcase "^4.3.0" + lodash.kebabcase "^4.1.1" + +"@endiliey/lqip-loader@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@endiliey/lqip-loader/-/lqip-loader-3.0.2.tgz#00f4aebe7d4205b741f913644dee831a689f4fcc" + integrity sha512-Kx8te/ZrXR1EqNxBn4hfBHlVCCovm8Fu1fTpYjLSIvcGSEC2+OYFgT7dwPzvh7HyADhMl3lizOgtWbDhtM5djA== + dependencies: + loader-utils "^1.2.3" + lodash.sortby "^4.7.0" + node-vibrant "^3.1.4" + sharp "^0.22.1" + +"@endiliey/react-ideal-image@^0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@endiliey/react-ideal-image/-/react-ideal-image-0.0.11.tgz#dc3803d04e1409cf88efa4bba0f67667807bdf27" + integrity sha512-QxMjt/Gvur/gLxSoCy7VIyGGGrGmDN+VHcXkN3R2ApoWX0EYUE+hMgPHSW/PV6VVebZ1Nd4t2UnGRBDihu16JQ== + +"@endiliey/responsive-loader@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@endiliey/responsive-loader/-/responsive-loader-1.3.2.tgz#b9276747293b57c1ae9df59c6f5bec7624b157b7" + integrity sha512-j77koHZIW8L6s7kw/VdZhORamdP7laW4+Gcu7Ddt7iRSXniADDk9HtKUZrBXC90hMYo+Kb4XdlqMizvMI8JGrA== + dependencies: + loader-utils "^1.2.3" + +"@endiliey/static-site-generator-webpack-plugin@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@endiliey/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.0.tgz#94bfe58fd83aeda355de797fcb5112adaca3a6b1" + integrity sha512-3MBqYCs30qk1OBRC697NqhGouYbs71D1B8hrk/AFJC6GwF2QaJOQZtA1JYAaGSe650sZ8r5ppRTtCRXepDWlng== + dependencies: + bluebird "^3.7.1" + cheerio "^0.22.0" + eval "^0.1.4" + url "^0.11.0" + webpack-sources "^1.4.3" + +"@hapi/address@2.x.x": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== + +"@hapi/joi@^15.1.0": + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + +"@jimp/bmp@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.8.tgz#5933ab8fb359889bec380b0f7802163374933624" + integrity sha512-CZYQPEC3iUBMuaGWrtIG+GKNl93q/PkdudrCKJR/B96dfNngsmoosEm3LuFgJHEcJIfvnJkNqKw74l+zEiqCbg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + bmp-js "^0.1.0" + core-js "^3.4.1" + +"@jimp/core@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.9.8.tgz#b2b74263a80559c0ee244e0f2d1052b36a358b85" + integrity sha512-N4GCjcXb0QwR5GBABDK2xQ3cKyaF7LlCYeJEG9mV7G/ynBoRqJe4JA6YKU9Ww9imGkci/4A594nQo8tUIqdcBw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^3.4.1" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "^0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/custom@^0.9.3": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.9.8.tgz#1e9d904b1b05aa22b00b899baba2be7c0704a5d1" + integrity sha512-1UpJjI7fhX02BWLJ/KEqPwkHH60eNkCNeD6hEd+IZdTwLXfZCfFiM5BVlpgiZYZJSsVoRiAL4ne2Q5mCiKPKyw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/core" "^0.9.8" + core-js "^3.4.1" + +"@jimp/gif@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.9.8.tgz#513aff511634c338d1ab33a7bba1ba3412220b5b" + integrity sha512-LEbfpcO1sBJIQCJHchZjNlyNxzPjZQQ4X32klpQHZJG58n9FvL7Uuh1rpkrJRbqv3cU3P0ENNtTrsBDxsYwcfA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + omggif "^1.0.9" + +"@jimp/jpeg@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.9.8.tgz#8c086f69d0e8c46e43a7db9725576edc30925cb1" + integrity sha512-5u29SUzbZ32ZMmOaz3gO0hXatwSCnsvEAXRCKZoPPgbsPoyFAiZKVxjfLzjkeQF6awkvJ8hZni5chM15SNMg+g== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + jpeg-js "^0.3.4" + +"@jimp/plugin-resize@^0.9.3": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.9.8.tgz#eef750b77f1cc06e8bcf9b390860c95c489dcc02" + integrity sha512-L80NZ+HKsiKFyeDc6AfneC4+5XACrdL2vnyAVfAAsb3pmamgT/jDInWvvGhyI0Y76vx2w6XikplzEznW/QQvWg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/png@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.9.8.tgz#f88dacc9b9da1c2ea8e91026a9530d0fb45c4409" + integrity sha512-9CqR8d40zQCDhbnXHqcwkAMnvlV0vk9xSyE6LHjkYHS7x18Unsz5txQdsaEkEcXxCrOQSoWyITfLezlrWXRJAA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + pngjs "^3.3.3" + +"@jimp/tiff@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.9.8.tgz#91dc3eab2f222e23414f139e917f3407caa73560" + integrity sha512-eMxcpJivJqMByn2dZxUHLeh6qvVs5J/52kBF3TFa3C922OJ97D9l1C1h0WKUCBqFMWzMYapQQ4vwnLgpJ5tkow== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + utif "^2.0.1" + +"@jimp/types@^0.9.3": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.9.8.tgz#46980a4a7bfcadf2f0484d187c32b4e7d6d61b8e" + integrity sha512-H5y/uqt0lqJ/ZN8pWqFG+pv8jPAppMKkTMByuC8YBIjWSsornwv44hjiWl93sbYhduLZY8ubz/CbX9jH2X6EwA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/bmp" "^0.9.8" + "@jimp/gif" "^0.9.8" + "@jimp/jpeg" "^0.9.8" + "@jimp/png" "^0.9.8" + "@jimp/tiff" "^0.9.8" + core-js "^3.4.1" + timm "^1.6.1" + +"@jimp/utils@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.9.8.tgz#6a6f47158ec6b424f03df0f55f0baff5b4b5e096" + integrity sha512-UK0Fu0eevQlpRXq5ff4o/71HJlpX9wJMddJjMYg9vUqCCl8ZnumRAljfShHFhGyO+Vc9IzN6dd8Y5JZZTp1KOw== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + +"@mdx-js/mdx@^1.5.8": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.6.tgz#6e235f0ca47c8652f4c744cf7bc46a1015bcaeaa" + integrity sha512-Q1j/RtjNbRZRC/ciaOqQLplsJ9lb0jJhDSvkusmzCsCX+NZH7YTUvccWf7l6zKW1CAiofJfqZdZtXkeJUDZiMw== + dependencies: + "@babel/core" "7.9.6" + "@babel/plugin-syntax-jsx" "7.8.3" + "@babel/plugin-syntax-object-rest-spread" "7.8.3" + "@mdx-js/util" "^1.6.6" + babel-plugin-apply-mdx-type-prop "^1.6.6" + babel-plugin-extract-import-names "^1.6.6" + camelcase-css "2.0.1" + detab "2.0.3" + hast-util-raw "5.0.2" + lodash.uniq "4.5.0" + mdast-util-to-hast "9.1.0" + remark-footnotes "1.0.0" + remark-mdx "^1.6.6" + remark-parse "8.0.2" + remark-squeeze-paragraphs "4.0.0" + style-to-object "0.3.0" + unified "9.0.0" + unist-builder "2.0.3" + unist-util-visit "2.0.2" + +"@mdx-js/react@^1.5.8": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.6.tgz#71ece2a24261eed0e184c0ef9814fcb77b1a4aee" + integrity sha512-zOOdNreHUNSFQ0dg3wYYg9sOGg2csf7Sk8JGBigeBq+4Xk4LO0QdycGAmgKNfeme+SyBV5LBIPjt1NNsScyWEQ== + +"@mdx-js/util@^1.6.6": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.6.tgz#9c70eb7e7e4abc1083c8edf7151d35a19e442c00" + integrity sha512-PKTHVgMHnK5p+kcMWWNnZuoR7O19VmHiOujmVcyN50hya7qIdDb5vvsYC+dwLxApEXiABhLozq0dlIwFeS3yjg== + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" + integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== + +"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" + integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" + integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" + integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== + +"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" + integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== + +"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" + integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== + +"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" + integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== + +"@svgr/babel-plugin-transform-svg-component@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.4.0.tgz#a2212b4d018e6075a058bb7e220a66959ef7a03c" + integrity sha512-zLl4Fl3NvKxxjWNkqEcpdSOpQ3LGVH2BNFQ6vjaK6sFo2IrSznrhURIPI0HAphKiiIwNYjAfE0TNoQDSZv0U9A== + +"@svgr/babel-preset@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.4.0.tgz#da21854643e1c4ad2279239baa7d5a8b128c1f15" + integrity sha512-Gyx7cCxua04DBtyILTYdQxeO/pwfTBev6+eXTbVbxe4HTGhOUW6yo7PSbG2p6eJMl44j6XSequ0ZDP7bl0nu9A== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" + "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" + "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" + "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" + "@svgr/babel-plugin-transform-svg-component" "^5.4.0" + +"@svgr/core@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.4.0.tgz#655378ee43679eb94fee3d4e1976e38252dff8e7" + integrity sha512-hWGm1DCCvd4IEn7VgDUHYiC597lUYhFau2lwJBYpQWDirYLkX4OsXu9IslPgJ9UpP7wsw3n2Ffv9sW7SXJVfqQ== + dependencies: + "@svgr/plugin-jsx" "^5.4.0" + camelcase "^6.0.0" + cosmiconfig "^6.0.0" + +"@svgr/hast-util-to-babel-ast@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.4.0.tgz#bb5d002e428f510aa5b53ec0a02377a95b367715" + integrity sha512-+U0TZZpPsP2V1WvVhqAOSTk+N+CjYHdZx+x9UBa1eeeZDXwH8pt0CrQf2+SvRl/h2CAPRFkm+Ey96+jKP8Bsgg== + dependencies: + "@babel/types" "^7.9.5" + +"@svgr/plugin-jsx@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.4.0.tgz#ab47504c55615833c6db70fca2d7e489f509787c" + integrity sha512-SGzO4JZQ2HvGRKDzRga9YFSqOqaNrgLlQVaGvpZ2Iht2gwRp/tq+18Pvv9kS9ZqOMYgyix2LLxZMY1LOe9NPqw== + dependencies: + "@babel/core" "^7.7.5" + "@svgr/babel-preset" "^5.4.0" + "@svgr/hast-util-to-babel-ast" "^5.4.0" + svg-parser "^2.0.2" + +"@svgr/plugin-svgo@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.4.0.tgz#45d9800b7099a6f7b4d85ebac89ab9abe8592f64" + integrity sha512-3Cgv3aYi1l6SHyzArV9C36yo4kgwVdF3zPQUC6/aCDUeXAofDYwE5kk3e3oT5ZO2a0N3lB+lLGvipBG6lnG8EA== + dependencies: + cosmiconfig "^6.0.0" + merge-deep "^3.0.2" + svgo "^1.2.2" + +"@svgr/webpack@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.4.0.tgz#b68bc86e29cf007292b96ced65f80971175632e0" + integrity sha512-LjepnS/BSAvelnOnnzr6Gg0GcpLmnZ9ThGFK5WJtm1xOqdBE/1IACZU7MMdVzjyUkfFqGz87eRE4hFaSLiUwYg== + dependencies: + "@babel/core" "^7.9.0" + "@babel/plugin-transform-react-constant-elements" "^7.9.0" + "@babel/preset-env" "^7.9.5" + "@babel/preset-react" "^7.9.4" + "@svgr/core" "^5.4.0" + "@svgr/plugin-jsx" "^5.4.0" + "@svgr/plugin-svgo" "^5.4.0" + loader-utils "^2.0.0" + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/html-minifier-terser@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz#551a4589b6ee2cc9c1dff08056128aec29b94880" + integrity sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA== + +"@types/json-schema@^7.0.4": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" + integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== + +"@types/lodash@^4.14.53": + version "4.14.157" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.157.tgz#fdac1c52448861dfde1a2e1515dbc46e54926dc8" + integrity sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ== + +"@types/mdast@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" + integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw== + dependencies: + "@types/unist" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "14.0.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.19.tgz#994d99708822bca643a2364f8aeed04a16e0f5a1" + integrity sha512-yf3BP/NIXF37BjrK5klu//asUWitOEoUP5xE1mhSUjazotwJ/eJDgEmMQNlOeWOVv72j24QQ+3bqXHE++CFGag== + +"@types/node@^10.11.7": + version "10.17.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.26.tgz#a8a119960bff16b823be4c617da028570779bcfd" + integrity sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/q@^1.5.1": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" + integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*", "@types/tapable@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + +"@types/uglify-js@*": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.3.tgz#d94ed608e295bc5424c9600e6b8565407b6b4b6b" + integrity sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w== + dependencies: + source-map "^0.6.1" + +"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + +"@types/webpack-sources@*": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.0.tgz#e58f1f05f87d39a5c64cf85705bdbdbb94d4d57e" + integrity sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.41.0", "@types/webpack@^4.41.8": + version "4.41.21" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.21.tgz#cc685b332c33f153bb2f5fc1fa3ac8adeb592dee" + integrity sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" + integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== + +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +agentkeepalive@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" + integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= + +aggregate-error@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" + integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.1.tgz#b83ca89c5d42d69031f424cad49aada0236c6957" + integrity sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA== + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5: + version "6.12.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +algoliasearch-helper@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.1.2.tgz#f01cfed1ff3e4848ae9dc1ece31a4e7cbf65eeea" + integrity sha512-HfCVvmKH6+5OU9/SaHLdhvr39DBObA02z62RsfPhFDftzgQM6pJB2JoPyGpIteHW4RAYh8bPLiB8l4hajuy6fA== + dependencies: + events "^1.1.1" + +algoliasearch@^3.24.5: + version "3.35.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.35.1.tgz#297d15f534a3507cab2f5dfb996019cac7568f0c" + integrity sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +any-base@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" + integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autocomplete.js@0.36.0: + version "0.36.0" + resolved "https://registry.yarnpkg.com/autocomplete.js/-/autocomplete.js-0.36.0.tgz#94fe775fe64b6cd42e622d076dc7fd26bedd837b" + integrity sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q== + dependencies: + immediate "^3.2.3" + +autoprefixer@^9.6.1: + version "9.8.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.4.tgz#736f1012673a70fa3464671d78d41abd54512863" + integrity sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001087" + colorette "^1.2.0" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-loader@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-apply-mdx-type-prop@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.6.tgz#f72d7ff9f40620c51280a1acb4964c55bc07ba02" + integrity sha512-rUzVvkQa8/9M63OZT6qQQ1bS8P0ozhXp9e5uJ3RwRJF5Me7s4nZK5SYhyNHYc0BkAflWnCOGMP3oPQUfuyB8tg== + dependencies: + "@babel/helper-plugin-utils" "7.8.3" + "@mdx-js/util" "^1.6.6" + +babel-plugin-dynamic-import-node@^2.3.0, babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-extract-import-names@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.6.tgz#70e39a46f1b2a08fbd061336a322d1ddd81a2f44" + integrity sha512-UtMuiQJnhVPAGE2+pDe7Nc9NVEmDdqGTN74BtRALgH+7oag88RpxFLOSiA+u5mFkFg741wW9Ut5KiyJpksEj/g== + dependencies: + "@babel/helper-plugin-utils" "7.8.3" + +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" + integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.5.5, bluebird@^3.7.1: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +bn.js@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" + integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11" + integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.2" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" + integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== + dependencies: + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.378" + node-releases "^1.1.52" + pkg-up "^3.1.0" + +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.4, browserslist@^4.8.5: + version "4.13.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d" + integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ== + dependencies: + caniuse-lite "^1.0.30001093" + electron-to-chromium "^1.3.488" + escalade "^3.0.1" + node-releases "^1.1.58" + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.2.0, buffer@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2, cacache@^12.0.3: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cacache@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" + integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== + dependencies: + chownr "^1.1.2" + figgy-pudding "^3.5.1" + fs-minipass "^2.0.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + minipass "^3.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + p-map "^3.0.0" + promise-inflight "^1.0.1" + rimraf "^2.7.1" + ssri "^7.0.0" + unique-filename "^1.1.1" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + dependencies: + pascal-case "^3.1.1" + tslib "^1.10.0" + +camelcase-css@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" + integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001087, caniuse-lite@^1.0.30001093: + version "1.0.30001094" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001094.tgz#0b11d02e1cdc201348dbd8e3e57bd9b6ce82b175" + integrity sha512-ufHZNtMaDEuRBpTbqD93tIQnngmJ+oBknjvr0IbFympSdtFpAUFmNv4mVKbb53qltxFx0nK3iy32S9AqkLzUNA== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +ccount@^1.0.0, ccount@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" + integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + +cheerio@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.3.0, chokidar@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8" + integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1, chownr@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +ci-info@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +clipboard@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376" + integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg== + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-deep@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" + integrity sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY= + dependencies: + for-own "^0.1.3" + is-plain-object "^2.0.1" + kind-of "^3.0.2" + lazy-cache "^1.0.3" + shallow-clone "^0.1.2" + +clsx@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.0.0, color@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colorette@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + +commander@^2.18.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.1, commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +consola@^2.10.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.14.0.tgz#162ee903b6c9c4de25077d93f34ab902ebcb4dac" + integrity sha512-A2j1x4u8d6SIVikhZROfpFJxQZie+cZOfQMyI/tu2+hWXe8iAv7R6FW6s6x04/7zBCst94lPddztot/d6GJiuQ== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +"consolidated-events@^1.1.0 || ^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/consolidated-events/-/consolidated-events-2.0.2.tgz#da8d8f8c2b232831413d9e190dc11669c79f4a91" + integrity sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-text-to-clipboard@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-2.2.0.tgz#329dd6daf8c42034c763ace567418401764579ae" + integrity sha512-WRvoIdnTs1rgPMkgA2pUOa/M4Enh2uzCwdKsOMYNAJiz/4ZvEJgmbF4OmninPmlFdAWisfeh0tH+Cpf7ni3RqQ== + +copy-webpack-plugin@^5.0.5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz#5481a03dea1123d88a988c6ff8b78247214f0b88" + integrity sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg== + dependencies: + cacache "^12.0.3" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.1" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + webpack-log "^2.0.0" + +core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + dependencies: + browserslist "^4.8.5" + semver "7.0.0" + +core-js@^2.6.5: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + +core-js@^3.4.1: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@^3.4.2: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^1.1.0, css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +css-what@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" + integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + dependencies: + css-tree "1.0.0-alpha.39" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.1, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +del@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7" + integrity sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA== + dependencies: + globby "^10.0.1" + graceful-fs "^4.2.2" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.1" + p-map "^3.0.0" + rimraf "^3.0.0" + slash "^3.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detab@2.0.3, detab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.3.tgz#33e5dd74d230501bd69985a0d2b9a3382699a130" + integrity sha512-Up8P0clUVwq0FnFjDclzZsy9PadzRn5FFxrr47tQQvMHqyiFYVbpH8oXDzWtF0Q7pYy3l+RPmtBl+BsFF6wH0A== + dependencies: + repeat-string "^1.5.4" + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dir-glob@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +docsearch.js@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/docsearch.js/-/docsearch.js-2.6.3.tgz#57cb4600d3b6553c677e7cbbe6a734593e38625d" + integrity sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A== + dependencies: + algoliasearch "^3.24.5" + autocomplete.js "0.36.0" + hogan.js "^3.0.2" + request "^2.87.0" + stack-utils "^1.0.1" + to-factory "^1.0.0" + zepto "^1.2.0" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + +electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.488: + version "1.3.490" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.490.tgz#12aa776c493e66ba21536512fc317bdda6d04cd4" + integrity sha512-jKJF1mKXrQkT0ZiuJ/oV63Q02hAeWz0GGt/z6ryc518uCHtMyS9+wYAysZtBQ8rsjqFPAYXV4TIz5GQ8xyubPA== + +elliptic@^6.0.0, elliptic@^6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +"emoji-regex@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +emoticon@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-3.2.0.tgz#c008ca7d7620fac742fe1bf4af8ff8fed154ae7f" + integrity sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d" + integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + +envify@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" + integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== + dependencies: + esprima "^4.0.0" + through "~2.3.4" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^4.1.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +escalade@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.1.tgz#52568a77443f6927cd0ab9c73129137533c965ed" + integrity sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA== + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +eta@^1.1.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/eta/-/eta-1.2.2.tgz#9f182673738589281042641cb22f801dcabdf7bf" + integrity sha512-8H+zm3HfY2ELz5P4zzR3uJ1LQLnhTAe5gb0vR9ziKZGCLhQrRtqwIyzsOkf7pdBnH7gFPLRAaKZdv2nj9vu9cw== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eval@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.4.tgz#e05dbe0dab4b9330215cbb7bf4886eb24bd58700" + integrity sha512-npGsebJejyjMRnLdFu+T/97dnigqIU0Ov3IGrZ8ygd1v7RL1vGkEKtvyWZobqUH1AQgKlg0Yqqe2BtMA9/QZLw== + dependencies: + require-like ">= 0.1.1" + +eventemitter3@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^1.1.0, events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exif-parser@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +express@^4.16.3, express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^2.0.2: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-glob@^3.0.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastq@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" + integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +feed@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.1.tgz#b246ef891051c7dbf088ca203341d9fb0444baee" + integrity sha512-l28KKcK1J/u3iq5dRDmmoB2p7dtBfACC2NqJh4dI2kFptxH0asfjmOfcxqh5Sv8suAlVa73gZJ4REY5RrafVvg== + dependencies: + xml-js "^1.6.11" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-type@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" + integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filesize@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" + integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@4.1.0, find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.12.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" + integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +fork-ts-checker-webpack-plugin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-copy-file-sync@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" + integrity sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +github-slugger@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" + integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= + dependencies: + delegate "^3.1.2" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +gray-matter@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.2.tgz#9aa379e3acaf421193fce7d2a28cebd4518ac454" + integrity sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw== + dependencies: + js-yaml "^3.11.0" + kind-of "^6.0.2" + section-matter "^1.0.0" + strip-bom-string "^1.0.0" + +gzip-size@5.1.1, gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hast-to-hyperscript@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-7.0.4.tgz#7c4c037d9a8ea19b0a3fdb676a26448ad922353d" + integrity sha512-vmwriQ2H0RPS9ho4Kkbf3n3lY436QKLq6VaGA1pzBh36hBi3tm1DO9bR+kaJIbpT10UqaANDkMjxvjVfr+cnOA== + dependencies: + comma-separated-tokens "^1.0.0" + property-information "^5.3.0" + space-separated-tokens "^1.0.0" + style-to-object "^0.2.1" + unist-util-is "^3.0.0" + web-namespaces "^1.1.2" + +hast-util-from-parse5@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz#3089dc0ee2ccf6ec8bc416919b51a54a589e097c" + integrity sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA== + dependencies: + ccount "^1.0.3" + hastscript "^5.0.0" + property-information "^5.0.0" + web-namespaces "^1.1.2" + xtend "^4.0.1" + +hast-util-parse-selector@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz#60c99d0b519e12ab4ed32e58f150ec3f61ed1974" + integrity sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA== + +hast-util-raw@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-5.0.2.tgz#62288f311ec2f35e066a30d5e0277f963ad43a67" + integrity sha512-3ReYQcIHmzSgMq8UrDZHFL0oGlbuVGdLKs8s/Fe8BfHFAyZDrdv1fy/AGn+Fim8ZuvAHcJ61NQhVMtyfHviT/g== + dependencies: + hast-util-from-parse5 "^5.0.0" + hast-util-to-parse5 "^5.0.0" + html-void-elements "^1.0.0" + parse5 "^5.0.0" + unist-util-position "^3.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hast-util-to-parse5@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-5.1.2.tgz#09d27bee9ba9348ea05a6cfcc44e02f9083969b6" + integrity sha512-ZgYLJu9lYknMfsBY0rBV4TJn2xiwF1fXFFjbP6EE7S0s5mS8LIKBVWzhA1MeIs1SWW6GnnE4In6c3kPb+CWhog== + dependencies: + hast-to-hyperscript "^7.0.0" + property-information "^5.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hastscript@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" + integrity sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hogan.js@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/hogan.js/-/hogan.js-3.0.2.tgz#4cd9e1abd4294146e7679e41d7898732b02c7bfd" + integrity sha1-TNnhq9QpQUbnZ55B14mHMrAse/0= + dependencies: + mkdirp "0.3.0" + nopt "1.0.10" + +hoist-non-react-statics@^3.1.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-entities@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + +html-minifier-terser@^5.0.1, html-minifier-terser@^5.0.5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +html-tags@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" + integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== + +html-void-elements@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== + +html-webpack-plugin@^4.0.4: + version "4.3.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz#53bf8f6d696c4637d5b656d3d9863d89ce8174fd" + integrity sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +htmlparser2@^3.3.0, htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" + integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^5.1.1: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immer@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" + integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3, infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +infima@0.2.0-alpha.12: + version "0.2.0-alpha.12" + resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.12.tgz#6b4a0ba9756262e4f1af2c60feb4bc0ffd9b9e21" + integrity sha512-in5n36oE2sdiB/1rzuzdmKyuNRMVUO9P+qUidUG8leHeDU+WMQ7oTP7MXSqtAAxduiPb7HHi0/ptQLLUr/ge4w== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.5, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + +inquirer@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" + integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.2.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-alphabetical@1.0.4, is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.0.2, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-docker@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" + integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-cwd@^2.0.0, is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-path-inside@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" + integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== + dependencies: + has-symbols "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-whitespace-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-word-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jest-worker@^25.4.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" + integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jpeg-js@^0.3.4: + version "0.3.7" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" + integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.11.0, js-yaml@^3.13.1: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= + dependencies: + is-buffer "^1.0.2" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +lazy-cache@^0.2.3: + version "0.2.7" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" + integrity sha1-f+3fLctu23fRHvHRF6tf/fCrG2U= + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +load-bmfont@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9" + integrity sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA== + dependencies: + buffer-equal "0.0.1" + mime "^1.3.4" + parse-bmfont-ascii "^1.0.3" + parse-bmfont-binary "^1.0.5" + parse-bmfont-xml "^1.1.4" + phin "^2.9.1" + xhr "^2.0.1" + xtend "^4.0.0" + +load-script@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4" + integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ= + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.chunk@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" + integrity sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw= + +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= + +lodash.flatmap@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e" + integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4= + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + +lodash.groupby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1" + integrity sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E= + +lodash.has@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" + integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.4.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.padstart@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= + +lodash.pick@^4.2.1, lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash.pickby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" + integrity sha1-feoh2MGNdwOifHBMFdO4SmfjOv8= + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= + +lodash.some@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= + +lodash.uniq@4.5.0, lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +lodash@^4.17.4: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + +loglevel@^1.6.8: + version "1.6.8" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" + integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-escapes@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdast-squeeze-paragraphs@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" + integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== + dependencies: + unist-util-remove "^2.0.0" + +mdast-util-definitions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-3.0.1.tgz#06af6c49865fc63d6d7d30125569e2f7ae3d0a86" + integrity sha512-BAv2iUm/e6IK/b2/t+Fx69EL/AGcq/IG2S+HxHjDJGfLJtd6i9SZUS76aC9cig+IEucsqxKTR0ot3m933R3iuA== + dependencies: + unist-util-visit "^2.0.0" + +mdast-util-to-hast@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-9.1.0.tgz#6ef121dd3cd3b006bf8650b1b9454da0faf79ffe" + integrity sha512-Akl2Vi9y9cSdr19/Dfu58PVwifPXuFt1IrHe7l+Crme1KvgUT+5z+cHLVcQVGCiNTZZcdqjnuv9vPkGsqWytWA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.3" + collapse-white-space "^1.0.0" + detab "^2.0.0" + mdast-util-definitions "^3.0.0" + mdurl "^1.0.0" + trim-lines "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + +mdast-util-to-string@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + +mdurl@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-deep@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2" + integrity sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA== + dependencies: + arr-union "^3.1.0" + clone-deep "^0.2.4" + kind-of "^3.0.2" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3, merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0, mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.4.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" + integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +mini-create-react-context@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz#df60501c83151db69e28eac0ef08b4002efab040" + integrity sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA== + dependencies: + "@babel/runtime" "^7.5.5" + tiny-warning "^1.0.3" + +mini-css-extract-plugin@^0.8.0: + version "0.8.2" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.2.tgz#a875e169beb27c88af77dd962771c9eedc3da161" + integrity sha512-a3Y4of27Wz+mqK3qrcd3VhYz6cU0iW5x3Sgvqzbj+XmlrSizmvu8QQMl5oMYJjgHOC4iyt+w7l4umP+dQeW3bw== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz#55f7839307d74859d6e8ada9c3ebe72cec216a34" + integrity sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ== + dependencies: + minipass "^3.0.0" + +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1, nan@^2.13.2: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== + dependencies: + lower-case "^2.0.1" + tslib "^1.10.0" + +node-abi@^2.7.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.18.0.tgz#1f5486cfd7d38bd4f5392fa44a4ad4d9a0dffbf4" + integrity sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw== + dependencies: + semver "^5.4.1" + +node-emoji@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" + integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== + dependencies: + lodash.toarray "^4.4.0" + +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-releases@^1.1.52, node-releases@^1.1.58: + version "1.1.58" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935" + integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg== + +node-vibrant@^3.1.4: + version "3.1.5" + resolved "https://registry.yarnpkg.com/node-vibrant/-/node-vibrant-3.1.5.tgz#8729bf35aabd54cd2eccbfadf22124ab4e1305b0" + integrity sha512-Gk+iyBzPSN1SF5qL818QaBtuA38206Z8iPNa0PcLUPyIbZL4+i14VmYxkGCL0n/5Q1721CRSktqtACgkx7Qodg== + dependencies: + "@jimp/custom" "^0.9.3" + "@jimp/plugin-resize" "^0.9.3" + "@jimp/types" "^0.9.3" + "@types/lodash" "^4.14.53" + "@types/node" "^10.11.7" + lodash "^4.17.4" + url "^0.11.0" + +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + +nopt@1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nprogress@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= + +nth-check@^1.0.2, nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +null-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-3.0.0.tgz#3e2b6c663c5bda8c73a54357d8fa0708dc61b245" + integrity sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw== + dependencies: + loader-utils "^1.2.3" + schema-utils "^1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-is@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.0, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +omggif@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +open@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/open/-/open-7.0.4.tgz#c28a9d315e5c98340bf979fdcb2e58664aa10d83" + integrity sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimize-css-assets-webpack-plugin@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" + integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== + dependencies: + cssnano "^4.1.10" + last-call-webpack-plugin "^3.0.0" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@^1.0.5, pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= + +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" + integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-headers@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" + integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + +parse-numeric-range@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-0.0.2.tgz#b4f09d413c7adbcd987f6e9233c7b4b210c938e4" + integrity sha1-tPCdQTx6282Yf26SM8e0shDJOOQ= + +parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +phin@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" + integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pixelmatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= + dependencies: + pngjs "^3.0.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-up@3.1.0, pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +pngjs@^3.0.0, pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +pnp-webpack-plugin@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +portfinder@^1.0.25, portfinder@^1.0.26: + version "1.0.26" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-calc@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" + integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" + integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + dependencies: + postcss "^7.0.2" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-initial@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" + integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prebuild-install@^5.3.0: + version "5.3.5" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.5.tgz#e7e71e425298785ea9d22d4f958dbaccf8bb0e1b" + integrity sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp "^0.5.1" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +pretty-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +pretty-time@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" + integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== + +prism-react-renderer@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.1.1.tgz#1c1be61b1eb9446a146ca7a50b7bcf36f2a70a44" + integrity sha512-MgMhSdHuHymNRqD6KM3eGS0PNqgK9q4QF5P0yoQQvpB6jNjeSAi3jcSAz0Sua/t9fa4xDOMar9HJbLa08gl9ug== + +prismjs@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03" + integrity sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ== + optionalDependencies: + clipboard "^2.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.6.2, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +property-information@^5.0.0, property-information@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.5.0.tgz#4dc075d493061a82e2b7d096f406e076ed859943" + integrity sha512-RgEbCx2HLa1chNgvChcx+rrCWD0ctBmGSE0M7lVm1yyv4UbvbrWoXp/BkVLZefzjrRBGW8/Js6uh/BnlHXFyjA== + dependencies: + xtend "^4.0.0" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0, querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dev-utils@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" + integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== + dependencies: + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.10.0" + chalk "2.4.2" + cross-spawn "7.0.1" + detect-port-alt "1.1.6" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" + global-modules "2.0.0" + globby "8.0.2" + gzip-size "5.1.1" + immer "1.10.0" + inquirer "7.0.4" + is-root "2.1.0" + loader-utils "1.2.3" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.7" + recursive-readdir "2.2.2" + shell-quote "1.7.2" + strip-ansi "6.0.0" + text-table "0.2.0" + +react-dom@^16.8.4: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" + integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-error-overlay@^6.0.7: + version "6.0.7" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" + integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== + +react-fast-compare@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" + integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + +react-helmet@^6.0.0-beta: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726" + integrity sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw== + dependencies: + object-assign "^4.1.1" + prop-types "^15.7.2" + react-fast-compare "^3.1.1" + react-side-effect "^2.1.0" + +react-is@^16.6.0, react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-loadable-ssr-addon@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon/-/react-loadable-ssr-addon-0.2.3.tgz#55057abf95628d47727c68e966a6b3a53cde34e0" + integrity sha512-vPCqsmiafAMDcS9MLgXw3m4yMI40v1UeI8FTYJJkjf85LugKNnHf6D9yoDTzYwp8wEGF5viekwOD03ZPxSwnQQ== + +react-loadable@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.5.0.tgz#582251679d3da86c32aae2c8e689c59f1196d8c4" + integrity sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg== + dependencies: + prop-types "^15.5.0" + +react-router-config@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" + integrity sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg== + dependencies: + "@babel/runtime" "^7.1.2" + +react-router-dom@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" + integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.2.0, react-router@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" + integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-side-effect@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.0.tgz#1ce4a8b4445168c487ed24dab886421f74d380d3" + integrity sha512-IgmcegOSi5SNX+2Snh1vqmF0Vg/CbkycU9XZbOHJlZ6kMzTmi3yc254oB1WCkgA7OQtIAoLmcSFuHTc/tlcqXg== + +react-toggle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.1.1.tgz#2317f67bf918ea3508a96b09dd383efd9da572af" + integrity sha512-+wXlMcSpg8SmnIXauMaZiKpR+r2wp2gMUteroejp2UTSqGTVvZLN+m9EhMzFARBKEw7KpQOwzCyfzeHeAndQGw== + dependencies: + classnames "^2.2.5" + +react-waypoint@^9.0.2: + version "9.0.3" + resolved "https://registry.yarnpkg.com/react-waypoint/-/react-waypoint-9.0.3.tgz#176aa4686b33eb40d0d48d361c468f0367167958" + integrity sha512-NRmyjW8CUBNNl4WpvBqLDgBs18rFUsixeHVHrRrFlWTdOlWP7eiDjptqlR/cJAPLD6RwP5XFCm3bi9OiofN3nA== + dependencies: + consolidated-events "^1.1.0 || ^2.0.0" + prop-types "^15.0.0" + react-is "^16.6.3" + +react@^16.8.4: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" + integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + +reading-time@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.2.0.tgz#ced71c06715762f805506328dcc1fd45d8249ac4" + integrity sha512-5b4XmKK4MEss63y0Lw0vn0Zn6G5kiHP88mUnD8UeEsyORj3sh1ghTH0/u6m1Ax9G2F4wUZrknlp6WlIsCvoXVA== + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +reduce@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.2.tgz#0cd680ad3ffe0b060e57a5c68bdfce37168d361b" + integrity sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ== + dependencies: + object-keys "^1.1.0" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" + integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +rehype-parse@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.2.tgz#aeb3fdd68085f9f796f1d3137ae2b85a98406964" + integrity sha512-0S3CpvpTAgGmnz8kiCyFLGuW5yA4OQhyNTm/nwPopZ7+PI11WnGl1TTWTGv/2hPEe/g2jRLlhVVSsoDH8waRug== + dependencies: + hast-util-from-parse5 "^5.0.0" + parse5 "^5.0.0" + xtend "^4.0.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remark-admonitions@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/remark-admonitions/-/remark-admonitions-1.2.1.tgz#87caa1a442aa7b4c0cafa04798ed58a342307870" + integrity sha512-Ji6p68VDvD+H1oS95Fdx9Ar5WA2wcDA4kwrrhVU7fGctC6+d3uiMICu7w7/2Xld+lnU7/gi+432+rRbup5S8ow== + dependencies: + rehype-parse "^6.0.2" + unified "^8.4.2" + unist-util-visit "^2.0.1" + +remark-emoji@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.1.0.tgz#69165d1181b98a54ad5d9ef811003d53d7ebc7db" + integrity sha512-lDddGsxXURV01WS9WAiS9rO/cedO1pvr9tahtLhr6qCGFhHG4yZSJW3Ha4Nw9Uk1hLNmUBtPC0+m45Ms+xEitg== + dependencies: + emoticon "^3.2.0" + node-emoji "^1.10.0" + unist-util-visit "^2.0.2" + +remark-footnotes@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-1.0.0.tgz#9c7a97f9a89397858a50033373020b1ea2aad011" + integrity sha512-X9Ncj4cj3/CIvLI2Z9IobHtVi8FVdUrdJkCNaL9kdX8ohfsi18DXHsCVd/A7ssARBdccdDb5ODnt62WuEWaM/g== + +remark-mdx@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.6.tgz#6b5e9042ae0821cfa727ea05389d743696ce6996" + integrity sha512-BkR7SjP+3OvrCsWGlYy1tWEsZ8aQ86x+i7XWbW79g73Ws/cCaeVsEn0ZxAzzoTRH+PJWVU7Mbe64GdejEyKr2g== + dependencies: + "@babel/core" "7.9.6" + "@babel/helper-plugin-utils" "7.8.3" + "@babel/plugin-proposal-object-rest-spread" "7.9.6" + "@babel/plugin-syntax-jsx" "7.8.3" + "@mdx-js/util" "^1.6.6" + is-alphabetical "1.0.4" + remark-parse "8.0.2" + unified "9.0.0" + +remark-parse@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.2.tgz#5999bc0b9c2e3edc038800a64ff103d0890b318b" + integrity sha512-eMI6kMRjsAGpMXXBAywJwiwAse+KNpmt+BK55Oofy4KvBZEqUDj6mWbGLJZrujoPIPPxDXzn3T9baRlpsm2jnQ== + dependencies: + ccount "^1.0.0" + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^2.0.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^2.0.0" + vfile-location "^3.0.0" + xtend "^4.0.1" + +remark-squeeze-paragraphs@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" + integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== + dependencies: + mdast-squeeze-paragraphs "^4.0.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.4, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.87.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +"require-like@>= 0.1.1": + version "0.1.2" + resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" + integrity sha1-rW8wwTvs15cBDEaK+ndcDAprR/o= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.3.2, resolve@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + +rxjs@^6.5.3: + version "6.6.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84" + integrity sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.0.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +section-matter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== + dependencies: + extend-shallow "^2.0.1" + kind-of "^6.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= + +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== + dependencies: + node-forge "0.9.0" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serialize-javascript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" + integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-clone@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" + integrity sha1-WQnodLp3EG1zrEFM/sH/yofZcGA= + dependencies: + is-extendable "^0.1.1" + kind-of "^2.0.1" + lazy-cache "^0.2.3" + mixin-object "^2.0.1" + +sharp@^0.22.1: + version "0.22.1" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.22.1.tgz#a67c0e75567f03dd5a7861b901fec04072c5b0f4" + integrity sha512-lXzSk/FL5b/MpWrT1pQZneKe25stVjEbl6uhhJcTULm7PhmJgKKRbTDM/vtjyUuC/RLqL2PRyC4rpKwbv3soEw== + dependencies: + color "^3.1.1" + detect-libc "^1.0.3" + fs-copy-file-sync "^1.1.1" + nan "^2.13.2" + npmlog "^4.1.2" + prebuild-install "^5.3.0" + semver "^6.0.0" + simple-get "^3.0.3" + tar "^4.4.8" + tunnel-agent "^0.6.0" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shelljs@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sitemap@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-3.2.2.tgz#3f77c358fa97b555c879e457098e39910095c62b" + integrity sha512-TModL/WU4m2q/mQcrDgNANn0P4LwprM9MMvG4hu5zP4c6IIKs2YLTu6nXXnNr8ODW/WFtxKggiJ1EGn2W0GNmg== + dependencies: + lodash.chunk "^4.2.0" + lodash.padstart "^4.6.1" + whatwg-url "^7.0.0" + xmlbuilder "^13.0.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.20: + version "0.3.20" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" + integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.4.0" + websocket-driver "0.6.5" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +ssri@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" + integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== + dependencies: + figgy-pudding "^3.5.1" + minipass "^3.1.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +state-toggle@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +std-env@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.2.1.tgz#2ffa0fdc9e2263e0004c1211966e960948a40f6b" + integrity sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ== + dependencies: + ci-info "^1.6.0" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-to-object@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== + dependencies: + inline-style-parser "0.1.1" + +style-to-object@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.2.3.tgz#afcf42bc03846b1e311880c55632a26ad2780bcb" + integrity sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng== + dependencies: + inline-style-parser "0.1.1" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +svg-parser@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.0.0, svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar-fs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5" + integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.3.tgz#1e2022559221b7866161660f118255e20fa79e41" + integrity sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^4.4.8: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +terser-webpack-plugin@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" + integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser-webpack-plugin@^2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.7.tgz#4910ff5d1a872168cc7fa6cd3749e2b0d60a8a0b" + integrity sha512-xzYyaHUNhzgaAdBsXxk2Yvo/x1NJdslUaussK3fdpBbvttm1iIwU+c26dj9UxJcwk2c5UWt5F55MUTIA8BE7Dg== + dependencies: + cacache "^13.0.1" + find-cache-dir "^3.3.1" + jest-worker "^25.4.0" + p-limit "^2.3.0" + schema-utils "^2.6.6" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.6.12" + webpack-sources "^1.4.3" + +terser@^4.1.2, terser@^4.6.12, terser@^4.6.3: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@0.2.0, text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6, through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timm@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" + integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tiny-emitter@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-factory@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-factory/-/to-factory-1.0.0.tgz#8738af8bd97120ad1d4047972ada5563bf9479b1" + integrity sha1-hzivi9lxIK0dQEeXKtpVY7+UebE= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-lines@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.3.tgz#839514be82428fd9e7ec89e35081afe8f6f93115" + integrity sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA== + +trim-trailing-lines@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz#7f0739881ff76657b7776e10874128004b625a94" + integrity sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tslib@^1.10.0, tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +unherit@^1.0.4: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== + dependencies: + inherits "^2.0.0" + xtend "^4.0.0" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +unified@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.0.0.tgz#12b099f97ee8b36792dbad13d278ee2f696eed1d" + integrity sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + +unified@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" + integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unist-builder@2.0.3, unist-builder@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== + +unist-util-generated@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.5.tgz#1e903e68467931ebfaea386dae9ea253628acd42" + integrity sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw== + +unist-util-is@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" + integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== + +unist-util-is@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.2.tgz#c7d1341188aa9ce5b3cff538958de9895f14a5de" + integrity sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ== + +unist-util-position@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== + +unist-util-remove-position@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" + integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== + dependencies: + unist-util-visit "^2.0.0" + +unist-util-remove@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.0.0.tgz#32c2ad5578802f2ca62ab808173d505b2c898488" + integrity sha512-HwwWyNHKkeg/eXRnE11IpzY8JT55JNM1YCwwU9YNCnfzk6s8GhPXrVBBZWiwLeATJbI7euvoGSzcy9M29UeW3g== + dependencies: + unist-util-is "^4.0.0" + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-visit-parents@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz#d4076af3011739c71d2ce99d05de37d545f4351d" + integrity sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@2.0.2, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.2.tgz#3843782a517de3d2357b4c193b24af2d9366afb7" + integrity sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utif@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" + integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== + dependencies: + pako "^1.0.5" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vfile-location@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.0.1.tgz#d78677c3546de0f7cd977544c367266764d31bb3" + integrity sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ== + +vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.1.1.tgz#282d28cebb609183ac51703001bc18b3e3f17de9" + integrity sha512-lRjkpyDGjVlBA7cDQhQ+gNcvB1BGaTHYuSOcY3S7OhDmBtnzX95FhtZZDecSTDm6aajFymyve6S5DN4ZHGezdQ== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + replace-ext "1.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +wait-file@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/wait-file/-/wait-file-1.0.5.tgz#377f48795f1765046a41bb0671c142ef8e509ae6" + integrity sha512-udLpJY/eOxlrMm3+XD1RLuF2oT9B7J7wiyR5/9xrvQymS6YR6trWvVhzOldHrVbLwyiRmLj9fcvsjzpSXeZHkw== + dependencies: + "@hapi/joi" "^15.1.0" + fs-extra "^8.1.0" + rx "^4.1.0" + +watchpack-chokidar2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" + integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa" + integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.0" + watchpack-chokidar2 "^2.0.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +web-namespaces@^1.0.0, web-namespaces@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-bundle-analyzer@^3.6.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz#ce6b3f908daf069fd1f7266f692cbb3bded9ba16" + integrity sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" + integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.20" + sockjs-client "1.4.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.41.2: + version "4.43.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" + integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.1" + webpack-sources "^1.4.1" + +webpackbar@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-4.0.0.tgz#ee7a87f16077505b5720551af413c8ecd5b1f780" + integrity sha512-k1qRoSL/3BVuINzngj09nIwreD8wxV4grcuhHTD8VJgUbGcy8lQSPqv+bM00B7F+PffwIsQ8ISd4mIwRbr23eQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + consola "^2.10.0" + figures "^3.0.0" + pretty-time "^1.1.0" + std-env "^2.2.1" + text-table "^0.2.0" + wrap-ansi "^6.0.0" + +websocket-driver@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= + dependencies: + websocket-extensions ">=0.1.1" + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^6.0.0, ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + dependencies: + sax "^1.2.4" + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= + +xml2js@^0.4.5: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@^13.0.0: + version "13.0.2" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7" + integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ== + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.7.2: + version "1.10.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +zepto@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98" + integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g= + +zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== diff --git a/sdk/python/.flake8 b/sdk/python/.flake8 new file mode 100644 index 00000000..670212d6 --- /dev/null +++ b/sdk/python/.flake8 @@ -0,0 +1,12 @@ +[flake8] +max-line-length = 88 +exclude = + .git, + __pycache__, + build, + dist, + tests/pg2_testsuite/ + approzium/_protos/ + setup.py +extend-ignore = + E203 diff --git a/sdk/python/Makefile b/sdk/python/Makefile new file mode 100644 index 00000000..eaa6a5ce --- /dev/null +++ b/sdk/python/Makefile @@ -0,0 +1,23 @@ +deps: + python3 -m grpc_tools.protoc -I../../authenticator/server/protos --python_out=approzium/_protos --grpc_python_out=approzium/_protos ../../authenticator/server/protos/authenticator.proto + +download_psycopg2_testsuite: + $(eval TMP := $(shell mktemp -d)) + git clone https://github.com/psycopg/psycopg2.git $(TMP) + mkdir -p tests/pg2_testsuite/ + mv -f $(TMP)/tests/* tests/pg2_testsuite/ + rm -rf $(TMP) + +# To run the test suite, first set the environment variables: +# - TEST_IAM_ROLE +# - PSYCOPG2_TESTDB +# - PSYCOPG2_TESTDB_HOST +# - PSYCOPG2_TESTDB_PORT +# - PSYCOPG2_TESTDB_USER=bob +# You can automate setting setting up the test database servers and environment +# variables using docker-compose by running `make test-e2e` in the project root +# directory. +test: download_psycopg2_testsuite + pip3 install -e . + cd tests && python3 run_pg2_testsuite.py + rm -rf tests/pg2_testsuite/ diff --git a/sdk/python/README.md b/sdk/python/README.md new file mode 100644 index 00000000..e92e18a7 --- /dev/null +++ b/sdk/python/README.md @@ -0,0 +1 @@ +# Approzium SDK for Python diff --git a/sdk/python/approzium/__init__.py b/sdk/python/approzium/__init__.py new file mode 100644 index 00000000..e562eaf9 --- /dev/null +++ b/sdk/python/approzium/__init__.py @@ -0,0 +1,19 @@ +import logging + +from ._authenticator import AuthClient, TLSConfig + +default_auth_client = None +""" +Set this variable to an instance of :class:`~approzium.AuthClient` to set it as +the default auth client to be used for connections. +""" + +logger = logging.getLogger(__name__) +log_format = "[%(filename)s:%(lineno)s - %(funcName)10s() ] %(message)s" +formatter = logging.Formatter(log_format) +ch = logging.StreamHandler() +ch.setFormatter(formatter) +logger.addHandler(ch) + + +__all__ = ["default_auth_client", "AuthClient", "TLSConfig"] diff --git a/sdk/python/approzium/_authenticator.py b/sdk/python/approzium/_authenticator.py new file mode 100644 index 00000000..5afe84f7 --- /dev/null +++ b/sdk/python/approzium/_authenticator.py @@ -0,0 +1,236 @@ +# needed to be able to import protos code +import json +import sys +from datetime import datetime, timedelta +from itertools import count +from pathlib import Path + +import grpc + +from . import _mysql, _postgres +from ._iam import ( + assume_role, + get_local_arn, + obtain_claimed_arn, + obtain_credentials, + obtain_signed_get_caller_identity, +) + +sys.path.append(str(Path(__file__).parent / "_protos")) # isort:skip +import authenticator_pb2 # noqa: E402 isort:skip +import authenticator_pb2_grpc # noqa: E402 isort:skip + + +class AuthClient(object): + """This class represents a connection to an Approzium authenticator + service. Instances of this class can be used as arguments to database + drivers connect method to use for authentication. + + :param server_address: address (host:port) at which an authenticator + service is listening. + :type server_address: str + + :param disable_tls: defaults to False. When False, https is used and a + client_cert and client_key proving the client's identity must be + provided. When True, http is used and no other TLS options must be + set. + :type disable_tls: bool, optional + + :param tls_config: the TLS config to use for encrypted communication. + :type tls_config: TLSConfig, optional + + :param iam_role: if an IAM role Amazon resource number (ARN) is provided, + it will be assumed and its identity will be used for authentication. + Otherwise, the default ``boto3`` session will be used as the identity. + :type iam_role: str, optional + """ + + def __init__( + self, server_address, disable_tls=False, tls_config=None, iam_role=None, + ): + self.server_address = server_address + + if not disable_tls: + if tls_config is None: + raise ValueError("if tls is not disabled, tls config must be provided") + if tls_config.client_cert is None or tls_config.client_key is None: + raise ValueError( + "if tls is not disabled, " + "client_cert and client_key must be provided" + ) + + self.disable_tls = disable_tls + self.tls_config = TLSConfig( + trusted_certs=tls_config.trusted_certs, + client_cert=tls_config.client_cert, + client_key=tls_config.client_key, + ) + self.authenticated = False + self._counter = count(1) + self.n_conns = 0 + + # Parse the claimed ARN once because it'll never change. + # Parse the signed_gci at startup, and then we'll update + # it every 5 minutes because it expires every 15. + if iam_role is None: + claimed_arn = get_local_arn() + signed_gci = obtain_signed_get_caller_identity(None) + else: + response = assume_role(iam_role) + credentials = obtain_credentials(response) + claimed_arn = obtain_claimed_arn(response) + signed_gci = obtain_signed_get_caller_identity(credentials) + + self.claimed_arn = claimed_arn + self.signed_gci = signed_gci + self.signed_gci_last_updated = datetime.utcnow() + + @property + def attribution_info(self): + """Provides a dictionary containing information about the current state + of the AuthClient. Useful for logging. + + :rtype: dict + + **Return Structure**: + - *authenticator_address* (*str*): address of authenticator service used + - *iam_arn* (*str*): IAM Amazon resource number (ARN) used as identity + - *authenticated* (*bool*): whether the AuthClient was verified by the + authenticator service. + - *num_connections* (*int*): number of connections made through this + AuthClient + """ + info = {} + info["authenticator_address"] = self.server_address + info["iam_arn"] = self.claimed_arn + info["authenticated"] = self.authenticated + info["num_connections"] = self.n_conns + return info + + @property + def attribution_info_json(self): + """Provides the same attribution info returned by + :func:`~AuthClient.attribution_info` as a JSON format string + + :rtype: str + """ + info = self.attribution_info + return json.dumps(info) + + def _execute_request(self, request, getmethodname, dbhost, dbport, dbuser): + # The presigned GetCallerIdentity call expires every 15 minutes. + self._update_gci_if_needed() + + if self.disable_tls: + channel = grpc.insecure_channel(self.server_address) + else: + credentials = grpc.ssl_channel_credentials( + root_certificates=_read_file(self.tls_config.trusted_certs), + certificate_chain=_read_file(self.tls_config.client_cert), + private_key=_read_file(self.tls_config.client_key), + ) + channel = grpc.secure_channel(self.server_address, credentials) + + stub = authenticator_pb2_grpc.AuthenticatorStub(channel) + # authentication info + aws_identity = authenticator_pb2.AWSIdentity( + signed_get_caller_identity=self.signed_gci, + claimed_iam_arn=self.claimed_arn, + ) + password_request = authenticator_pb2.PasswordRequest( + aws=aws_identity, + client_language=authenticator_pb2.PYTHON, + dbhost=dbhost, + dbport=dbport, + dbuser=dbuser, + ) + request.pwd_request.CopyFrom(password_request) + response = getattr(stub, getmethodname)(request) + # if no exception is raised, request was successful + self.authenticated = True + self.n_conns = next(self._counter) + return response + + def _get_pg2_hash(self, dbhost, dbport, dbuser, auth_type, auth_info): + if auth_type == _postgres.AUTH_REQ_MD5: + salt = auth_info + if len(salt) != 4: + raise Exception("salt not right size") + request = authenticator_pb2.PGMD5HashRequest(salt=salt,) + response = self._execute_request( + request, "GetPGMD5Hash", dbhost, dbport, dbuser + ) + return response.hash + elif auth_type == _postgres.AUTH_REQ_SASL: + auth = auth_info + auth._generate_auth_msg() + request = authenticator_pb2.PGSHA256HashRequest( + salt=auth.password_salt, + iterations=auth.password_iterations, + authentication_msg=auth.authorization_message, + ) + response = self._execute_request( + request, "GetPGSHA256Hash", dbhost, dbport, dbuser + ) + client_final = auth.create_client_final_message(response.cproof) + auth.server_signature = response.sproof + return client_final, auth + + def _get_mysql_hash(self, dbhost, dbport, dbuser, auth_type, auth_info): + if auth_type == _mysql.MYSQLNativePassword: + salt = auth_info + if len(salt) != 20: + raise Exception("salt not right size") + request = authenticator_pb2.MYSQLSHA1HashRequest(salt=salt,) + response = self._execute_request( + request, "GetMYSQLSHA1Hash", dbhost, dbport, dbuser + ) + return response.hash + else: + raise Exception("Unexpected authentication method") + + # The presigned GetCallerIdentity string expires every 15 minuts, so refresh it + # after 5 minutes just to be safe. + def _update_gci_if_needed(self): + if datetime.utcnow() - self.signed_gci_last_updated < timedelta(minutes=5): + return + if self.iam_role is None: + self.signed_gci = obtain_signed_get_caller_identity(None) + self.signed_gci_last_updated = datetime.utcnow() + else: + response = assume_role(self.iam_role) + credentials = obtain_credentials(response) + self.signed_gci = obtain_signed_get_caller_identity(credentials) + self.signed_gci_last_updated = datetime.utcnow() + + +class TLSConfig(object): + """This class represents the TLS config to be used while communicating + with Approzium. Its fields are further described here: + https://grpc.github.io/grpc/python/grpc.html#create-client-credentials + + :param trusted_certs: the path to the root certificate(s) that must have + issued the identity certificate used by Approzium's authentication + server. + :type trusted_certs: str, optional + + :param client_cert: this client's certificate, used for proving its + identity, and used by the caller to encrypt communication with + its public key + :type client_cert: str, optional + + :param client_key: this client's key, used for decrypting incoming + communication that was encrypted by callers using the client_cert's + public key + :type client_key: str, optional + """ + + def __init__(self, trusted_certs=None, client_cert=None, client_key=None): + self.trusted_certs = trusted_certs + self.client_cert = client_cert + self.client_key = client_key + + +def _read_file(path_to_file): + with open(path_to_file, "rb") as f: + return f.read() diff --git a/sdk/python/approzium/_iam.py b/sdk/python/approzium/_iam.py new file mode 100644 index 00000000..29692169 --- /dev/null +++ b/sdk/python/approzium/_iam.py @@ -0,0 +1,38 @@ +import boto3 + + +def assume_role(iam_role): + sts_client = boto3.client("sts") + response = sts_client.assume_role( + DurationSeconds=3600, RoleArn=iam_role, RoleSessionName="Service1", + ) + return response + + +def obtain_credentials(response): + return response["Credentials"] + + +def obtain_claimed_arn(response): + return response["AssumedRoleUser"]["Arn"] + + +def obtain_signed_get_caller_identity(credentials=None): + if credentials is None: + # Attempt to use local identity through the boto3 client. + sts_client = boto3.client("sts") + else: + sts_session = boto3.Session( + aws_access_key_id=credentials["AccessKeyId"], + aws_secret_access_key=credentials["SecretAccessKey"], + aws_session_token=credentials["SessionToken"], + ) + sts_client = sts_session.client("sts") + presigned_url = sts_client.generate_presigned_url("get_caller_identity", {}) + return presigned_url + + +def get_local_arn(): + sts_client = boto3.client("sts") + response = sts_client.get_caller_identity() + return response["Arn"] diff --git a/sdk/python/approzium/_misc.py b/sdk/python/approzium/_misc.py new file mode 100644 index 00000000..2c016f8f --- /dev/null +++ b/sdk/python/approzium/_misc.py @@ -0,0 +1,9 @@ +import logging +import struct + +logger = logging.getLogger(__name__) + + +def read_int32_from_bytes(bytes, index): + num = struct.unpack("!i", bytes[index : index + 4])[0] + return num diff --git a/sdk/python/approzium/_mysql/__init__.py b/sdk/python/approzium/_mysql/__init__.py new file mode 100644 index 00000000..f862f4f0 --- /dev/null +++ b/sdk/python/approzium/_mysql/__init__.py @@ -0,0 +1,17 @@ +import struct + +MYSQLNativePassword = "mysql_native_password" + + +def get_auth_resp( + authenticator, dbhost, dbport, dbuser, auth_plugin, auth_data, is_secure_connection +): + plugin_auth_response = authenticator._get_mysql_hash( + dbhost, dbport, dbuser, auth_plugin, auth_data + ) + if is_secure_connection: + resplen = len(plugin_auth_response) + auth_response = struct.pack(">> import approzium + >>> import asyncio + >>> from approzium.asyncpg import connect + >>> auth = approzium.AuthClient("myauthenticator.com:6001") + >>> async def run(): + ... con = await connect(user='postgres', authenticator=auth) + ... # use the connection just like any other Asyncpg connection + ... types = await con.fetch('SELECT * FROM pg_type') + ... print(types) + >>> asyncio.get_event_loop().run_until_complete(run()) + """ + if authenticator is None: + authenticator = approzium.default_auth_client + conn = await asyncpg.connect( + *args, **kwargs, connection_class=construct_approzium_connection(authenticator) + ) + return conn diff --git a/sdk/python/approzium/asyncpg/pool.py b/sdk/python/approzium/asyncpg/pool.py new file mode 100644 index 00000000..15faef25 --- /dev/null +++ b/sdk/python/approzium/asyncpg/pool.py @@ -0,0 +1,104 @@ +import asyncio + +import asyncpg +from asyncpg.connection import Connection + +from ._asyncpg_connect import connect, new__connect_addr # approzium's connect method + + +class _ApproziumPool(asyncpg.pool.Pool): + async def _get_new_connection(self): + if self._working_addr is None: + # First connection attempt on this pool. + # 1) use our connect method instead of asyncpg's + con = await connect( + *self._connect_args, loop=self._loop, **self._connect_kwargs + ) + + self._working_addr = con._addr + self._working_config = con._config + self._working_params = con._params + # 2) after first connection, store class instance because it + # contains authenticator + self._connection_class = con.__class__ + + else: + # We've connected before and have a resolved address, + # and parsed options and config. + + # 3) use our own _connect_addr instead of asyncpg's + con = await new__connect_addr( + loop=self._loop, + addr=self._working_addr, + timeout=self._working_params.connect_timeout, + config=self._working_config, + params=self._working_params, + connection_class=self._connection_class, + ) + + if self._init is not None: + try: + await self._init(con) + except (Exception, asyncio.CancelledError) as ex: + # If a user-defined `init` function fails, we don't + # know if the connection is safe for re-use, hence + # we close it. A new connection will be created + # when `acquire` is called again. + try: + # Use `close()` to close the connection gracefully. + # An exception in `init` isn't necessarily caused + # by an IO or a protocol error. close() will + # do the necessary cleanup via _release_on_close(). + await con.close() + finally: + raise ex + + return con + + +def create_pool( + dsn=None, + *, + min_size=10, + max_size=10, + max_queries=50000, + max_inactive_connection_lifetime=300.0, + setup=None, + init=None, + loop=None, + authenticator=None, + **connect_kwargs, +): + """Create an Asyncpg connection pool through Approzium authentication. + Takes same arguments as ``asyncpg.create_pool`` in addition to the + `authenticator` argument + + :return: An instance of :class:`~approzium.asyncpg.pool._ApproziumPool`. + + Example: + + .. code-block:: python + + >>> import approzium + >>> from approzium.asyncpg import create_pool + >>> auth = approzium.AuthClient("myauthenticator.com:6001") + >>> pool = await create_pool(user='postgres', authenticator=auth) + >>> con = await pool.acquire() + >>> try: + ... await con.fetch('SELECT 1') + ... finally: + ... await pool.release(con) + """ + return _ApproziumPool( + dsn, + connection_class=Connection, + min_size=min_size, + max_size=max_size, + max_queries=max_queries, + loop=loop, + setup=setup, + init=init, + max_inactive_connection_lifetime=max_inactive_connection_lifetime, + authenticator=authenticator, + **connect_kwargs, + ) diff --git a/sdk/python/approzium/mysql/__init__.py b/sdk/python/approzium/mysql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sdk/python/approzium/mysql/connector/__init__.py b/sdk/python/approzium/mysql/connector/__init__.py new file mode 100644 index 00000000..cbdf0804 --- /dev/null +++ b/sdk/python/approzium/mysql/connector/__init__.py @@ -0,0 +1,3 @@ +from ._connect import connect + +__all__ = ["connect"] diff --git a/sdk/python/approzium/mysql/connector/_connect.py b/sdk/python/approzium/mysql/connector/_connect.py new file mode 100644 index 00000000..2a610cc1 --- /dev/null +++ b/sdk/python/approzium/mysql/connector/_connect.py @@ -0,0 +1,113 @@ +from contextlib import contextmanager + +import mysql.connector +from mysql.connector import MySQLConnection + +import approzium + +from ..._mysql import get_auth_resp + + +class ApproziumMySQLConnection(MySQLConnection): + def _do_auth(self, *args, **kwargs): + if self._password.__class__.__name__ == "AuthClient": + + def _auth_response( + client_flags, + username, + password, + database, + auth_plugin, + auth_data, + ssl_enabled, + ): + authenticator = password + is_secure_connection = ( + client_flags + & mysql.connector.constants.ClientFlag.SECURE_CONNECTION + ) + auth_response = get_auth_resp( + authenticator, + host, + str(port), + username, + auth_plugin, + auth_data, + is_secure_connection, + ) + return auth_response + + host = self.server_host + port = self.server_port + self._protocol._auth_response = _auth_response + + return super(ApproziumMySQLConnection, self)._do_auth(*args, **kwargs) + + +@contextmanager +def _patch_MySQLConnection(include_pooling=False): + mysql.connector.MySQLConnection = ApproziumMySQLConnection + if include_pooling: + mysql.connector.pooling.MySQLConnection = ApproziumMySQLConnection + try: + yield + finally: + mysql.connector.MySQLConnection = MySQLConnection + if include_pooling: + mysql.connector.pooling.MySQLConnection = MySQLConnection + + +def _parse_kwargs(kwargs): + authenticator = kwargs.pop("authenticator", None) + if authenticator is None: + authenticator = approzium.default_auth_client + if authenticator is None: + raise TypeError("Auth client not specified and no default auth client is set") + kwargs["password"] = authenticator + use_pure = kwargs.get("use_pure", False) + if not use_pure: + msg = "MySQL C-Extension based connection is not currently supported.\ +Pass use_pure=True" + raise NotImplementedError(msg) + return kwargs + + +def connect(*args, authenticator=None, **kwargs): + """Creates a MySQL connector connection through Approzium authentication. Takes + the same arguments as ``mysql.connector.connect``, in addition to the + authenticator argument. + + :param authenticator: AuthClient instance to be used for authentication. If + not provided, the default AuthClient, if set, is used. + :type authenticator: approzium.AuthClient, optional + :raises: TypeError, if no AuthClient is given and no default one is set. + :rtype: ``mysql.connector.MySQLConnection`` + + Example: + + .. code-block:: python + + >>> import approzium + >>> from approzium.mysql.connector import connect + >>> auth = approzium.AuthClient("myauthenticator.com:6001") + >>> con = connect(user="bob", host="host.com", authenticator=auth, \ + ... use_pure=True) + >>> # use the connection just like any other MySQL connector connection + + .. warning:: + Currently, only the pure Python MySQL connector implementation is + supported. Therefore, you have to pass in ``use_pure=True``, otherwise, + an exception is raised. + + .. note: + Currently, only secure password authentication using + `mysql_native_password` is supported. For more details, read MySQL's + `documentation`_ + + .. _documentation: + https://dev.mysql.com/doc/internals/en/secure-password-authentication.html + """ + kwargs = _parse_kwargs({"authenticator": authenticator, **kwargs}) + with _patch_MySQLConnection(): + conn = mysql.connector.connect(*args, **kwargs) + return conn diff --git a/sdk/python/approzium/mysql/connector/pooling.py b/sdk/python/approzium/mysql/connector/pooling.py new file mode 100644 index 00000000..d2c143ba --- /dev/null +++ b/sdk/python/approzium/mysql/connector/pooling.py @@ -0,0 +1,13 @@ +from mysql.connector.pooling import MySQLConnectionPool + +from ._connect import _parse_kwargs, _patch_MySQLConnection + + +class MySQLConnectionPool(MySQLConnectionPool): + def set_config(self, **kwargs): + kwargs = _parse_kwargs(kwargs) + super(MySQLConnectionPool, self).set_config(**kwargs) + + def add_connection(self, cnx=None): + with _patch_MySQLConnection(include_pooling=True): + super().add_connection(cnx) diff --git a/sdk/python/approzium/psycopg2/__init__.py b/sdk/python/approzium/psycopg2/__init__.py new file mode 100644 index 00000000..36314fbf --- /dev/null +++ b/sdk/python/approzium/psycopg2/__init__.py @@ -0,0 +1,3 @@ +from ._psycopg2_connect import connect + +__all__ = ["connect"] diff --git a/sdk/python/approzium/psycopg2/_psycopg2_connect.py b/sdk/python/approzium/psycopg2/_psycopg2_connect.py new file mode 100644 index 00000000..40179ada --- /dev/null +++ b/sdk/python/approzium/psycopg2/_psycopg2_connect.py @@ -0,0 +1,121 @@ +import logging +import select + +import psycopg2 + +import approzium + +from .._postgres import PGAuthClient +from ._psycopg2_ctypes import ( + ensure_compatible_ssl, + libpq_PQstatus, + read_msg, + set_connection_sync, + set_debug, + write_msg, +) + +logger = logging.getLogger(__name__) + +pgconnect = psycopg2.connect + + +def wait(pgconn): + while True: + state = pgconn.poll() + if state == psycopg2.extensions.POLL_OK: + break + elif state == psycopg2.extensions.POLL_WRITE: + select.select([], [pgconn.fileno()], []) + elif state == psycopg2.extensions.POLL_READ: + select.select([pgconn.fileno()], [], []) + else: + raise psycopg2.OperationalError("poll() returned %s" % state) + + +def construct_approzium_conn(is_sync, authenticator): + class ApproziumConn(psycopg2.extensions.connection): + CONNECTION_AWAITING_RESPONSE = 4 + + def __init__(self, *args, **kwargs): + logger.debug("ApproziumConn __init__") + kwargs.pop("async", None) + kwargs.pop("async_", None) + super().__init__(*args, **kwargs, async_=1) + if self.dsn is None: + # connection is uninitalized due to an error + return + if logger.getEffectiveLevel() <= logging.DEBUG: + set_debug(self) + dbhost = self.get_dsn_parameters()["host"] + dbport = self.get_dsn_parameters()["port"] + dbuser = self.get_dsn_parameters()["user"] + self._pgauthclient = PGAuthClient( + lambda: read_msg(self), + lambda msg: write_msg(self, msg), + authenticator, + dbhost, + dbport, + dbuser, + ) + self._checked_ssl = False + if is_sync: + wait(self) + set_connection_sync(self) + self.autocommit = False + + def poll(self): + status = libpq_PQstatus(self.pgconn_ptr) + if self.info.ssl_in_use and not self._checked_ssl: + ensure_compatible_ssl(self) + logging.debug("checked ssl") + self._checked_ssl = True + if ( + status == self.CONNECTION_AWAITING_RESPONSE + and not self._pgauthclient.done + ): + next(self._pgauthclient) + return psycopg2.extensions.POLL_WRITE + else: + logging.debug("normal poll") + return super().poll() + + return ApproziumConn + + +def connect(dsn=None, cursor_factory=None, authenticator=None, **kwargs): + """Creates a Psycopg2 connection through Approzium authentication. Takes + the same arguments as ``psycopg2.connect``, in addition to the + authenticator argument. + + :param authenticator: AuthClient instance to be used for authentication. If + not provided, the default AuthClient, if set, is used. + :type authenticator: approzium.AuthClient, optional + :raises: TypeError, if no AuthClient is given and no default one is set. + :rtype: ``psycopg2.Connection`` + + Example: + + .. code-block:: python + + >>> import approzium + >>> from approzium.psycopg2 import connect + >>> auth = approzium.AuthClient("myauthenticator.com:6001") + >>> con = connect("host=DB.com dbname=mydb", authenticator=auth) # no password! + >>> # use the connection just like any other Psycopg2 connection + + .. warning:: + Currently, only `psycopg2` with dynamically linked `libpq` is + supported. Thus, `psycopg2-binary` is not supported. + """ + is_sync = True + if kwargs.get("async", False): + is_sync = False + if kwargs.get("async_", False): + is_sync = False + if authenticator is None: + authenticator = approzium.default_auth_client + if authenticator is None: + raise TypeError("Auth client not specified and not default auth client is set") + factory = construct_approzium_conn(is_sync, authenticator) + return pgconnect(dsn, factory, cursor_factory, **kwargs) diff --git a/sdk/python/approzium/psycopg2/_psycopg2_ctypes.py b/sdk/python/approzium/psycopg2/_psycopg2_ctypes.py new file mode 100644 index 00000000..ed2a41e5 --- /dev/null +++ b/sdk/python/approzium/psycopg2/_psycopg2_ctypes.py @@ -0,0 +1,141 @@ +import logging +import select +import struct +import warnings +from ctypes import ( + CDLL, + c_char_p, + c_int, + c_void_p, + cdll, + create_string_buffer, + memmove, + string_at, +) +from ctypes.util import find_library +from sys import getsizeof + +from .._socketfromfd import fromfd + +logger = logging.getLogger(__name__) + +libpq = cdll.LoadLibrary(find_library("pq")) +libssl = cdll.LoadLibrary(find_library("ssl")) + + +# setup ctypes functions +# necessary to avoid segfaults when using multiple Python threads +libpq_PQstatus = libpq.PQstatus +libpq_PQstatus.argtypes = [c_void_p] +libpq_PQstatus.restype = c_int + +libpq_PQsslInUse = libpq.PQsslInUse +libpq_PQsslInUse.argtypes = [c_void_p] +libpq_PQsslInUse.restype = c_int + +libpq_PQgetssl = libpq.PQgetssl +libpq_PQgetssl.argtypes = [c_void_p] +libpq_PQgetssl.restype = c_void_p + +libpq_PQsetnonblocking = libpq.PQsetnonblocking +libpq_PQsetnonblocking.argtypes = [c_void_p, c_int] +libpq_PQsetnonblocking.restype = c_int + +libssl_SSL_read = libssl.SSL_read +libssl_SSL_read.argtypes = [c_void_p, c_char_p, c_int] +libssl_SSL_read.restype = c_int + +libssl_SSL_write = libssl.SSL_write +libssl_SSL_write.argtypes = [c_void_p, c_char_p, c_int] +libssl_SSL_write.restype = c_int + + +def set_connection_sync(pgconn): + mem = bytearray(string_at(id(pgconn), getsizeof(pgconn))) + sizeofint = struct.calcsize("@i") + sizeoflong = struct.calcsize("@l") + + def addressofint(number, mem=mem): + int_bytes = struct.pack("@i", number) + return mem.find(int_bytes) + + def intataddress(address): + return struct.unpack("@i", mem[address : address + sizeofint])[0] + + def ensure(check): + if not check: + raise Exception("Could not set connection to sync. Unidentified struct") + + # as a check, we check server and protocol version numbers, which succeed + # the async value in the psycopg connection struct + server_version_addr = addressofint(pgconn.server_version) + # check that there is only one match for that value + ensure( + addressofint(pgconn.server_version, mem[server_version_addr + sizeofint :]) + == -1 + ) + protocol_address = server_version_addr - sizeofint + protocol_version = intataddress(protocol_address) + ensure(protocol_version == pgconn.protocol_version) + async_address = protocol_address - sizeoflong + async_value = struct.unpack("@l", mem[async_address:protocol_address])[0] + ensure(async_value == pgconn.async_) + new_async_value = struct.pack("@l", 0) + memmove(id(pgconn) + async_address, new_async_value, sizeoflong) + ensure(pgconn.async_ == 0) + error = libpq_PQsetnonblocking(pgconn.pgconn_ptr, 0) + ensure(error == 0) + + +def read_msg(pgconn): + def read_bytes(n): + if pgconn.info.ssl_in_use: + buffer = bytearray(n) + c_buffer = create_string_buffer(bytes(buffer), n) + ssl_obj = libpq_PQgetssl(pgconn.pgconn_ptr) + nread = -1 + while nread == -1: + nread = libssl_SSL_read(ssl_obj, c_buffer, n) + msg = bytes(c_buffer.raw[:nread]) + return msg + else: + fd = pgconn.fileno() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", ResourceWarning) + sock = fromfd(fd) + return sock.recv(n) + + select.select([pgconn.fileno()], [], []) + msg_type = read_bytes(1) + msg_size_b = read_bytes(4) + msg_size = struct.unpack("!i", msg_size_b)[0] + msg_content = read_bytes(msg_size - 4) + logger.debug(f"read: {msg_type} {msg_content}") + return msg_type + msg_size_b + msg_content + + +def write_msg(pgconn, msg): + select.select([], [pgconn.fileno()], []) + if libpq_PQsslInUse(pgconn.pgconn_ptr): + ssl_obj = libpq_PQgetssl(pgconn.pgconn_ptr) + c_buffer = create_string_buffer(msg, len(msg)) + n = libssl_SSL_write(ssl_obj, c_buffer, len(msg)) + if n != len(msg): + raise ValueError("could not send response") + else: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", ResourceWarning) + sock = fromfd(pgconn.fileno(), keep_fd=True) + sock.sendall(msg) + logger.debug(f"sent: {msg}") + + +def set_debug(conn): + libc = CDLL(find_library("c")) + stdout = c_void_p.in_dll(libc, "stdout") + libpq.PQtrace(conn.pgconn_ptr, stdout) + + +def ensure_compatible_ssl(conn): + if conn.info.ssl_attribute("library") != "OpenSSL": + raise Exception("Unsupported SSL library") diff --git a/sdk/python/approzium/psycopg2/pool.py b/sdk/python/approzium/psycopg2/pool.py new file mode 100644 index 00000000..da70c902 --- /dev/null +++ b/sdk/python/approzium/psycopg2/pool.py @@ -0,0 +1,41 @@ +import psycopg2.pool + +from . import connect + + +class _AbstractConnectionPool(psycopg2.pool.AbstractConnectionPool): + def _connect(self, key=None): + # originally, this line uses psycopg2.connect. we change it to use our + # connect method instead + conn = connect(*self._args, **self._kwargs) + if key is not None: + self._used[key] = conn + self._rused[id(conn)] = key + else: + self._pool.append(conn) + return conn + + +class SimpleConnectionPool(_AbstractConnectionPool, psycopg2.pool.SimpleConnectionPool): + """A Psycopg2 pool that can't be shared across different threads. + + Example: + + .. code-block:: python + + >>> import approzium + >>> from approzium.psycopg2.pool import SimpleConnectionPool + >>> auth = approzium.AuthClient("myauthenticator.com:6001") + >>> pool = SimpleConnectionPool("host=DB.com dbname=mydb", authenticator=auth) + >>> conn = poll.getconn() + """ + + pass + + +class ThreadedConnectionPool( + _AbstractConnectionPool, psycopg2.pool.ThreadedConnectionPool +): + """A Psycopg2 pool that works with the threading module""" + + pass diff --git a/sdk/python/docs/Makefile b/sdk/python/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/sdk/python/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/sdk/python/docs/make.bat b/sdk/python/docs/make.bat new file mode 100644 index 00000000..6247f7e2 --- /dev/null +++ b/sdk/python/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/sdk/python/docs/source/api.rst b/sdk/python/docs/source/api.rst new file mode 100644 index 00000000..4824a230 --- /dev/null +++ b/sdk/python/docs/source/api.rst @@ -0,0 +1,48 @@ +AuthClient +---------- + +.. automodule:: approzium + :members: + :undoc-members: + :show-inheritance: + + +approzium.psycopg2 +------------------ + +.. automodule:: approzium.psycopg2 + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: approzium.psycopg2.pool + :members: + :undoc-members: + :show-inheritance: + +approzium.asyncpg +----------------- + +.. automodule:: approzium.asyncpg + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: approzium.asyncpg.pool + :members: + :undoc-members: + :show-inheritance: + +approzium.mysql.connector +------------------------- + + +.. automodule:: approzium.mysql.connector + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: approzium.mysql.connector.pooling + :members: + :undoc-members: + :show-inheritance: diff --git a/sdk/python/docs/source/conf.py b/sdk/python/docs/source/conf.py new file mode 100644 index 00000000..80a3ba03 --- /dev/null +++ b/sdk/python/docs/source/conf.py @@ -0,0 +1,56 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +sys.path.insert(0, os.path.abspath("../../")) + + +# -- Project information ----------------------------------------------------- + +project = "Approzium Python SDK" +copyright = "2020, Cyral" +author = "Cyral" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ["sphinx.ext.autodoc", "sphinx_rtd_theme"] + +autodoc_mock_imports = ["ctypes"] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +master_doc = "index" + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] diff --git a/sdk/python/docs/source/examples.rst b/sdk/python/docs/source/examples.rst new file mode 100644 index 00000000..8b5e2f6f --- /dev/null +++ b/sdk/python/docs/source/examples.rst @@ -0,0 +1,29 @@ +If any example is broken, or if you’d like to add an example to this page, feel free to raise an issue on our Github repository. + +Postgres Examples +----------------- + +Example of creating a Psycopg2 single connection and a connection pool + +:file:`psycopg2_connect.py`: + +.. literalinclude:: ../../examples/psycopg2_connect.py + :language: python + +Example of creating a Asyncpg single connection and a connection pool + +:file:`asyncpg_connect.py`: + +.. literalinclude:: ../../examples/asyncpg_connect.py + :language: python + + +MySQL Examples +-------------- + +Example of creating a MySQL Connector single connection and a connection pool + +:file:`mysql_connector_connect.py`: + +.. literalinclude:: ../../examples/mysql_connector_connect.py + :language: python diff --git a/sdk/python/docs/source/index.rst b/sdk/python/docs/source/index.rst new file mode 100644 index 00000000..9b20489a --- /dev/null +++ b/sdk/python/docs/source/index.rst @@ -0,0 +1,53 @@ +.. Approzium SDK documentation master file, created by + sphinx-quickstart on Thu Jun 25 20:59:53 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Approzium Python SDK's documentation! +================================================ + +This is the Python SDK for Approzium_ (identity-based credential-less authentication to databases). Currently, there is support for Psycopg2 and Asyncpg (both for Postgres) as database drivers, but support for more database drivers is planned. Check out our roadmap_ for more details. + +Approzium Python SDK is implemented as thin wrappers that integrate with existing Python database drivers, resulting in being extremely easy to use. It creates the same database connection objects that you are using, so you don't have to change your existing code! + +Currently, it supports Python 3.5+ and AWS-based identity. + +.. _Approzium: https://approzium.org/ +.. _roadmap: https://approzium.org/src-pages-roadmap + + +Contents +======== + +.. toctree:: + :maxdepth: 5 + :caption: User Guide + + userguide + +.. toctree:: + :caption: API Reference + :maxdepth: 7 + + api + +.. toctree:: + :caption: Examples + :maxdepth: 7 + + examples + +.. toctree:: + :caption: Other Links + + Approzium General Documentation + Github + Slack (#help-and-questions) + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/sdk/python/docs/source/userguide.rst b/sdk/python/docs/source/userguide.rst new file mode 100644 index 00000000..90ebbec1 --- /dev/null +++ b/sdk/python/docs/source/userguide.rst @@ -0,0 +1,64 @@ +Installation +------------ + +The last stable release is available on PyPI and can be installed with ``pip``:: + + $ python3 -m pip install approzium + +Requirements +------------ + +* CPython_ >= 3.5 + +.. _CPython: http://www.python.org/ + +Supported Database Drivers +-------------------------- + + +The following database driver libraries are supported: + + + +------------+--------------------+----------------------------------------------------------+-------------------------------------------------------------+ + | Database | Driver | Authentication Methods | Notes | + +============+====================+==========================================================+=============================================================+ + | Postgres | Psycopg2_ | MD5 (Postgres default) and SCRAM-SHA-256 authentication | | + +------------+--------------------+----------------------------------------------------------+-------------------------------------------------------------+ + | Postgres | Asyncpg_ | Same as above | | + +------------+--------------------+----------------------------------------------------------+-------------------------------------------------------------+ + | MySQL | `MySQL Connector`_ | `Native password authentication`_ | Currently, only the pure Python implementation is supported | + +------------+--------------------+----------------------------------------------------------+-------------------------------------------------------------+ + +.. _Psycopg2: https://github.com/psycopg/psycopg2 +.. _Asyncpg: https://github.com/MagicStack/asyncpg +.. _MySQL Connector: https://dev.mysql.com/doc/connector-python/en/ +.. _Native password authentication: https://dev.mysql.com/doc/refman/8.0/en/native-pluggable-authentication.html + + +Usage +----- + +Approzium Python SDK is designed to have a small footprint on the source code of your application. + +1. The first step in creating an Approzium database connection is instantiating an :class:`approzium.AuthClient`: + + .. code-block:: python + + import approzium + auth = approzium.AuthClient("authenticator_service_host:port") + +2. By default, the AuthClient automatically detects the environment that the service is running in. Currently, only AWS-based IAM identity is supported, so it will detect that. + +3. Set this auth client to be the default one: + + .. code-block:: python + + approzium.default_auth_client = auth + +4. Create a connection! The way you create a connection is extremely similar to existing code. All you have to do is prepend ``approzium.`` to the import path. For example, if you are creating a Psycopg2 connection, instead of ``psycopg2.connect`` you would use ``approzium.psycopg2.connect``. It's that easy! + + .. code-block:: python + + from approzium.psycopg2 import connect + conn = connect(dbname="test", user="postgres", host="host.com") + # conn is now a psycopg2.Connection object diff --git a/sdk/python/examples/asyncpg_connect.py b/sdk/python/examples/asyncpg_connect.py new file mode 100644 index 00000000..54023508 --- /dev/null +++ b/sdk/python/examples/asyncpg_connect.py @@ -0,0 +1,27 @@ +import asyncio + +from approzium import AuthClient +from approzium.asyncpg import connect +from approzium.asyncpg.pool import create_pool + +auth = AuthClient( + "authenticator:6001", + # This is insecure, see https://approzium.org/configuration for proper use. + disable_tls=True, +) + + +async def run(): + conn = await connect(user="bob", database="db", host="host", authenticator=auth) + print("Connection Established!") + await conn.fetch("""SELECT 1""") + await conn.close() + + pool = await create_pool(user="bob", database="db", host="host", authenticator=auth) + print("Connection Established!") + async with pool.acquire() as conn: + await conn.fetch("""SELECT 1""") + + +loop = asyncio.get_event_loop() +loop.run_until_complete(run()) diff --git a/sdk/python/examples/mysql_connector_connect.py b/sdk/python/examples/mysql_connector_connect.py new file mode 100644 index 00000000..0e1e2412 --- /dev/null +++ b/sdk/python/examples/mysql_connector_connect.py @@ -0,0 +1,25 @@ +from approzium import AuthClient +from approzium.mysql.connector import connect +from approzium.mysql.connector.pooling import MySQLConnectionPool + +auth = AuthClient( + "authenticator:6001", + # This is insecure, see https://approzium.org/configuration for proper use. + disable_tls=True, +) +conn = connect(user="bob", authenticator=auth, host="dbmysql", use_pure=True) +print("Connection Established") + +cur = conn.cursor() +cur.execute("SELECT 1") +result = next(cur) +print(result) + +cnxpool = MySQLConnectionPool( + pool_name="mypool", pool_size=3, user="bob", host="dbmysql", authenticator=auth +) +print("Connection Pool Established") +conn = cnxpool.get_connection() +cur = conn.cursor() +cur.execute("SELECT 1") +print(result) diff --git a/sdk/python/examples/psycopg2_connect.py b/sdk/python/examples/psycopg2_connect.py new file mode 100644 index 00000000..2971e431 --- /dev/null +++ b/sdk/python/examples/psycopg2_connect.py @@ -0,0 +1,16 @@ +from approzium import AuthClient +from approzium.psycopg2 import connect +from approzium.psycopg2.pool import ThreadedConnectionPool + +auth = AuthClient( + "authenticator:6001", + # This is insecure, see https://approzium.org/configuration for proper use. + disable_tls=True, +) +dsn = "host=dbmd5 dbname=db user=bob" +conn = connect(dsn, authenticator=auth) +print("Connection Established") + +conns = ThreadedConnectionPool(1, 5, dsn) +conn = conns.getconn() +print("Connection Pool Established") diff --git a/sdk/python/poetry.lock b/sdk/python/poetry.lock new file mode 100644 index 00000000..0727ddbd --- /dev/null +++ b/sdk/python/poetry.lock @@ -0,0 +1,628 @@ +[[package]] +category = "dev" +description = "Async generators and context managers for Python 3.5+" +marker = "python_version == \"3.5\"" +name = "async-generator" +optional = false +python-versions = ">=3.5" +version = "1.10" + +[[package]] +category = "main" +description = "An asyncio PostgreSQL driver" +name = "asyncpg" +optional = true +python-versions = ">=3.5.0" +version = "0.20.1" + +[package.extras] +dev = ["Cython (0.29.14)", "pytest (>=3.6.0)", "Sphinx (>=1.7.3,<1.8.0)", "sphinxcontrib-asyncio (>=0.2.0,<0.3.0)", "sphinx-rtd-theme (>=0.2.4,<0.3.0)", "pycodestyle (>=2.5.0,<2.6.0)", "flake8 (>=3.7.9,<3.8.0)", "uvloop (>=0.14.0,<0.15.0)"] +docs = ["Sphinx (>=1.7.3,<1.8.0)", "sphinxcontrib-asyncio (>=0.2.0,<0.3.0)", "sphinx-rtd-theme (>=0.2.4,<0.3.0)"] +test = ["pycodestyle (>=2.5.0,<2.6.0)", "flake8 (>=3.7.9,<3.8.0)", "uvloop (>=0.14.0,<0.15.0)"] + +[[package]] +category = "dev" +description = "Atomic file writes." +marker = "sys_platform == \"win32\"" +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.4.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[package.extras] +azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] +dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] +docs = ["sphinx", "zope.interface"] +tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] + +[[package]] +category = "main" +description = "The AWS SDK for Python" +name = "boto3" +optional = false +python-versions = "*" +version = "1.14.16" + +[package.dependencies] +botocore = ">=1.17.16,<1.18.0" +jmespath = ">=0.7.1,<1.0.0" +s3transfer = ">=0.3.0,<0.4.0" + +[[package]] +category = "main" +description = "Low-level, data-driven core of boto 3." +name = "botocore" +optional = false +python-versions = "*" +version = "1.17.16" + +[package.dependencies] +docutils = ">=0.10,<0.16" +jmespath = ">=0.7.1,<1.0.0" +python-dateutil = ">=2.1,<3.0.0" + +[package.dependencies.urllib3] +python = "<3.4.0 || >=3.5.0" +version = ">=1.20,<1.26" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.4.3" + +[[package]] +category = "main" +description = "Docutils -- Python Documentation Utilities" +name = "docutils" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "0.15.2" + +[[package]] +category = "main" +description = "HTTP/2-based RPC framework" +name = "grpcio" +optional = false +python-versions = "*" +version = "1.30.0" + +[package.dependencies] +six = ">=1.5.2" + +[[package]] +category = "main" +description = "Protobuf code generator for gRPC" +name = "grpcio-tools" +optional = false +python-versions = "*" +version = "1.30.0" + +[package.dependencies] +grpcio = ">=1.30.0" +protobuf = ">=3.5.0.post1" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "1.7.0" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] + +[[package]] +category = "main" +description = "JSON Matching Expressions" +name = "jmespath" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "0.10.0" + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.5" +version = "8.4.0" + +[[package]] +category = "main" +description = "MySQL driver written in Python" +name = "mysql-connector-python" +optional = true +python-versions = "*" +version = "8.0.20" + +[package.dependencies] +protobuf = ">=3.0.0" + +[package.extras] +dns-srv = ["dnspython (>=1.16.0)"] + +[[package]] +category = "dev" +description = "Core utilities for Python packages" +name = "packaging" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.4" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +category = "dev" +description = "Object-oriented filesystem paths" +marker = "python_version < \"3.6\"" +name = "pathlib2" +optional = false +python-versions = "*" +version = "2.3.5" + +[package.dependencies] +six = "*" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" + +[package.dependencies] +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +category = "main" +description = "Protocol Buffers" +name = "protobuf" +optional = false +python-versions = "*" +version = "3.12.2" + +[package.dependencies] +setuptools = "*" +six = ">=1.9" + +[[package]] +category = "main" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +name = "psycopg2" +optional = true +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "2.8.5" + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.9.0" + +[[package]] +category = "dev" +description = "Python parsing module" +name = "pyparsing" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.7" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=3.5" +version = "5.4.3" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.dependencies.pathlib2] +python = "<3.6" +version = ">=2.2.0" + +[package.extras] +checkqa-mypy = ["mypy (v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +category = "dev" +description = "Pytest support for asyncio." +name = "pytest-asyncio" +optional = false +python-versions = ">= 3.5" +version = "0.14.0" + +[package.dependencies] +pytest = ">=5.4.0" + +[package.dependencies.async-generator] +python = ">=3.5,<3.6" +version = ">=1.3" + +[package.extras] +testing = ["async-generator (>=1.3)", "coverage", "hypothesis (>=5.7.1)"] + +[[package]] +category = "dev" +description = "a pytest plugin for parallel and concurrent testing" +name = "pytest-parallel" +optional = false +python-versions = "*" +version = "0.1.0" + +[package.dependencies] +pytest = ">=3.0.0" +tblib = "*" + +[[package]] +category = "main" +description = "Extensions to the standard Python datetime module" +name = "python-dateutil" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +version = "2.8.1" + +[package.dependencies] +six = ">=1.5" + +[[package]] +category = "main" +description = "An Amazon S3 Transfer Manager" +name = "s3transfer" +optional = false +python-versions = "*" +version = "0.3.3" + +[package.dependencies] +botocore = ">=1.12.36,<2.0a.0" + +[[package]] +category = "main" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.15.0" + +[[package]] +category = "dev" +description = "Traceback serialization library." +name = "tblib" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "1.6.0" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +marker = "python_version != \"3.4\"" +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.25.9" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + +[[package]] +category = "dev" +description = "Measures the displayed width of unicode strings in a terminal" +name = "wcwidth" +optional = false +python-versions = "*" +version = "0.2.5" + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" +optional = false +python-versions = ">=2.7" +version = "1.2.0" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"] + +[extras] +sqllibs = ["psycopg2", "asyncpg", "mysql-connector-python"] + +[metadata] +content-hash = "9652524954528695df8a20fb993f7577bbb3d5b571f99def3add4b158cc62938" +python-versions = "^3.5" + +[metadata.files] +async-generator = [ + {file = "async_generator-1.10-py3-none-any.whl", hash = "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b"}, + {file = "async_generator-1.10.tar.gz", hash = "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144"}, +] +asyncpg = [ + {file = "asyncpg-0.20.1-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:f7184689177eeb5a11fa1b2baf3f6f2e26bfd7a85acf4de1a3adbd0867d7c0e2"}, + {file = "asyncpg-0.20.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:f0c9719ac00615f097fe91082b785bce36dbf02a5ec4115ede0ebfd2cd9500cb"}, + {file = "asyncpg-0.20.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1388caa456070dab102be874205e3ae8fd1de2577d5de9fa22e65ba5c0f8b110"}, + {file = "asyncpg-0.20.1-cp35-cp35m-win32.whl", hash = "sha256:ec6e7046c98730cb2ba4df41387e10cb8963a3ac2918f69ae416f8aab9ca7b1b"}, + {file = "asyncpg-0.20.1-cp35-cp35m-win_amd64.whl", hash = "sha256:25edb0b947eb632b6b53e5a4b36cba5677297bb34cbaba270019714d0a5fed76"}, + {file = "asyncpg-0.20.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:95cd2df61ee00b789bdcd04a080e6d9188693b841db2bf9a87ebaed9e53147e0"}, + {file = "asyncpg-0.20.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:058baec9d6b75612412baa872a1aa47317d0ff88c318a49f9c4a2389043d5a8d"}, + {file = "asyncpg-0.20.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c773c7dbe2f4d3ebc9e3030e94303e45d6742e6c2fc25da0c46a56ea3d83caeb"}, + {file = "asyncpg-0.20.1-cp36-cp36m-win32.whl", hash = "sha256:5664d1bd8abe64fc60a0e701eb85fa1d8c9a4a8018a5a59164d27238f2caf395"}, + {file = "asyncpg-0.20.1-cp36-cp36m-win_amd64.whl", hash = "sha256:57666dfae38f4dbf84ffbf0c5c0f78733fef0e8e083230275dcb9ccad1d5ee09"}, + {file = "asyncpg-0.20.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:0c336903c3b08e970f8af2f606332f1738dba156bca83ed0467dc2f5c70da796"}, + {file = "asyncpg-0.20.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ad5ba062e09673b1a4b8d0facaf5a6d9719bf7b337440d10b07fe994d90a9552"}, + {file = "asyncpg-0.20.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba90d3578bc6dddcbce461875672fd9bdb34f0b8215b68612dd3b65a956ff51c"}, + {file = "asyncpg-0.20.1-cp37-cp37m-win32.whl", hash = "sha256:da238592235717419a6a7b5edc8564da410ebfd056ca4ecc41e70b1b5df86fba"}, + {file = "asyncpg-0.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:74510234c294c6a6767089ba9c938f09a491426c24405634eb357bd91dffd734"}, + {file = "asyncpg-0.20.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:391aea89871df8c1560750af6c7170f2772c2d133b34772acf3637e3cf4db93e"}, + {file = "asyncpg-0.20.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a981500bf6947926e53c48f4d60ae080af1b4ad7fa78e363465a5b5ad4f2b65e"}, + {file = "asyncpg-0.20.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a9e6fd6f0f9e8bd77e9a4e1ef9a4f83a80674d9136a754ae3603e915da96b627"}, + {file = "asyncpg-0.20.1-cp38-cp38-win32.whl", hash = "sha256:e39aac2b3a2f839ce65aa255ce416de899c58b7d38d601d24ca35558e13b48e3"}, + {file = "asyncpg-0.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:2af6a5a705accd36e13292ea43d08c20b15e52d684beb522cb3a7d3c9c8f3f48"}, + {file = "asyncpg-0.20.1.tar.gz", hash = "sha256:394bf19bdddbba07a38cd6fb526ebf66e120444d6b3097332b78efd5b26495b0"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, + {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, +] +boto3 = [ + {file = "boto3-1.14.16-py2.py3-none-any.whl", hash = "sha256:c2a223f4b48782e8b160b2130265e2a66081df111f630a5a384d6909e29a5aa9"}, + {file = "boto3-1.14.16.tar.gz", hash = "sha256:ce5a4ab6af9e993d1864209cbbb6f4812f65fbc57ad6b95e5967d8bf38b1dcfb"}, +] +botocore = [ + {file = "botocore-1.17.16-py2.py3-none-any.whl", hash = "sha256:99d995ef99cf77458a661f3fc64e0c3a4ce77ca30facfdf0472f44b2953dd856"}, + {file = "botocore-1.17.16.tar.gz", hash = "sha256:fe0c4f7cd6b67eff3b7cb8dff6709a65d6fca10b7b7449a493b2036915e98b4c"}, +] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +docutils = [ + {file = "docutils-0.15.2-py2-none-any.whl", hash = "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827"}, + {file = "docutils-0.15.2-py3-none-any.whl", hash = "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0"}, + {file = "docutils-0.15.2.tar.gz", hash = "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99"}, +] +grpcio = [ + {file = "grpcio-1.30.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:d5eee9d205518ee4feb9c424475ddad18a44fea97ff405780e7cd1d6df8ee96a"}, + {file = "grpcio-1.30.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:3cb78f8078ae583810c2eb47e536b0803a039656685144db43897e8beca4e203"}, + {file = "grpcio-1.30.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:d18e7fb5c5c336cc349d06cde24582e0bfa5e067fdd6268bf1519c4eb4af0199"}, + {file = "grpcio-1.30.0-cp27-cp27m-win32.whl", hash = "sha256:0c334d6cbe27ebaa9e7211236dc99f3a9ca2ea4b3bf89b0d2544df2924343cc5"}, + {file = "grpcio-1.30.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b47ec90cab0827679b511f7f9ef4fb0077cb5d7bb3d7b917154e718bb4d983b"}, + {file = "grpcio-1.30.0-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:872d45a2e01f47db095bec032470a8c5c0a5ebd00fc930b5ae35c756b20d2cff"}, + {file = "grpcio-1.30.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:9ae898c15d122a046f04ea99327e3e0bd10593eb413c4810b931103da6311a21"}, + {file = "grpcio-1.30.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:474bb992355b4a3cb8d7cb783b2d81f628c16ea921cec54ff492420e11c896f5"}, + {file = "grpcio-1.30.0-cp35-cp35m-linux_armv7l.whl", hash = "sha256:37da010e209289085d3362f371d9feefc152790859470f5e413d84a95a8d3998"}, + {file = "grpcio-1.30.0-cp35-cp35m-macosx_10_7_intel.whl", hash = "sha256:74e8b6bd0f7ae64a7eecfe9bf10bc7a905d3b3eb2775cd3a9fdcdafd277469dd"}, + {file = "grpcio-1.30.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:b8e5194fb20f4365eacfc3c33d61662651e12e166978186faf378ee972eb0bab"}, + {file = "grpcio-1.30.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:09bea7902adc33620d68462671942e163ab12214073ffb613d2fef3df94254f6"}, + {file = "grpcio-1.30.0-cp35-cp35m-win32.whl", hash = "sha256:2522f1808fe41bd8807feb5330025378553745b727eacb07562319205d1fd405"}, + {file = "grpcio-1.30.0-cp35-cp35m-win_amd64.whl", hash = "sha256:afe1f9173b51945e66c72002995eb6d4217384aaaee53215ae85d8543251fec2"}, + {file = "grpcio-1.30.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:b934542dd61746651f7907d2d7878f62ef42fdb46935088fc6a1d8266a406ba5"}, + {file = "grpcio-1.30.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ac97beab4a749c7faf6f267f7b149f6dff4f3ad64f6f6ac1d94d04019785d6a4"}, + {file = "grpcio-1.30.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:795f351ef70a931f8f7be6a10a509714ec0a6e36c674a071abe5da8eb6b8bb35"}, + {file = "grpcio-1.30.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:8d3249566b2d8b97925fbb2ae6c5b63c5ebdb919828230eae06a25e9614e051b"}, + {file = "grpcio-1.30.0-cp36-cp36m-win32.whl", hash = "sha256:32fe6369143c262d096995ebdd55eeb77f0e1dbe8343a956462ef0607527c7bc"}, + {file = "grpcio-1.30.0-cp36-cp36m-win_amd64.whl", hash = "sha256:08362b8b09562179b14db6ffce4b88e1a6a6edac8bccb85dd35f7b214fa5a0f5"}, + {file = "grpcio-1.30.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8ad75925e87ed68d5f7d5e3ec4b9f2ed209fae67c0abbcbd17481cc474421ba"}, + {file = "grpcio-1.30.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:14743e8fdfdabbab1a2075ffafd25e0a8b1a864505e3cccdf19793766cdc4624"}, + {file = "grpcio-1.30.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0c4e316e02fc227c6fba858707baee46f30d890754fc4acdf2cfec2ea0bf0aa1"}, + {file = "grpcio-1.30.0-cp37-cp37m-win32.whl", hash = "sha256:b0f7bfba0ae7a97b802348aba4e08b1e84988103cc1eb887241e7b069010058a"}, + {file = "grpcio-1.30.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2121afee4e3ebea7df1137bfb4dc396b1856aff4c517780108d9ce82f57bf2f8"}, + {file = "grpcio-1.30.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b022cedea66b7d6774bbd7d32d5a8a374947fb572da1a6915210b09a6f51cbdf"}, + {file = "grpcio-1.30.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:38ab75168a9024d393bf43343960da425736038d249920955f223bc762587697"}, + {file = "grpcio-1.30.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1f45ec5003101f16673436b150bac73c2355cd9ae78cb14f3707be01a39b5450"}, + {file = "grpcio-1.30.0-cp38-cp38-win32.whl", hash = "sha256:7f264d740906655a147448d57e4422723639d2d3f891734b8d5eb1675cb47192"}, + {file = "grpcio-1.30.0-cp38-cp38-win_amd64.whl", hash = "sha256:31e9891ac742e6866aec0cf67f1892618982cfbaf08bdcf3bb2e0f0828530c38"}, + {file = "grpcio-1.30.0.tar.gz", hash = "sha256:e8f2f5d16e0164c415f1b31a8d9a81f2e4645a43d1b261375d6bab7b0adf511f"}, +] +grpcio-tools = [ + {file = "grpcio-tools-1.30.0.tar.gz", hash = "sha256:7878adb93b0c1941eb2e0bed60719f38cda2ae5568bc0bcaa701f457e719a329"}, + {file = "grpcio_tools-1.30.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:755ccf09cbb16c0516a1e3d8db49ce2a657fd78d0bfc2491cb6520dfa6b43ddc"}, + {file = "grpcio_tools-1.30.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:de1ee76eba242d866fc030d5cc58f90181eb89de9ae30387e6e8d5a11f547981"}, + {file = "grpcio_tools-1.30.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:6876271f360248a9cf37e7c2d0f8c3c034be53b3d6a5d015fb5e69a014bf121f"}, + {file = "grpcio_tools-1.30.0-cp27-cp27m-win32.whl", hash = "sha256:3a03757a79ed9cff536bec1394721bbdc279dd59d8c0827101ba80eab894836d"}, + {file = "grpcio_tools-1.30.0-cp27-cp27m-win_amd64.whl", hash = "sha256:5f2b65df9ba3b83141d9a53a841758c97792ce36d7cf2067f657af0b43773c29"}, + {file = "grpcio_tools-1.30.0-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:2ca9b683db30cb29b00eb6a8274e700f8a585c9c8678213ec83f52cd1895eac5"}, + {file = "grpcio_tools-1.30.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:c3528d8f72fbd8cec8770af6989054a9b945c58bd685042abcbd8d5ea4333f9f"}, + {file = "grpcio_tools-1.30.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ecdd0fa0fd71a9754bbd75927d391be26c4f0b556563c742780da085aa8d530d"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-linux_armv7l.whl", hash = "sha256:089be110fc7e853709f68505be508aa055eff96bcb9b138e15f043bdb9d89011"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:2df744b0a1b70e80392fba66fb2141f8c88ecd4fff5c46f04e7e4c976fe05339"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:33d448bfdb65763ae2d4889b3981688dcf805df9b038c73fed12addf7bebd0a4"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:96338008a77fc284443707ebd014bb4114cd97ab529ebd63f157f83cbcb6e88d"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-win32.whl", hash = "sha256:e82b7d382d525a0649f87fb86a993fdf385b16f15c9c29d15f8da7b9e53dc6ac"}, + {file = "grpcio_tools-1.30.0-cp35-cp35m-win_amd64.whl", hash = "sha256:3454b4332dbe80f0692317d315f34acc086d6c347d3f6527b05a774a5712af84"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:62bb395d1d4e077bc1109d248e23af3200429c8e3358d47cf1a6c2ec7a429716"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0c78d3b2d46f5b704928dcedc34ec084d765b492781ebeae565ee2adba18ad9a"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:160c8c1f27bb44629da5e0c1e8e656ca2cda001bfb2fb7e346172933e08dc456"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:296acc97fd54957a2e3a25c28ab667a1e8e7ccc5daf97866e2af0960c63341cb"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-win32.whl", hash = "sha256:2af37ee55e466d364ca121273c1332e6430c0006c172a490d3594c8cacceb577"}, + {file = "grpcio_tools-1.30.0-cp36-cp36m-win_amd64.whl", hash = "sha256:83cd3231ce1c88fa2c896cab164320245ee371d45ea054375beb5a0cd75ce4da"}, + {file = "grpcio_tools-1.30.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a4fca9bea2ee4896164f83dde28aaa7407ce27343eb265f41b1122e5c91da6ec"}, + {file = "grpcio_tools-1.30.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9165773bb93aff153abce255a25ccabb5d94d1103ee195ec60fef127a2c5a035"}, + {file = "grpcio_tools-1.30.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0928912acdf5a9e93fc3c47e37f2c81fc48ed019a40964abe8cbd927d3b2a9cb"}, + {file = "grpcio_tools-1.30.0-cp37-cp37m-win32.whl", hash = "sha256:9af3bcfdceb3a5f89670808a129c2cf4f5d5d0d5018f0e1c7faf58a4d9547f76"}, + {file = "grpcio_tools-1.30.0-cp37-cp37m-win_amd64.whl", hash = "sha256:faa9ae69d1c623da0e65385406c4cfa782966be3cf3bdf2c6faa6f46281a4d49"}, + {file = "grpcio_tools-1.30.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:601bd2001ba9e4f2ccdf7b363c436397dcc5211194fe180fa0ad2a21df5a738e"}, + {file = "grpcio_tools-1.30.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:7874f5783bdf6afd8f8b6de721952ccc6568cf71fc7dae695a296998cd2cf1d5"}, + {file = "grpcio_tools-1.30.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fd61d5492219f59d11d390bc223b937ef80e36aee84218497135226fdf5f41d1"}, + {file = "grpcio_tools-1.30.0-cp38-cp38-win32.whl", hash = "sha256:912dbabb7e29dbc0f4457c214a2cb9738e224553e9d177224ec357c2f295b533"}, + {file = "grpcio_tools-1.30.0-cp38-cp38-win_amd64.whl", hash = "sha256:169c4b218584b071201b01ae2354bf3adf2f7d927b04154825f19b3764394fbf"}, +] +importlib-metadata = [ + {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, + {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, +] +jmespath = [ + {file = "jmespath-0.10.0-py2.py3-none-any.whl", hash = "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"}, + {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, +] +more-itertools = [ + {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"}, + {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"}, +] +mysql-connector-python = [ + {file = "mysql-connector-python-8.0.20.tar.gz", hash = "sha256:bd1f1a57e9c89d6bf49b408c6fe151aad8c318237f2983dfc5b9a8202c6d20de"}, + {file = "mysql_connector_python-8.0.20-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:1b6f1dbe964990604782e55c5570a8a968ba1da7371ad75ed4ddd8be0129c0cf"}, + {file = "mysql_connector_python-8.0.20-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:a22183b55a3e5725a350b76f9ef6898573c808cb63a465b4bd78f860dfb6ed8d"}, + {file = "mysql_connector_python-8.0.20-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3b6b271de5664a2ac155954f38c09b6362f321f00734ff1f421e7ab721c7f98b"}, + {file = "mysql_connector_python-8.0.20-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:0f847818de953ebf53028fedfcb5622e11d226f01b1c5a93010063f78ab95b34"}, + {file = "mysql_connector_python-8.0.20-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbe901254597db9937b8dee4fe56c148fcfb792389f753fa35fff3696d04e5fa"}, + {file = "mysql_connector_python-8.0.20-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:ffe0bdd9b22a987028ca4e70df770edef987d54899ac5029c364d9c3c04e9e9d"}, + {file = "mysql_connector_python-8.0.20-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:86b7fac171a4433a9c263ab74d59ca4cf0c2941765f2f9a0cd1925295f04838f"}, + {file = "mysql_connector_python-8.0.20-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:829ff16c18900ca25af0007de027c796161ed8711ae22cc50a785e8e1e2f756a"}, + {file = "mysql_connector_python-8.0.20-cp35-cp35m-win_amd64.whl", hash = "sha256:584098ce99bc81ca71fcc5664228a1aea901e26b473f39c6b4d9945abb641421"}, + {file = "mysql_connector_python-8.0.20-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:88ecd6318e71d0a250efa016e80cfdcb987e7ce21793569b1751c20d3d022bb0"}, + {file = "mysql_connector_python-8.0.20-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:37e1da0f78f1df38a33ccfe8431edd59cfdcbf249f56820028898cf5acbba0a5"}, + {file = "mysql_connector_python-8.0.20-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1ed1f29e8db935c30b33b9d137660f70a71d8757a99e16e3f51a40867f6c5ec0"}, + {file = "mysql_connector_python-8.0.20-cp36-cp36m-win_amd64.whl", hash = "sha256:f23c8ddc1550def024ea708d2aa7c999f301cd45ff17ca7bf9a762b48f0d4513"}, + {file = "mysql_connector_python-8.0.20-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:2c126e929aa6b725d921a5c02e8b6ce999a8f3113494ca9fc94b3f1cbbdf3095"}, + {file = "mysql_connector_python-8.0.20-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:eec4c549d96d9678fe9df663226fc175562dcd7187af892bfe4711c9a0d99228"}, + {file = "mysql_connector_python-8.0.20-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c20dd01dee6212deb56d3df985fe9927a571000327251177d69f05a40c11ac19"}, + {file = "mysql_connector_python-8.0.20-cp37-cp37m-win_amd64.whl", hash = "sha256:9ba98169e360a4e8739803d7ebce5de693dc4cd5634a62eafb3b2bc3c7f0d7c4"}, + {file = "mysql_connector_python-8.0.20-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:4de6f599ec48e7807cc73812f43f2be22a2d7859310c6d99cf51ed436d41b4e5"}, + {file = "mysql_connector_python-8.0.20-cp38-cp38-manylinux1_i686.whl", hash = "sha256:541394d10909aa379d396953bc4a3071aed754157d42de4ffd8ada91f15a4f1b"}, + {file = "mysql_connector_python-8.0.20-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d7fb72758e5e11db4b946b342330c136034d1cf6759be9b182e17d619897de2"}, + {file = "mysql_connector_python-8.0.20-cp38-cp38m-win_amd64.whl", hash = "sha256:7bdb4e94462e91d10c7bf809c122db1459917d80202fe5cb88c6c04481b1a303"}, + {file = "mysql_connector_python-8.0.20-py2.py3-none-any.whl", hash = "sha256:0f4cf26d89a7d99ec215e01e47bac40935dc80c573005395dbc18890856f87a5"}, +] +packaging = [ + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] +pathlib2 = [ + {file = "pathlib2-2.3.5-py2.py3-none-any.whl", hash = "sha256:0ec8205a157c80d7acc301c0b18fbd5d44fe655968f5d947b6ecef5290fc35db"}, + {file = "pathlib2-2.3.5.tar.gz", hash = "sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +protobuf = [ + {file = "protobuf-3.12.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e1464a4a2cf12f58f662c8e6421772c07947266293fb701cb39cd9c1e183f63c"}, + {file = "protobuf-3.12.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:6f349adabf1c004aba53f7b4633459f8ca8a09654bf7e69b509c95a454755776"}, + {file = "protobuf-3.12.2-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:be04fe14ceed7f8641e30f36077c1a654ff6f17d0c7a5283b699d057d150d82a"}, + {file = "protobuf-3.12.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f4b73736108a416c76c17a8a09bc73af3d91edaa26c682aaa460ef91a47168d3"}, + {file = "protobuf-3.12.2-cp35-cp35m-win32.whl", hash = "sha256:5524c7020eb1fb7319472cb75c4c3206ef18b34d6034d2ee420a60f99cddeb07"}, + {file = "protobuf-3.12.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bff02030bab8b969f4de597543e55bd05e968567acb25c0a87495a31eb09e925"}, + {file = "protobuf-3.12.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c9ca9f76805e5a637605f171f6c4772fc4a81eced4e2f708f79c75166a2c99ea"}, + {file = "protobuf-3.12.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:304e08440c4a41a0f3592d2a38934aad6919d692bb0edfb355548786728f9a5e"}, + {file = "protobuf-3.12.2-cp36-cp36m-win32.whl", hash = "sha256:b5a114ea9b7fc90c2cc4867a866512672a47f66b154c6d7ee7e48ddb68b68122"}, + {file = "protobuf-3.12.2-cp36-cp36m-win_amd64.whl", hash = "sha256:85b94d2653b0fdf6d879e39d51018bf5ccd86c81c04e18a98e9888694b98226f"}, + {file = "protobuf-3.12.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a7ab28a8f1f043c58d157bceb64f80e4d2f7f1b934bc7ff5e7f7a55a337ea8b0"}, + {file = "protobuf-3.12.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:eafe9fa19fcefef424ee089fb01ac7177ff3691af7cc2ae8791ae523eb6ca907"}, + {file = "protobuf-3.12.2-cp37-cp37m-win32.whl", hash = "sha256:612bc97e42b22af10ba25e4140963fbaa4c5181487d163f4eb55b0b15b3dfcd2"}, + {file = "protobuf-3.12.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e72736dd822748b0721f41f9aaaf6a5b6d5cfc78f6c8690263aef8bba4457f0e"}, + {file = "protobuf-3.12.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:87535dc2d2ef007b9d44e309d2b8ea27a03d2fa09556a72364d706fcb7090828"}, + {file = "protobuf-3.12.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:50b5fee674878b14baea73b4568dc478c46a31dd50157a5b5d2f71138243b1a9"}, + {file = "protobuf-3.12.2-py2.py3-none-any.whl", hash = "sha256:a96f8fc625e9ff568838e556f6f6ae8eca8b4837cdfb3f90efcb7c00e342a2eb"}, + {file = "protobuf-3.12.2.tar.gz", hash = "sha256:49ef8ab4c27812a89a76fa894fe7a08f42f2147078392c0dee51d4a444ef6df5"}, +] +psycopg2 = [ + {file = "psycopg2-2.8.5-cp27-cp27m-win32.whl", hash = "sha256:a0984ff49e176062fcdc8a5a2a670c9bb1704a2f69548bce8f8a7bad41c661bf"}, + {file = "psycopg2-2.8.5-cp27-cp27m-win_amd64.whl", hash = "sha256:acf56d564e443e3dea152efe972b1434058244298a94348fc518d6dd6a9fb0bb"}, + {file = "psycopg2-2.8.5-cp34-cp34m-win32.whl", hash = "sha256:440a3ea2c955e89321a138eb7582aa1d22fe286c7d65e26a2c5411af0a88ae72"}, + {file = "psycopg2-2.8.5-cp34-cp34m-win_amd64.whl", hash = "sha256:6b306dae53ec7f4f67a10942cf8ac85de930ea90e9903e2df4001f69b7833f7e"}, + {file = "psycopg2-2.8.5-cp35-cp35m-win32.whl", hash = "sha256:d3b29d717d39d3580efd760a9a46a7418408acebbb784717c90d708c9ed5f055"}, + {file = "psycopg2-2.8.5-cp35-cp35m-win_amd64.whl", hash = "sha256:6a471d4d2a6f14c97a882e8d3124869bc623f3df6177eefe02994ea41fd45b52"}, + {file = "psycopg2-2.8.5-cp36-cp36m-win32.whl", hash = "sha256:27c633f2d5db0fc27b51f1b08f410715b59fa3802987aec91aeb8f562724e95c"}, + {file = "psycopg2-2.8.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2df2bf1b87305bd95eb3ac666ee1f00a9c83d10927b8144e8e39644218f4cf81"}, + {file = "psycopg2-2.8.5-cp37-cp37m-win32.whl", hash = "sha256:ac5b23d0199c012ad91ed1bbb971b7666da651c6371529b1be8cbe2a7bf3c3a9"}, + {file = "psycopg2-2.8.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2c0afb40cfb4d53487ee2ebe128649028c9a78d2476d14a67781e45dc287f080"}, + {file = "psycopg2-2.8.5-cp38-cp38-win32.whl", hash = "sha256:2327bf42c1744a434ed8ed0bbaa9168cac7ee5a22a9001f6fc85c33b8a4a14b7"}, + {file = "psycopg2-2.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:132efc7ee46a763e68a815f4d26223d9c679953cd190f1f218187cb60decf535"}, + {file = "psycopg2-2.8.5.tar.gz", hash = "sha256:f7d46240f7a1ae1dd95aab38bd74f7428d46531f69219954266d669da60c0818"}, +] +py = [ + {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, + {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, +] +pytest-asyncio = [ + {file = "pytest-asyncio-0.14.0.tar.gz", hash = "sha256:9882c0c6b24429449f5f969a5158b528f39bde47dc32e85b9f0403965017e700"}, + {file = "pytest_asyncio-0.14.0-py3-none-any.whl", hash = "sha256:2eae1e34f6c68fc0a9dc12d4bea190483843ff4708d24277c41568d6b6044f1d"}, +] +pytest-parallel = [ + {file = "pytest-parallel-0.1.0.tar.gz", hash = "sha256:4663a8fb805ac98b51e51de84d35ffd9717017fb71ed270440dc94b862466c20"}, + {file = "pytest_parallel-0.1.0-py3-none-any.whl", hash = "sha256:10693161e350b59466ca331bad964073555cda114cc0499bd826deeceee512ed"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] +s3transfer = [ + {file = "s3transfer-0.3.3-py2.py3-none-any.whl", hash = "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13"}, + {file = "s3transfer-0.3.3.tar.gz", hash = "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +tblib = [ + {file = "tblib-1.6.0-py2.py3-none-any.whl", hash = "sha256:e222f44485d45ed13fada73b57775e2ff9bd8af62160120bbb6679f5ad80315b"}, + {file = "tblib-1.6.0.tar.gz", hash = "sha256:229bee3754cb5d98b4837dd5c4405e80cfab57cb9f93220410ad367f8b352344"}, +] +urllib3 = [ + {file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"}, + {file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"}, +] +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, +] +zipp = [ + {file = "zipp-1.2.0-py2.py3-none-any.whl", hash = "sha256:e0d9e63797e483a30d27e09fffd308c59a700d365ec34e93cc100844168bf921"}, + {file = "zipp-1.2.0.tar.gz", hash = "sha256:c70410551488251b0fee67b460fb9a536af8d6f9f008ad10ac51f615b6a521b1"}, +] diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml new file mode 100644 index 00000000..596cdc5e --- /dev/null +++ b/sdk/python/pyproject.toml @@ -0,0 +1,46 @@ +[build-system] +requires = ["poetry>=1.0.9"] +build-backend = "poetry.masonry.api" + +[tool.poetry] +name = "approzium" +version = "0.1.1" +description = "Approzium SDK provides Approzium database authentiation for Python" +authors = ["Cyral "] + +[tool.poetry.dependencies] +python = "^3.5" +boto3 = "^1.14.10" +grpcio = "^1.30.0" +grpcio-tools = "^1.30.0" +psycopg2 = { version = "^2.8.5", optional = true} +asyncpg = { version = "^0.20.1", optional = true} +mysql-connector-python = { version = "^8.0.20", optional = true} + +[tool.poetry.dev-dependencies] +pytest = "^5.4.3" +pytest-parallel = "^0.1.0" +pytest-asyncio = "^0.14.0" + +[tool.poetry.extras] +sqllibs = ["psycopg2", "asyncpg", "mysql-connector-python"] + +[tool.black] +target-version = ['py37'] +exclude = ''' + +( + /( + \.eggs # exclude a few common directories in the + | \.hg # root of the project + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + )/ + | approzium/_protos +) +''' diff --git a/sdk/python/pytest.ini b/sdk/python/pytest.ini new file mode 100644 index 00000000..d4288346 --- /dev/null +++ b/sdk/python/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tests +addopts = --ignore=tests/pg2_testsuite diff --git a/sdk/python/tests/conftest.py b/sdk/python/tests/conftest.py new file mode 100644 index 00000000..51906784 --- /dev/null +++ b/sdk/python/tests/conftest.py @@ -0,0 +1,41 @@ +from os import environ + +import pytest + +import approzium + + +def pytest_configure(): + determine_authclients() + + +def determine_authclients(): + """If TEST_ASSUMABLE_ARN is set, adds an additional Approzium AuthClient + that uses it""" + pytest.authclients = [] + base_aws_auth = approzium.AuthClient( + "authenticator:6001", + tls_config=approzium.TLSConfig( + trusted_certs=environ.get("TEST_CERT_DIR") + "/approzium.pem", + client_cert=environ.get("TEST_CERT_DIR") + "/client.pem", + client_key=environ.get("TEST_CERT_DIR") + "/client.key", + ), + disable_tls=environ.get("APPROZIUM_DISABLE_TLS"), + ) + pytest.authclients.append(base_aws_auth) + if environ.get("TEST_ASSUMABLE_ARN"): + role_aws_auth = approzium.AuthClient( + "authenticator:6001", + tls_config=approzium.TLSConfig( + trusted_certs=environ.get("TEST_CERT_DIR") + "/approzium.pem", + client_cert=environ.get("TEST_CERT_DIR") + "/client.pem", + client_key=environ.get("TEST_CERT_DIR") + "/client.key", + ), + disable_tls=environ.get("APPROZIUM_DISABLE_TLS"), + ) + pytest.authclients.append(role_aws_auth) + else: + print( + """Skipping testing using assumable AWS roles because +TEST_ASSUMABLE_ARN is not set""" + ) diff --git a/sdk/python/tests/run_pg2_testsuite.py b/sdk/python/tests/run_pg2_testsuite.py new file mode 100644 index 00000000..a1726bf0 --- /dev/null +++ b/sdk/python/tests/run_pg2_testsuite.py @@ -0,0 +1,66 @@ +""" +This script runs the Psycopg2 test suite without a running authenticator +service. Therefore, it only tests the client SDK and a password is needed +""" +import logging +import os +import sys +import unittest +from os.path import abspath +from unittest import SkipTest + +import pg2_testsuite # noqa: E402 F401 +import psycopg2 + +from approzium import Authenticator, set_default_authenticator + +# once get hash is mocked, import connect method +from approzium.psycopg2 import connect as approzium_pg2_connect + +sys.path.append(abspath("pg2_testsuite")) + + +try: + test_iam_role = os.environ["TEST_ASSUMABLE_ARN"] +except KeyError: + print("Please set env var 'TEST_ASSUMABLE_ARN' to a valid value") + sys.exit(1) + +auth = Authenticator("authenticator:6001", test_iam_role) +set_default_authenticator(auth) + +# replace connect method +psycopg2.connect = approzium_pg2_connect + + +def skip_tests(ids, pg2_suites): + filtered_suite = unittest.TestSuite() + # the way the Psycopg2 test suite is setup, there are many layers of + # organization + for suites in pg2_suites: + for suite in suites: + for test in suite: + if test.id() in skipped_tests: + + def skip_method(): + raise SkipTest("skipped by Approzium") + + setattr(test, test._testMethodName, skip_method) + filtered_suite.addTest(test) + return filtered_suite + + +# tests that are accepted to not work with Approzium +skipped_tests = [ + "pg2_testsuite.test_async.AsyncTests.test_async_subclass", + "pg2_testsuite.test_module.ConnectTestCase.test_no_keywords", + "pg2_testsuite.test_module.ConnectTestCase.test_dsn", + "pg2_testsuite.test_module.ConnectTestCase.test_async", + "pg2_testsuite.test_module.ConnectTestCase.test_factory", + "pg2_testsuite.test_module.ConnectTestCase.test_flush_on_write", +] +pg2_suite = unittest.TestLoader().loadTestsFromName("pg2_testsuite.test_suite") +suite = skip_tests(skipped_tests, pg2_suite) + +logging.getLogger().setLevel(logging.ERROR) +unittest.TextTestRunner(verbosity=1).run(suite) diff --git a/sdk/python/tests/test__postgres.py b/sdk/python/tests/test__postgres.py new file mode 100644 index 00000000..d129d684 --- /dev/null +++ b/sdk/python/tests/test__postgres.py @@ -0,0 +1,30 @@ +from approzium._postgres import construct_msg, parse_msg + + +def test_parse_msg(): + # empty messages with a header + msg = b"R\x00\00\00\04" + assert parse_msg(msg) == (ord("R"), b"") + msg = b"Z\x00\00\00\04" + assert parse_msg(msg) == (ord("Z"), b"") + # message with one byte content + msg = b"M\x00\00\00\05\13" + assert parse_msg(msg) == (ord("M"), b"\13") + # message with one byte content but lots of extra content + # extra content should be ignored + msg = b"M\x00\00\00\05\13" + 100 * b"E" + assert parse_msg(msg) == (ord("M"), b"\13") + + +def test_construct_msg(): + assert construct_msg(b"R", b"") == b"R\x00\00\00\04" + assert construct_msg(b"Z", b"") == b"Z\x00\00\00\04" + assert construct_msg(b"R", b"\x0c") == b"R\x00\00\00\05\x0c" + + +def test_integration_parse_construct_msg(): + headers = [b"R", b"Z"] + contents = [b"testbytestring", b""] + for header, content in zip(headers, contents): + msg = construct_msg(header, content) + assert parse_msg(msg) == (ord(header), content) diff --git a/sdk/python/tests/test_approzium_sdk.py b/sdk/python/tests/test_approzium_sdk.py new file mode 100644 index 00000000..338b19fb --- /dev/null +++ b/sdk/python/tests/test_approzium_sdk.py @@ -0,0 +1,8 @@ +from approzium._misc import read_int32_from_bytes + + +def test_readint32(): + b = bytes([0, 0, 0, 0, 1, 0]) + assert read_int32_from_bytes(b, 0) == 0 + assert read_int32_from_bytes(b, 1) == 1 + assert read_int32_from_bytes(b, 2) == 256 diff --git a/sdk/python/tests/test_asyncpg_connect.py b/sdk/python/tests/test_asyncpg_connect.py new file mode 100644 index 00000000..e248a486 --- /dev/null +++ b/sdk/python/tests/test_asyncpg_connect.py @@ -0,0 +1,38 @@ +from os import environ + +import pytest + +import approzium +from approzium.asyncpg import connect +from approzium.asyncpg.pool import create_pool + +# use Psycopg2 defined test environment variables +connopts = { + "user": environ["PSYCOPG2_TESTDB_USER"], + "database": environ["PSYCOPG2_TESTDB"], + "port": int(environ["PSYCOPG2_TESTDB_PORT"]), +} + + +@pytest.mark.parametrize("auth", pytest.authclients) +@pytest.mark.parametrize("host", ["dbmd5", "dbsha256"]) +@pytest.mark.parametrize("sslmode", ["disable", "require"]) +@pytest.mark.asyncio +async def test_connect(auth, host, sslmode): + # set SSL mode using env variable because there is no better way + environ["PGSSLMODE"] = sslmode + conn = await connect(**connopts, host=host, authenticator=auth) + await conn.fetch("SELECT 1") + + +@pytest.mark.parametrize("auth", pytest.authclients) +@pytest.mark.parametrize("host", ["dbmd5", "dbsha256"]) +@pytest.mark.parametrize("sslmode", ["disable", "require"]) +@pytest.mark.asyncio +async def test_pool(auth, host, sslmode): + approzium.default_auth_client = auth + # set SSL mode using env variable because there is no better way + environ["PGSSLMODE"] = sslmode + pool = await create_pool(**connopts, host=host) + async with pool.acquire() as conn: + await conn.fetch("""SELECT 1""") diff --git a/sdk/python/tests/test_mysql_connect.py b/sdk/python/tests/test_mysql_connect.py new file mode 100644 index 00000000..26bf3371 --- /dev/null +++ b/sdk/python/tests/test_mysql_connect.py @@ -0,0 +1,34 @@ +from os import environ + +import pytest + +import approzium +from approzium.mysql.connector import connect +from approzium.mysql.connector.pooling import MySQLConnectionPool + +# use Psycopg2 defined test environment variables +connopts = { + "user": environ["PSYCOPG2_TESTDB_USER"], + "host": "dbmysqlsha1", + "use_pure": True, +} + + +@pytest.mark.parametrize("auth", pytest.authclients) +def test_connect(auth): + conn = connect(**connopts, authenticator=auth) + cur = conn.cursor() + cur.execute("SELECT 1") + result = next(cur) + assert result == (1,) + + +@pytest.mark.parametrize("auth", pytest.authclients) +def test_pooling(auth): + approzium.default_auth_client = auth + cnxpool = MySQLConnectionPool(pool_name="testpool", pool_size=3, **connopts) + conn = cnxpool.get_connection() + cur = conn.cursor() + cur.execute("SELECT 1") + result = next(cur) + assert result == (1,) diff --git a/sdk/python/tests/test_psycopg2_connect.py b/sdk/python/tests/test_psycopg2_connect.py new file mode 100644 index 00000000..3d3da8c7 --- /dev/null +++ b/sdk/python/tests/test_psycopg2_connect.py @@ -0,0 +1,66 @@ +from os import environ +from select import select + +import psycopg2 +import pytest + +import approzium +from approzium.psycopg2 import connect +from approzium.psycopg2.pool import SimpleConnectionPool, ThreadedConnectionPool + +# use Psycopg2 defined test environment variables +connopts = { + "user": environ["PSYCOPG2_TESTDB_USER"], + "dbname": environ["PSYCOPG2_TESTDB"], + "port": environ["PSYCOPG2_TESTDB_PORT"], +} + + +# waits for an async connection to start or finish execution +# source: https://www.psycopg.org/docs/advanced.html +def wait(conn): + while True: + state = conn.poll() + if state == psycopg2.extensions.POLL_OK: + break + elif state == psycopg2.extensions.POLL_WRITE: + select([], [conn.fileno()], []) + elif state == psycopg2.extensions.POLL_READ: + select([conn.fileno()], [], []) + else: + raise psycopg2.OperationalError("poll() returned %s" % state) + + +@pytest.mark.parametrize("auth", pytest.authclients) +@pytest.mark.parametrize("dbhost", ["dbmd5", "dbsha256"]) +@pytest.mark.parametrize("sslmode", ["require", "disable"]) +@pytest.mark.parametrize("async_", [1, 0]) +def test_connect(auth, dbhost, sslmode, async_): + conn = connect( + **connopts, host=dbhost, sslmode=sslmode, async_=async_, authenticator=auth + ) + if async_: + wait(conn) + cur = conn.cursor() + cur.execute("SELECT 1") + if async_: + wait(conn) + assert cur.fetchone() == (1,) + + +@pytest.mark.parametrize("auth", pytest.authclients) +@pytest.mark.parametrize("dbhost", ["dbmd5", "dbsha256"]) +@pytest.mark.parametrize("sslmode", ["require", "disable"]) +@pytest.mark.parametrize("async_", [1, 0]) +@pytest.mark.parametrize("Pool", [ThreadedConnectionPool, SimpleConnectionPool]) +def test_pool(auth, dbhost, sslmode, async_, Pool): + approzium.default_auth_client = auth + conns = Pool(1, 5, "", **connopts, host=dbhost, sslmode=sslmode, async_=async_,) + conn = conns.getconn() + if async_: + wait(conn) + cur = conn.cursor() + cur.execute("SELECT 1") + if async_: + wait(conn) + assert cur.fetchone() == (1,) diff --git a/ssl/Dockerfile b/ssl/Dockerfile new file mode 100644 index 00000000..9f8bc11a --- /dev/null +++ b/ssl/Dockerfile @@ -0,0 +1,6 @@ +FROM postgres:12.3 +LABEL "Product"="PostgreSQL (SSL enabled)" +COPY server.key /var/lib/postgresql/server.key +COPY server.crt /var/lib/postgresql/server.crt +RUN chown postgres /var/lib/postgresql/server.key && \ + chmod 600 /var/lib/postgresql/server.key diff --git a/ssl/gen_cert.sh b/ssl/gen_cert.sh new file mode 100755 index 00000000..60ed789f --- /dev/null +++ b/ssl/gen_cert.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +BASEDIR=$(dirname "$0") +LOGGING_PREFIX="gen_cert.sh >> " + +PASSKEY=somekey + +rm -f ${BASEDIR}/server.crt +rm -f ${BASEDIR}/server.csr +rm -f ${BASEDIR}/server.key +rm -f ${BASEDIR}/rootCA.crt +rm -f ${BASEDIR}/rootCA.csr +rm -f ${BASEDIR}/rootCA.key +rm -f ${BASEDIR}/rootCA.srl + +# generate a key for our root CA certificate +echo "${LOGGING_PREFIX} Generating key for root CA certificate" +openssl genrsa -des3 -passout pass:${PASSKEY} -out ${BASEDIR}/rootCA.pass.key 2048 +openssl rsa -passin pass:${PASSKEY} -in ${BASEDIR}/rootCA.pass.key -out ${BASEDIR}/rootCA.key +rm ${BASEDIR}/rootCA.pass.key +echo + +# create and self sign the root CA certificate +echo +echo "${LOGGING_PREFIX} Creating self-signed root CA certificate" +openssl req -x509 -new -nodes -key ${BASEDIR}/rootCA.key -sha256 -days 1024 -out ${BASEDIR}/rootCA.crt -subj "/C=UK/ST=/L=/O=IBM/OU=AIOS/CN=aios-orch-dev-env-CA" +echo "${LOGGING_PREFIX} Self-signed root CA certificate (${BASEDIR}/rootCA.crt) is:" +openssl x509 -in ${BASEDIR}/rootCA.crt -text -noout +echo + +# generate a key for our server certificate +echo +echo "${LOGGING_PREFIX} Generating key for server certificate" +openssl genrsa -des3 -passout pass:${PASSKEY} -out ${BASEDIR}/server.pass.key 2048 +openssl rsa -passin pass:${PASSKEY} -in ${BASEDIR}/server.pass.key -out ${BASEDIR}/server.key +rm ${BASEDIR}/server.pass.key +echo + +# create a certificate request for our server. This includes a subject alternative name so either aios-localhost, localhost or postgres_ssl can be used to address it +echo +echo "${LOGGING_PREFIX} Creating server certificate" +openssl req -new -key ${BASEDIR}/server.key -out ${BASEDIR}/server.csr -subj "/C=UK/ST=/L=/O=IBM/OU=AIOS/CN=postgres_ssl" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:postgres_ssl,DNS:localhost,DNS:aios-localhost")) +echo "${LOGGING_PREFIX} Server certificate signing request (${BASEDIR}/server.csr) is:" +openssl req -verify -in ${BASEDIR}/server.csr -text -noout +echo + +# use our CA certificate and key to create a signed version of the server certificate +echo +echo "${LOGGING_PREFIX} Signing server certificate using our root CA certificate and key" +openssl x509 -req -sha256 -days 365 -in ${BASEDIR}/server.csr -CA ${BASEDIR}/rootCA.crt -CAkey ${BASEDIR}/rootCA.key -CAcreateserial -out ${BASEDIR}/server.crt -extensions SAN -extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:postgres_ssl,DNS:localhost,DNS:aios-localhost")) +chmod og-rwx ${BASEDIR}/server.key +echo "${LOGGING_PREFIX} Server certificate signed with our root CA certificate (${BASEDIR}/server.crt) is:" +openssl x509 -in ${BASEDIR}/server.crt -text -noout +echo + +# done output the base64 encoded version of the root CA certificate which should be added to trust stores +echo +echo "${LOGGING_PREFIX} Done. Next time the postgres_ssl docker image is rebuilt the new server certificate (${BASEDIR}/server.crt) will be used." +echo +echo "${LOGGING_PREFIX} Use the following CA certificate variables:" +B64_CA_CERT=`cat ${BASEDIR}/rootCA.crt | base64` +echo "POSTGRES_SSL_CA_CERT=${B64_CA_CERT}" \ No newline at end of file