From 5c9700f808777b6a318666e713a5328bfeced620 Mon Sep 17 00:00:00 2001 From: Jack Urbanek Date: Wed, 4 Nov 2020 12:31:31 -0500 Subject: [PATCH] Refactor a lot of paths to re-organize structure (#295) * moving around the stuff from data_model and webapp/client * Migrating crowd providers * Moving script utils * Migrating architects * Forgot to update channel callsites * Moving blueprints * Migrating core * merging 298 * doc path refactor --- docs/architecture_overview.md | 2 +- docs/hydra_migration.md | 32 +- docs/quickstart.md | 2 +- .../parlai_test_script.py | 8 +- .../simple_static_task/examine_results.py | 4 +- .../static_run_with_onboarding.py | 14 +- .../simple_static_task/static_test_script.py | 12 +- examples/static_react_task/run_task.py | 12 +- mephisto/__init__.py | 6 +- .../mturk/utils => abstractions}/__init__.py | 0 mephisto/abstractions/architect.py | 113 + .../architects/README.md | 0 .../abstractions/architects}/__init__.py | 0 .../architects/channels}/__init__.py | 0 .../architects/channels/websocket_channel.py | 175 + .../architects/heroku_architect.py | 460 + .../architects/local_architect.py | 182 + .../abstractions/architects/mock_architect.py | 369 + .../architects/router}/__init__.py | 0 .../architects/router/build_router.py | 91 + .../router/deploy/package-lock.json | 906 ++ .../architects/router/deploy/package.json | 23 + .../architects/router/deploy/server.js | 526 ++ .../router/deploy/static/index.html | 25 + .../router/deploy/uploads/exists.txt | 0 mephisto/abstractions/blueprint.py | 625 ++ mephisto/abstractions/blueprints/README.md | 43 + .../abstractions/blueprints}/__init__.py | 0 .../blueprints/abstract/README.md | 2 + .../blueprints/abstract}/__init__.py | 0 .../abstract/static_task}/__init__.py | 0 .../static_task/empty_task_builder.py | 22 + .../static_task/static_agent_state.py | 115 + .../abstract/static_task/static_blueprint.py | 188 + .../static_task/static_task_runner.py | 79 + .../abstractions/blueprints/mock/__init__.py | 5 + .../blueprints/mock/mock_agent_state.py | 59 + .../blueprints/mock/mock_blueprint.py | 93 + .../blueprints/mock/mock_task_builder.py | 29 + .../blueprints/mock/mock_task_runner.py | 111 + .../blueprints/parlai_chat/__init__.py | 5 + .../parlai_chat/parlai_chat_agent_state.py | 121 + .../parlai_chat/parlai_chat_blueprint.py | 282 + .../parlai_chat/parlai_chat_task_builder.py | 183 + .../parlai_chat/parlai_chat_task_runner.py | 272 + .../parlai_chat/source/package-lock.json | 5490 ++++++++++++ .../blueprints/parlai_chat/webapp/.babelrc | 4 + .../blueprints/parlai_chat/webapp/.eslintrc | 3 + .../blueprints/parlai_chat/webapp/README.md | 16 + .../parlai_chat/webapp/package-lock.json | 7914 +++++++++++++++++ .../parlai_chat/webapp/package.json | 44 + .../blueprints/parlai_chat/webapp/src/main.js | 56 + .../parlai_chat/webapp/src/static/index.html | 32 + .../parlai_chat/webapp/src/static/notif.mp3 | Bin 0 -> 46393 bytes .../parlai_chat/webapp/webpack.config.js | 48 + .../blueprints/parlai_chat/webapp/yarn.lock | 5654 ++++++++++++ .../blueprints/static_html_task/__init__.py | 5 + .../static_html_task/source/.babelrc | 4 + .../static_html_task/source/dev/app.jsx | 193 + .../static_html_task/source/dev/main.js | 6 + .../blueprints/static_react_task/__init__.py | 5 + .../static_react_blueprint.py | 94 + .../static_react_task_builder.py | 40 + mephisto/abstractions/channel.py | 86 + mephisto/abstractions/crowd_provider.py | 138 + mephisto/abstractions/database.py | 582 ++ mephisto/abstractions/databases/__init__.py | 5 + .../abstractions/databases/local_database.py | 1369 +++ .../{ => abstractions}/providers/README.md | 0 mephisto/abstractions/providers/__init__.py | 5 + .../abstractions/providers/mock/__init__.py | 5 + .../abstractions/providers/mock/mock_agent.py | 92 + .../providers/mock/mock_datastore.py | 219 + .../providers/mock/mock_provider.py | 88 + .../providers/mock/mock_requester.py | 74 + .../abstractions/providers/mock/mock_unit.py | 73 + .../providers/mock/mock_worker.py | 61 + .../providers/mock/provider_type.py | 7 + .../providers/mock/wrap_crowd_source.js | 0 .../abstractions/providers/mturk/__init__.py | 5 + .../providers/mturk/mturk_agent.py | 109 + .../providers/mturk/mturk_datastore.py | 289 + .../providers/mturk/mturk_provider.py | 163 + .../providers/mturk/mturk_requester.py | 150 + .../providers/mturk/mturk_unit.py | 249 + .../providers/mturk/mturk_utils.py | 704 ++ .../providers/mturk/mturk_worker.py | 203 + .../providers/mturk/provider_type.py | 7 + .../providers/mturk/utils/__init__.py | 5 + .../providers/mturk/utils/script_utils.py | 4 +- .../providers/mturk/wrap_crowd_source.js | 0 .../providers/mturk_sandbox/__init__.py | 5 + .../providers/mturk_sandbox/provider_type.py | 7 + .../mturk_sandbox/sandbox_mturk_agent.py | 41 + .../mturk_sandbox/sandbox_mturk_provider.py | 85 + .../mturk_sandbox/sandbox_mturk_requester.py | 58 + .../mturk_sandbox/sandbox_mturk_unit.py | 43 + .../mturk_sandbox/sandbox_mturk_worker.py | 62 + .../mturk_sandbox/wrap_crowd_source.js | 0 mephisto/client/api.py | 8 +- mephisto/client/cli.py | 12 +- mephisto/client/{ => full}/server.py | 8 +- .../{ => client/full}/webapp/.gitattributes | 0 mephisto/{ => client/full}/webapp/.gitignore | 0 mephisto/{ => client/full}/webapp/README.md | 0 .../full}/webapp/build/asset-manifest.json | 0 .../{ => client/full}/webapp/build/index.html | 0 ...nifest.6a3f8be9c9b4eda91b48c53412c4ac04.js | 0 ...nifest.9f9697fc33c2a769605084eb8123c827.js | 34 + .../{ => client/full}/webapp/build/robots.txt | 0 .../full}/webapp/build/service-worker.js | 0 .../build/static/css/2.d6c513eb.chunk.css | 0 .../build/static/css/2.d6c513eb.chunk.css.map | 0 .../build/static/css/main.ec5c0f52.chunk.css | 0 .../static/css/main.ec5c0f52.chunk.css.map | 0 .../build/static/css/main.f511f1d3.chunk.css | 2 + .../static/css/main.f511f1d3.chunk.css.map | 1 + .../build/static/js/2.34d4026e.chunk.js | 0 .../static/js/2.34d4026e.chunk.js.LICENSE | 0 .../build/static/js/2.34d4026e.chunk.js.map | 0 .../build/static/js/main.6e109e52.chunk.js | 0 .../static/js/main.6e109e52.chunk.js.map | 0 .../build/static/js/main.d1c9df08.chunk.js | 2 + .../static/js/main.d1c9df08.chunk.js.map | 1 + .../build/static/js/runtime-main.97447897.js | 0 .../static/js/runtime-main.97447897.js.map | 0 .../build/static/media/Oval.456d8835.svg | 0 .../build/static/media/icons-16.782154b8.ttf | Bin .../build/static/media/icons-16.7fb844a7.woff | Bin .../build/static/media/icons-16.d4f6722b.eot | Bin .../build/static/media/icons-20.90afdd23.eot | Bin .../build/static/media/icons-20.c0e4874e.woff | Bin .../build/static/media/icons-20.d1f0f6c1.ttf | Bin .../{ => client/full}/webapp/package.json | 0 .../full}/webapp/public/index.html | 0 .../full}/webapp/public/robots.txt | 0 mephisto/{ => client/full}/webapp/src/App.css | 0 mephisto/{ => client/full}/webapp/src/App.tsx | 0 .../{ => client/full}/webapp/src/Oval.svg | 0 .../{ => client/full}/webapp/src/axios.ts | 0 .../{ => client/full}/webapp/src/index.css | 0 .../{ => client/full}/webapp/src/index.tsx | 0 .../{ => client/full}/webapp/src/lib/Async.ts | 0 .../full}/webapp/src/lib/toaster.ts | 0 .../{ => client/full}/webapp/src/logo.svg | 0 .../{ => client/full}/webapp/src/mocks.ts | 0 .../{ => client/full}/webapp/src/models.ts | 0 .../full}/webapp/src/react-app-env.d.ts | 0 .../{ => client/full}/webapp/src/service.ts | 0 .../full}/webapp/src/setupTests.ts | 0 .../{ => client/full}/webapp/src/utils.ts | 0 .../full}/webapp/src/widgets/Base.tsx | 0 .../full}/webapp/src/widgets/GridReview.js | 0 .../full}/webapp/src/widgets/Launch.tsx | 0 .../full}/webapp/src/widgets/Prepare.tsx | 0 .../full}/webapp/src/widgets/Review.tsx | 0 .../webapp/src/widgets/TaskRunSummary.tsx | 0 .../widgets/components/ArchitectSelect.tsx | 0 .../widgets/components/BlueprintSelect.tsx | 0 .../src/widgets/components/FormField.tsx | 0 .../src/widgets/components/OptionsForm.tsx | 0 .../src/widgets/components/ProviderSelect.tsx | 0 .../src/widgets/components/RequesterForm.tsx | 0 .../widgets/components/RequesterSelect.tsx | 0 .../{ => client/full}/webapp/tsconfig.json | 0 mephisto/{ => client/full}/webapp/yarn.lock | 0 mephisto/client/{ => review}/review_server.py | 0 mephisto/core/argparse_parser.py | 69 - mephisto/core/config_handler.py | 67 +- mephisto/core/data_browser.py | 72 +- mephisto/core/hydra_config.py | 54 +- mephisto/core/local_database.py | 1369 +-- mephisto/core/logger_core.py | 58 +- mephisto/core/operator.py | 419 +- mephisto/core/registry.py | 170 +- mephisto/core/supervisor.py | 856 +- mephisto/core/task_launcher.py | 217 +- mephisto/core/utils.py | 196 +- mephisto/data_model/agent.py | 13 +- mephisto/data_model/architect.py | 116 +- mephisto/data_model/assignment.py | 312 +- mephisto/data_model/assignment_state.py | 93 +- mephisto/data_model/blueprint.py | 625 +- .../{constants.py => constants/__init__.py} | 0 .../data_model/constants/assignment_state.py | 90 + mephisto/data_model/crowd_provider.py | 141 +- mephisto/data_model/database.py | 582 +- mephisto/data_model/project.py | 2 +- mephisto/data_model/qualification.py | 6 +- mephisto/data_model/requester.py | 6 +- mephisto/data_model/task.py | 315 +- mephisto/data_model/task_config.py | 4 +- mephisto/data_model/task_run.py | 327 + mephisto/data_model/test/architect_tester.py | 14 +- mephisto/data_model/test/blueprint_tester.py | 15 +- .../data_model/test/crowd_provider_tester.py | 6 +- .../test/data_model_database_tester.py | 11 +- mephisto/data_model/test/utils.py | 13 +- mephisto/data_model/unit.py | 321 + mephisto/data_model/worker.py | 10 +- mephisto/operations/config_handler.py | 66 + mephisto/operations/hydra_config.py | 51 + mephisto/operations/logger_core.py | 55 + mephisto/operations/operator.py | 418 + mephisto/operations/registry.py | 173 + mephisto/operations/supervisor.py | 855 ++ mephisto/operations/task_launcher.py | 216 + mephisto/operations/utils.py | 195 + mephisto/providers/__init__.py | 10 + mephisto/providers/mock/__init__.py | 10 + mephisto/providers/mock/mock_agent.py | 95 +- mephisto/providers/mock/mock_datastore.py | 222 +- mephisto/providers/mock/mock_provider.py | 91 +- mephisto/providers/mock/mock_requester.py | 77 +- mephisto/providers/mock/mock_unit.py | 76 +- mephisto/providers/mock/mock_worker.py | 64 +- mephisto/providers/mock/provider_type.py | 10 +- mephisto/providers/mturk/__init__.py | 10 + mephisto/providers/mturk/mturk_agent.py | 110 +- mephisto/providers/mturk/mturk_datastore.py | 292 +- mephisto/providers/mturk/mturk_provider.py | 164 +- mephisto/providers/mturk/mturk_requester.py | 151 +- mephisto/providers/mturk/mturk_unit.py | 250 +- mephisto/providers/mturk/mturk_utils.py | 707 +- mephisto/providers/mturk/mturk_worker.py | 204 +- mephisto/providers/mturk/provider_type.py | 10 +- mephisto/providers/mturk_sandbox/__init__.py | 10 + .../providers/mturk_sandbox/provider_type.py | 10 +- .../mturk_sandbox/sandbox_mturk_agent.py | 44 +- .../mturk_sandbox/sandbox_mturk_provider.py | 77 +- .../mturk_sandbox/sandbox_mturk_requester.py | 61 +- .../mturk_sandbox/sandbox_mturk_unit.py | 46 +- .../mturk_sandbox/sandbox_mturk_worker.py | 65 +- .../mturk/soft_block_workers_by_mturk_id.py | 6 +- .../server/architects/heroku_architect.py | 461 +- mephisto/server/architects/local_architect.py | 185 +- mephisto/server/architects/mock_architect.py | 370 +- .../server/architects/router/build_router.py | 94 +- .../static_task/empty_task_builder.py | 25 +- .../static_task/static_agent_state.py | 118 +- .../abstract/static_task/static_blueprint.py | 189 +- .../static_task/static_task_runner.py | 82 +- .../blueprints/mock/mock_agent_state.py | 62 +- .../server/blueprints/mock/mock_blueprint.py | 94 +- .../blueprints/mock/mock_task_builder.py | 32 +- .../blueprints/mock/mock_task_runner.py | 114 +- .../parlai_chat/parlai_chat_agent_state.py | 122 +- .../parlai_chat/parlai_chat_blueprint.py | 281 +- .../parlai_chat/parlai_chat_task_builder.py | 186 +- .../parlai_chat/parlai_chat_task_runner.py | 273 +- .../static_react_blueprint.py | 95 +- .../static_react_task_builder.py | 43 +- .../static_task/static_html_blueprint.py | 155 +- .../static_task/static_html_task_builder.py | 101 +- mephisto/server/channels/channel.py | 89 +- mephisto/server/channels/websocket_channel.py | 178 +- mephisto/tasks/README.md | 2 - mephisto/tools/__init__.py | 5 + mephisto/tools/data_browser.py | 69 + mephisto/tools/scripts.py | 120 + mephisto/utils/scripts.py | 121 +- test/abstractions/__init__.py | 5 + test/abstractions/architects/__init__.py | 5 + .../architects/test_heroku_architect.py | 12 +- .../architects/test_local_architect.py | 18 +- .../architects/test_mock_architect.py | 19 +- test/abstractions/blueprints/__init__.py | 5 + .../blueprints/test_mock_blueprint.py | 29 +- test/abstractions/providers/__init__.py | 5 + test/abstractions/providers/mturk/__init__.py | 5 + .../providers/mturk/test_mturk.py | 4 +- .../providers/mturk_sandbox/__init__.py | 5 + .../mturk_sandbox/test_mturk_provider.py | 14 +- test/core/test_database.py | 2 +- test/core/test_operator.py | 17 +- test/core/test_supervisor.py | 33 +- test/core/test_task_launcher.py | 14 +- 277 files changed, 33504 insertions(+), 11689 deletions(-) rename mephisto/{providers/mturk/utils => abstractions}/__init__.py (100%) create mode 100644 mephisto/abstractions/architect.py rename mephisto/{server => abstractions}/architects/README.md (100%) rename {test/providers => mephisto/abstractions/architects}/__init__.py (100%) rename {test/providers/mturk => mephisto/abstractions/architects/channels}/__init__.py (100%) create mode 100644 mephisto/abstractions/architects/channels/websocket_channel.py create mode 100644 mephisto/abstractions/architects/heroku_architect.py create mode 100644 mephisto/abstractions/architects/local_architect.py create mode 100644 mephisto/abstractions/architects/mock_architect.py rename {test/providers/mturk_sandbox => mephisto/abstractions/architects/router}/__init__.py (100%) create mode 100644 mephisto/abstractions/architects/router/build_router.py create mode 100644 mephisto/abstractions/architects/router/deploy/package-lock.json create mode 100644 mephisto/abstractions/architects/router/deploy/package.json create mode 100644 mephisto/abstractions/architects/router/deploy/server.js create mode 100644 mephisto/abstractions/architects/router/deploy/static/index.html create mode 100644 mephisto/abstractions/architects/router/deploy/uploads/exists.txt create mode 100644 mephisto/abstractions/blueprint.py create mode 100644 mephisto/abstractions/blueprints/README.md rename {test/server => mephisto/abstractions/blueprints}/__init__.py (100%) create mode 100644 mephisto/abstractions/blueprints/abstract/README.md rename {test/server/architects => mephisto/abstractions/blueprints/abstract}/__init__.py (100%) rename {test/server/blueprints => mephisto/abstractions/blueprints/abstract/static_task}/__init__.py (100%) create mode 100644 mephisto/abstractions/blueprints/abstract/static_task/empty_task_builder.py create mode 100644 mephisto/abstractions/blueprints/abstract/static_task/static_agent_state.py create mode 100644 mephisto/abstractions/blueprints/abstract/static_task/static_blueprint.py create mode 100644 mephisto/abstractions/blueprints/abstract/static_task/static_task_runner.py create mode 100644 mephisto/abstractions/blueprints/mock/__init__.py create mode 100644 mephisto/abstractions/blueprints/mock/mock_agent_state.py create mode 100644 mephisto/abstractions/blueprints/mock/mock_blueprint.py create mode 100644 mephisto/abstractions/blueprints/mock/mock_task_builder.py create mode 100644 mephisto/abstractions/blueprints/mock/mock_task_runner.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/__init__.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/parlai_chat_agent_state.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/parlai_chat_blueprint.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_builder.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_runner.py create mode 100644 mephisto/abstractions/blueprints/parlai_chat/source/package-lock.json create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/.babelrc create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/.eslintrc create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/README.md create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/package-lock.json create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/package.json create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/src/main.js create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/index.html create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/notif.mp3 create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/webpack.config.js create mode 100644 mephisto/abstractions/blueprints/parlai_chat/webapp/yarn.lock create mode 100644 mephisto/abstractions/blueprints/static_html_task/__init__.py create mode 100644 mephisto/abstractions/blueprints/static_html_task/source/.babelrc create mode 100644 mephisto/abstractions/blueprints/static_html_task/source/dev/app.jsx create mode 100644 mephisto/abstractions/blueprints/static_html_task/source/dev/main.js create mode 100644 mephisto/abstractions/blueprints/static_react_task/__init__.py create mode 100644 mephisto/abstractions/blueprints/static_react_task/static_react_blueprint.py create mode 100644 mephisto/abstractions/blueprints/static_react_task/static_react_task_builder.py create mode 100644 mephisto/abstractions/channel.py create mode 100644 mephisto/abstractions/crowd_provider.py create mode 100644 mephisto/abstractions/database.py create mode 100644 mephisto/abstractions/databases/__init__.py create mode 100644 mephisto/abstractions/databases/local_database.py rename mephisto/{ => abstractions}/providers/README.md (100%) create mode 100644 mephisto/abstractions/providers/__init__.py create mode 100644 mephisto/abstractions/providers/mock/__init__.py create mode 100644 mephisto/abstractions/providers/mock/mock_agent.py create mode 100644 mephisto/abstractions/providers/mock/mock_datastore.py create mode 100644 mephisto/abstractions/providers/mock/mock_provider.py create mode 100644 mephisto/abstractions/providers/mock/mock_requester.py create mode 100644 mephisto/abstractions/providers/mock/mock_unit.py create mode 100644 mephisto/abstractions/providers/mock/mock_worker.py create mode 100644 mephisto/abstractions/providers/mock/provider_type.py rename mephisto/{ => abstractions}/providers/mock/wrap_crowd_source.js (100%) create mode 100644 mephisto/abstractions/providers/mturk/__init__.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_agent.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_datastore.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_provider.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_requester.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_unit.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_utils.py create mode 100644 mephisto/abstractions/providers/mturk/mturk_worker.py create mode 100644 mephisto/abstractions/providers/mturk/provider_type.py create mode 100644 mephisto/abstractions/providers/mturk/utils/__init__.py rename mephisto/{ => abstractions}/providers/mturk/utils/script_utils.py (94%) rename mephisto/{ => abstractions}/providers/mturk/wrap_crowd_source.js (100%) create mode 100644 mephisto/abstractions/providers/mturk_sandbox/__init__.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/provider_type.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_agent.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_provider.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_requester.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_unit.py create mode 100644 mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_worker.py rename mephisto/{ => abstractions}/providers/mturk_sandbox/wrap_crowd_source.js (100%) rename mephisto/client/{ => full}/server.py (86%) rename mephisto/{ => client/full}/webapp/.gitattributes (100%) rename mephisto/{ => client/full}/webapp/.gitignore (100%) rename mephisto/{ => client/full}/webapp/README.md (100%) rename mephisto/{ => client/full}/webapp/build/asset-manifest.json (100%) rename mephisto/{ => client/full}/webapp/build/index.html (100%) rename mephisto/{ => client/full}/webapp/build/precache-manifest.6a3f8be9c9b4eda91b48c53412c4ac04.js (100%) create mode 100644 mephisto/client/full/webapp/build/precache-manifest.9f9697fc33c2a769605084eb8123c827.js rename mephisto/{ => client/full}/webapp/build/robots.txt (100%) rename mephisto/{ => client/full}/webapp/build/service-worker.js (100%) rename mephisto/{ => client/full}/webapp/build/static/css/2.d6c513eb.chunk.css (100%) rename mephisto/{ => client/full}/webapp/build/static/css/2.d6c513eb.chunk.css.map (100%) rename mephisto/{ => client/full}/webapp/build/static/css/main.ec5c0f52.chunk.css (100%) rename mephisto/{ => client/full}/webapp/build/static/css/main.ec5c0f52.chunk.css.map (100%) create mode 100644 mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css create mode 100644 mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css.map rename mephisto/{ => client/full}/webapp/build/static/js/2.34d4026e.chunk.js (100%) rename mephisto/{ => client/full}/webapp/build/static/js/2.34d4026e.chunk.js.LICENSE (100%) rename mephisto/{ => client/full}/webapp/build/static/js/2.34d4026e.chunk.js.map (100%) rename mephisto/{ => client/full}/webapp/build/static/js/main.6e109e52.chunk.js (100%) rename mephisto/{ => client/full}/webapp/build/static/js/main.6e109e52.chunk.js.map (100%) create mode 100644 mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js create mode 100644 mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js.map rename mephisto/{ => client/full}/webapp/build/static/js/runtime-main.97447897.js (100%) rename mephisto/{ => client/full}/webapp/build/static/js/runtime-main.97447897.js.map (100%) rename mephisto/{ => client/full}/webapp/build/static/media/Oval.456d8835.svg (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-16.782154b8.ttf (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-16.7fb844a7.woff (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-16.d4f6722b.eot (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-20.90afdd23.eot (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-20.c0e4874e.woff (100%) rename mephisto/{ => client/full}/webapp/build/static/media/icons-20.d1f0f6c1.ttf (100%) rename mephisto/{ => client/full}/webapp/package.json (100%) rename mephisto/{ => client/full}/webapp/public/index.html (100%) rename mephisto/{ => client/full}/webapp/public/robots.txt (100%) rename mephisto/{ => client/full}/webapp/src/App.css (100%) rename mephisto/{ => client/full}/webapp/src/App.tsx (100%) rename mephisto/{ => client/full}/webapp/src/Oval.svg (100%) rename mephisto/{ => client/full}/webapp/src/axios.ts (100%) rename mephisto/{ => client/full}/webapp/src/index.css (100%) rename mephisto/{ => client/full}/webapp/src/index.tsx (100%) rename mephisto/{ => client/full}/webapp/src/lib/Async.ts (100%) rename mephisto/{ => client/full}/webapp/src/lib/toaster.ts (100%) rename mephisto/{ => client/full}/webapp/src/logo.svg (100%) rename mephisto/{ => client/full}/webapp/src/mocks.ts (100%) rename mephisto/{ => client/full}/webapp/src/models.ts (100%) rename mephisto/{ => client/full}/webapp/src/react-app-env.d.ts (100%) rename mephisto/{ => client/full}/webapp/src/service.ts (100%) rename mephisto/{ => client/full}/webapp/src/setupTests.ts (100%) rename mephisto/{ => client/full}/webapp/src/utils.ts (100%) rename mephisto/{ => client/full}/webapp/src/widgets/Base.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/GridReview.js (100%) rename mephisto/{ => client/full}/webapp/src/widgets/Launch.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/Prepare.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/Review.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/TaskRunSummary.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/ArchitectSelect.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/BlueprintSelect.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/FormField.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/OptionsForm.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/ProviderSelect.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/RequesterForm.tsx (100%) rename mephisto/{ => client/full}/webapp/src/widgets/components/RequesterSelect.tsx (100%) rename mephisto/{ => client/full}/webapp/tsconfig.json (100%) rename mephisto/{ => client/full}/webapp/yarn.lock (100%) rename mephisto/client/{ => review}/review_server.py (100%) delete mode 100644 mephisto/core/argparse_parser.py rename mephisto/data_model/{constants.py => constants/__init__.py} (100%) create mode 100644 mephisto/data_model/constants/assignment_state.py create mode 100644 mephisto/data_model/task_run.py create mode 100644 mephisto/data_model/unit.py create mode 100644 mephisto/operations/config_handler.py create mode 100644 mephisto/operations/hydra_config.py create mode 100644 mephisto/operations/logger_core.py create mode 100644 mephisto/operations/operator.py create mode 100644 mephisto/operations/registry.py create mode 100644 mephisto/operations/supervisor.py create mode 100644 mephisto/operations/task_launcher.py create mode 100644 mephisto/operations/utils.py delete mode 100644 mephisto/tasks/README.md create mode 100644 mephisto/tools/__init__.py create mode 100644 mephisto/tools/data_browser.py create mode 100644 mephisto/tools/scripts.py create mode 100644 test/abstractions/__init__.py create mode 100644 test/abstractions/architects/__init__.py rename test/{server => abstractions}/architects/test_heroku_architect.py (88%) rename test/{server => abstractions}/architects/test_local_architect.py (81%) rename test/{server => abstractions}/architects/test_mock_architect.py (74%) create mode 100644 test/abstractions/blueprints/__init__.py rename test/{server => abstractions}/blueprints/test_mock_blueprint.py (79%) create mode 100644 test/abstractions/providers/__init__.py create mode 100644 test/abstractions/providers/mturk/__init__.py rename test/{ => abstractions}/providers/mturk/test_mturk.py (92%) create mode 100644 test/abstractions/providers/mturk_sandbox/__init__.py rename test/{ => abstractions}/providers/mturk_sandbox/test_mturk_provider.py (92%) diff --git a/docs/architecture_overview.md b/docs/architecture_overview.md index d03c933d3..66add2403 100644 --- a/docs/architecture_overview.md +++ b/docs/architecture_overview.md @@ -78,7 +78,7 @@ The classes are all expected to provide an `Args` class, which is a dataclass th There's also the abstraction of the `MephistoDB`, which defines the data operations that Mephisto requires to operate properly. If a specific setup requires specialized data handling, any class implementing this interface could stand in for it. ## Blueprints -The [blueprints](https://github.com/facebookresearch/Mephisto/tree/master/mephisto/server/blueprints) contain all of the related code required to set up a task run. Blueprints may follow a hierarchical structure, in that general functionality can be written into abstract blueprints (which are powerful but perhaps hard to configure) and then downstream blueprints may have more configuration control but less breadth. Much of this can actually require significant overhead, so we've created additional abstract classes that a blueprint must link to an implementation for. These are listed below: +The [blueprints](https://github.com/facebookresearch/Mephisto/tree/master/mephisto/abstractions/blueprints) contain all of the related code required to set up a task run. Blueprints may follow a hierarchical structure, in that general functionality can be written into abstract blueprints (which are powerful but perhaps hard to configure) and then downstream blueprints may have more configuration control but less breadth. Much of this can actually require significant overhead, so we've created additional abstract classes that a blueprint must link to an implementation for. These are listed below: ### BlueprintArgs These define the specific arguments for configuring a blueprint. Some base arguments relevant to all blueprints are provided already, and classes that override `BlueprintArgs` can add anything else they want. ### SharedTaskState diff --git a/docs/hydra_migration.md b/docs/hydra_migration.md index d44549f16..2cee70af3 100644 --- a/docs/hydra_migration.md +++ b/docs/hydra_migration.md @@ -9,10 +9,10 @@ This document shows the transition steps from moving from the old format to the import os import time import shlex -from mephisto.core.operator import Operator -from mephisto.core.utils import get_root_dir -from mephisto.server.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE -from mephisto.utils.scripts import MephistoRunScriptParser, str2bool +from mephisto.operations.operator import Operator +from mephisto.operations.utils import get_root_dir +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE +from mephisto.tools.scripts import MephistoRunScriptParser, str2bool parser = MephistoRunScriptParser() parser.add_argument( @@ -214,7 +214,7 @@ defaults = [ {"conf": "example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass class TestScriptConfig(RunScriptConfig): @@ -321,10 +321,10 @@ operator.wait_for_runs_then_shutdown(skip_input=True, log_rate=30) ```python import os import shlex # shlex is no longer required, as we're not using arg strings -from mephisto.core.operator import Operator -from mephisto.core.utils import get_root_dir -from mephisto.server.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE -from mephisto.utils.scripts import MephistoRunScriptParser, str2bool # RunScriptParser has been deprecated. +from mephisto.operations.operator import Operator +from mephisto.operations.utils import get_root_dir +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE +from mephisto.tools.scripts import MephistoRunScriptParser, str2bool # RunScriptParser has been deprecated. ``` We remove unnecessary or deprecated imports. @@ -334,9 +334,9 @@ We'll need to add a few things. First, `load_db_and_process_config` covers the o Mephisto now defines run scripts and configurations using Hydra and dataclasses, as such you'll need some imports from `dataclasses`, `hydra`, and `omegaconf` (which is the configuration library that powers hydra). ```python import os -from mephisto.core.operator import Operator -from mephisto.utils.scripts import load_db_and_process_config -from mephisto.server.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE, SharedParlAITaskState +from mephisto.operations.operator import Operator +from mephisto.tools.scripts import load_db_and_process_config +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE, SharedParlAITaskState import hydra from omegaconf import DictConfig @@ -349,9 +349,9 @@ from typing import List, Any ```python # parlai_test_script.py import os -from mephisto.core.operator import Operator -from mephisto.utils.scripts import load_db_and_process_config -from mephisto.server.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE, SharedParlAITaskState +from mephisto.operations.operator import Operator +from mephisto.tools.scripts import load_db_and_process_config +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_blueprint import BLUEPRINT_TYPE, SharedParlAITaskState import hydra from omegaconf import DictConfig @@ -368,7 +368,7 @@ defaults = [ {"conf": "example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass class TestScriptConfig(RunScriptConfig): diff --git a/docs/quickstart.md b/docs/quickstart.md index c6f45db56..df56882b2 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -103,7 +103,7 @@ $ cd examples/simple_static_task $ python static_test_script.py mephisto/architect=heroku mephisto.provider.requester_name=my_mturk_user_sandbox Locating heroku... INFO - Creating a task run under task name: html-static-task-example -[mephisto.core.operator][INFO] - Creating a task run under task name: html-static-task-example +[mephisto.operations.operator][INFO] - Creating a task run under task name: html-static-task-example Building server files... ... diff --git a/examples/parlai_chat_task_demo/parlai_test_script.py b/examples/parlai_chat_task_demo/parlai_test_script.py index 20be32d91..aa7d628ac 100644 --- a/examples/parlai_chat_task_demo/parlai_test_script.py +++ b/examples/parlai_chat_task_demo/parlai_test_script.py @@ -6,9 +6,9 @@ import os -from mephisto.core.operator import Operator -from mephisto.utils.scripts import load_db_and_process_config -from mephisto.server.blueprints.parlai_chat.parlai_chat_blueprint import ( +from mephisto.operations.operator import Operator +from mephisto.tools.scripts import load_db_and_process_config +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_blueprint import ( BLUEPRINT_TYPE, SharedParlAITaskState, ) @@ -28,7 +28,7 @@ {"conf": "example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass diff --git a/examples/simple_static_task/examine_results.py b/examples/simple_static_task/examine_results.py index 1d8b00275..b85820184 100644 --- a/examples/simple_static_task/examine_results.py +++ b/examples/simple_static_task/examine_results.py @@ -4,8 +4,8 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from mephisto.core.local_database import LocalMephistoDB -from mephisto.core.data_browser import DataBrowser as MephistoDataBrowser +from mephisto.abstractions.databases.local_database import LocalMephistoDB +from mephisto.tools.data_browser import DataBrowser as MephistoDataBrowser from mephisto.data_model.worker import Worker from mephisto.data_model.assignment import Unit diff --git a/examples/simple_static_task/static_run_with_onboarding.py b/examples/simple_static_task/static_run_with_onboarding.py index 1c43fbb77..664411956 100644 --- a/examples/simple_static_task/static_run_with_onboarding.py +++ b/examples/simple_static_task/static_run_with_onboarding.py @@ -5,11 +5,13 @@ # LICENSE file in the root directory of this source tree. import os -from mephisto.core.operator import Operator -from mephisto.core.utils import get_root_dir -from mephisto.utils.scripts import load_db_and_process_config -from mephisto.server.blueprints.static_task.static_html_blueprint import BLUEPRINT_TYPE -from mephisto.server.blueprints.abstract.static_task.static_blueprint import ( +from mephisto.operations.operator import Operator +from mephisto.operations.utils import get_root_dir +from mephisto.tools.scripts import load_db_and_process_config +from mephisto.abstractions.blueprints.static_html_task.static_html_blueprint import ( + BLUEPRINT_TYPE, +) +from mephisto.abstractions.blueprints.abstract.static_task.static_blueprint import ( SharedStaticTaskState, ) @@ -28,7 +30,7 @@ {"conf": "onboarding_example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass diff --git a/examples/simple_static_task/static_test_script.py b/examples/simple_static_task/static_test_script.py index 5a98517e6..ecbeb2bc5 100644 --- a/examples/simple_static_task/static_test_script.py +++ b/examples/simple_static_task/static_test_script.py @@ -5,10 +5,12 @@ # LICENSE file in the root directory of this source tree. import os -from mephisto.core.operator import Operator -from mephisto.core.utils import get_root_dir -from mephisto.server.blueprints.static_task.static_html_blueprint import BLUEPRINT_TYPE -from mephisto.utils.scripts import load_db_and_process_config +from mephisto.operations.operator import Operator +from mephisto.operations.utils import get_root_dir +from mephisto.abstractions.blueprints.static_html_task.static_html_blueprint import ( + BLUEPRINT_TYPE, +) +from mephisto.tools.scripts import load_db_and_process_config import hydra from omegaconf import DictConfig @@ -25,7 +27,7 @@ {"conf": "example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass diff --git a/examples/static_react_task/run_task.py b/examples/static_react_task/run_task.py index 482729d1d..85e7b1704 100644 --- a/examples/static_react_task/run_task.py +++ b/examples/static_react_task/run_task.py @@ -7,13 +7,13 @@ import os import shutil import subprocess -from mephisto.core.operator import Operator -from mephisto.core.utils import get_root_dir -from mephisto.utils.scripts import load_db_and_process_config -from mephisto.server.blueprints.static_react_task.static_react_blueprint import ( +from mephisto.operations.operator import Operator +from mephisto.operations.utils import get_root_dir +from mephisto.tools.scripts import load_db_and_process_config +from mephisto.abstractions.blueprints.static_react_task.static_react_blueprint import ( BLUEPRINT_TYPE, ) -from mephisto.server.blueprints.abstract.static_task.static_blueprint import ( +from mephisto.abstractions.blueprints.abstract.static_task.static_blueprint import ( SharedStaticTaskState, ) @@ -31,7 +31,7 @@ {"conf": "example"}, ] -from mephisto.core.hydra_config import RunScriptConfig, register_script_config +from mephisto.operations.hydra_config import RunScriptConfig, register_script_config @dataclass diff --git a/mephisto/__init__.py b/mephisto/__init__.py index 1a894d18e..24b1850bd 100644 --- a/mephisto/__init__.py +++ b/mephisto/__init__.py @@ -3,9 +3,9 @@ # 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. -from mephisto.core.registry import fill_registries -from mephisto.core.config_handler import init_config -from mephisto.core.hydra_config import initialize_named_configs +from mephisto.operations.registry import fill_registries +from mephisto.operations.config_handler import init_config +from mephisto.operations.hydra_config import initialize_named_configs __version__ = "0.1.0" diff --git a/mephisto/providers/mturk/utils/__init__.py b/mephisto/abstractions/__init__.py similarity index 100% rename from mephisto/providers/mturk/utils/__init__.py rename to mephisto/abstractions/__init__.py diff --git a/mephisto/abstractions/architect.py b/mephisto/abstractions/architect.py new file mode 100644 index 000000000..935e1edc2 --- /dev/null +++ b/mephisto/abstractions/architect.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +# 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. + +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from typing import Dict, List, Any, ClassVar, Type, TYPE_CHECKING, Callable + +if TYPE_CHECKING: + from mephisto.abstractions.channel import Channel + from mephsito.data_model.packet import Packet + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.database import MephistoDB + from mephisto.abstractions.blueprint import SharedTaskState + from argparse import _ArgumentGroup as ArgumentGroup + + +@dataclass +class ArchitectArgs: + """Base class for arguments to configure architects""" + + _architect_type: str = MISSING + + +class Architect(ABC): + """ + Provides methods for setting up a server somewhere and deploying tasks + onto that server. + """ + + ArgsClass: ClassVar[Type[ArchitectArgs]] = ArchitectArgs + ARCHITECT_TYPE: str + + def __init__( + self, + db: "MephistoDB", + args: DictConfig, + shared_state: "SharedTaskState", + task_run: "TaskRun", + build_dir_root: str, + ): + """ + Initialize this architect with whatever options are provided given + ArgsClass. Parse whatever additional options may be required + for the specific task_run. + + Also set up any required database/memory into the MephistoDB so that + this data can be stored long-term. + """ + raise NotImplementedError() + + @classmethod + def assert_task_args(cls, args: DictConfig, shared_state: "SharedTaskState"): + """ + Assert that the provided arguments are valid. Should + fail if a task launched with these arguments would + not work. + + This should include throwing an exception if the architect + needs login details or something similar given the + arguments passed in. + """ + return + + def get_channels( + self, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, "Packet"], None], + ) -> List["Channel"]: + """ + Return a list of all relevant channels that the Supervisor will + need to register to in order to function + """ + raise NotImplementedError() + + def download_file(self, filename: str, save_dir: str) -> None: + """ + Save the file that is noted as stored on the server to + the desired save location. + """ + raise NotImplementedError() + + def prepare(self) -> str: + """ + Produce the server files that will be deployed to the server + """ + raise NotImplementedError() + + def deploy(self) -> str: + """ + Launch the server, and push the task files to the server. Return + the server URL + """ + raise NotImplementedError() + + def cleanup(self) -> None: + """ + Remove any files that were used for the deployment process that + no longer need to be kept track of now that the task has + been launched. + """ + raise NotImplementedError() + + def shutdown(self) -> None: + """ + Shut down the server launched by this Surveyor, as stored + in the db. + """ + raise NotImplementedError() diff --git a/mephisto/server/architects/README.md b/mephisto/abstractions/architects/README.md similarity index 100% rename from mephisto/server/architects/README.md rename to mephisto/abstractions/architects/README.md diff --git a/test/providers/__init__.py b/mephisto/abstractions/architects/__init__.py similarity index 100% rename from test/providers/__init__.py rename to mephisto/abstractions/architects/__init__.py diff --git a/test/providers/mturk/__init__.py b/mephisto/abstractions/architects/channels/__init__.py similarity index 100% rename from test/providers/mturk/__init__.py rename to mephisto/abstractions/architects/channels/__init__.py diff --git a/mephisto/abstractions/architects/channels/websocket_channel.py b/mephisto/abstractions/architects/channels/websocket_channel.py new file mode 100644 index 000000000..57a12b81a --- /dev/null +++ b/mephisto/abstractions/architects/channels/websocket_channel.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 + +# 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. + +from typing import Callable, Optional +from mephisto.data_model.packet import Packet +from mephisto.abstractions.channel import Channel, STATUS_CHECK_TIME + +import errno +import websocket +import threading +import json +import time + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + + +class WebsocketChannel(Channel): + """ + Channel for communicating with a server via websockets. + """ + + def __init__( + self, + channel_id: str, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, Packet], None], + socket_url: str, + ): + """ + Create a channel by the given name, and initialize any resources that + will later be required during the `open` call. + + Requires a socket_url to connect with. + """ + super().__init__( + channel_id=channel_id, + on_channel_open=on_channel_open, + on_catastrophic_disconnect=on_catastrophic_disconnect, + on_message=on_message, + ) + self.socket_url = socket_url + self.socket: Optional[websocket.WebSocketApp] = None + self.thread: Optional[threading.Thread] = None + self._is_alive = False + self._is_closed = False + + def is_closed(self): + """ + Return whether or not this connection has been explicitly closed + by the supervisor or another source. + """ + return self._is_closed + + def close(self): + """ + Close this channel, and ensure that all threads and surrounding + resources are cleaned up + """ + self._is_closed = True + try: + self.socket.close() + except Exception: + # socket already closed + pass + self._is_alive = False + if self.thread is not None: + self.thread.join() + + def is_alive(self): + """Return if this channel is actively able to send/recieve messages.""" + return self._is_alive + + def open(self): + """Set up a socket handling thread.""" + + def on_socket_open(*args): + self._is_alive = True + self.on_channel_open(self.channel_id) + logger.info(f"channel open {args}") + + def on_error(ws, error): + if hasattr(error, "errno"): + if error.errno == errno.ECONNREFUSED: + # TODO(CLEAN) replace with channel exception + raise Exception( + f"Socket {self.socket_url} refused connection, cancelling" + ) + else: + logger.error(f"Socket logged error: {error}") + if isinstance(error, websocket._exceptions.WebSocketException): + return + + import traceback + + traceback.print_exc() + try: + # Close the socket to attempt to reconnect + self.socket.close() + self.socket.keep_running = False + except Exception: + # TODO(CLEAN) only catch socket closed connection + # Already closed + pass + + def on_disconnect(*args): + """Disconnect event is a no-op for us, as the server reconnects + automatically on a retry. + """ + # TODO(OWN) we need to set a timeout for reconnecting to the server, + # if it fails it's time to call on_catastrophic_disconnect + pass + + def on_message(*args): + """Incoming message handler defers to the internal handler""" + try: + packet_dict = json.loads(args[1]) + packet = Packet.from_dict(packet_dict) + self.on_message(self.channel_id, packet) + except Exception as e: + # TODO(CLEAN) properly handle only failed from_dict calls + logger.exception(repr(e), exc_info=True) + raise + + def run_socket(*args): + while not self._is_closed: + try: + socket = websocket.WebSocketApp( + self.socket_url, + on_message=on_message, + on_error=on_error, + on_close=on_disconnect, + ) + self.socket = socket + socket.on_open = on_socket_open + socket.run_forever(ping_interval=8 * STATUS_CHECK_TIME) + except Exception as e: + logger.exception( + f"Socket error {repr(e)}, attempting restart", exc_info=True + ) + time.sleep(0.2) + + # Start listening thread + self.thread = threading.Thread( + target=run_socket, name=f"socket-thread-{self.socket_url}" + ) + self.thread.start() + + def send(self, packet: "Packet") -> bool: + """ + Send the packet given to the intended recipient. + Return True on success and False on failure. + """ + if self.socket is None: + return False + try: + data = packet.to_sendable_dict() + self.socket.send(json.dumps(data)) + except websocket.WebSocketConnectionClosedException: + # The channel died mid-send, wait for it to come back up + return False + except BrokenPipeError: + # The channel died mid-send, wait for it to come back up + return False + except Exception as e: + logger.exception( + f"Unexpected socket error occured: {repr(e)}", exc_info=True + ) + return False + return True diff --git a/mephisto/abstractions/architects/heroku_architect.py b/mephisto/abstractions/architects/heroku_architect.py new file mode 100644 index 000000000..9b6dd2cc1 --- /dev/null +++ b/mephisto/abstractions/architects/heroku_architect.py @@ -0,0 +1,460 @@ +#!/usr/bin/env python3 + +# 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 getpass +import glob +import hashlib +import netrc +import os +import platform +import sh +import shlex +import shutil +import subprocess +import sys +import time +import requests +import re +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from mephisto.operations.utils import get_mephisto_tmp_dir +from mephisto.abstractions.architect import Architect, ArchitectArgs +from mephisto.abstractions.architects.router.build_router import build_router +from mephisto.abstractions.architects.channels.websocket_channel import WebsocketChannel +from mephisto.operations.registry import register_mephisto_abstraction +from typing import Any, Tuple, List, Dict, Optional, TYPE_CHECKING, Callable + +if TYPE_CHECKING: + from mephisto.abstractions.channel import Channel + from mephsito.data_model.packet import Packet + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.database import MephistoDB + from mephisto.abstractions.blueprint import SharedTaskState + from argparse import _ArgumentGroup as ArgumentGroup + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + +ARCHITECT_TYPE = "heroku" + +USER_NAME = getpass.getuser() +HEROKU_SERVER_BUILD_DIRECTORY = "heroku_server" +HEROKU_CLIENT_URL = ( + "https://cli-assets.heroku.com/heroku-cli/channels/stable/heroku-cli" +) + +HEROKU_WAIT_TIME = 3 + +HEROKU_TMP_DIR = os.path.join(get_mephisto_tmp_dir(), "heroku") +os.makedirs(HEROKU_TMP_DIR, exist_ok=True) + + +@dataclass +class HerokuArchitectArgs(ArchitectArgs): + """Additional arguments for configuring a heroku architect""" + + _architect_type: str = ARCHITECT_TYPE + use_hobby: bool = field( + default=False, metadata={"help": "Launch on the Heroku Hobby tier"} + ) + heroku_team: Optional[str] = field( + default=MISSING, metadata={"help": "Heroku team to use for this launch"} + ) + + +@register_mephisto_abstraction() +class HerokuArchitect(Architect): + """ + Sets up a server on heroku and deploys the task on that server + """ + + ArgsClass = HerokuArchitectArgs + ARCHITECT_TYPE = ARCHITECT_TYPE + + def __init__( + self, + db: "MephistoDB", + args: DictConfig, + shared_state: "SharedTaskState", + task_run: "TaskRun", + build_dir_root: str, + ): + """ + Ensure heroku credentials are setup, then prepare the necessary files + for launching for this task. + + All necessary paths should be built in the init or stored in the database + such that a re-init on the same task run can pull the server information. + + This means that we can shutdown a server that is still running after a + catastrophic failure. + """ + # TODO(#102) put the expected info into the MephistoDB rather than storing here? + # Servers will have a status which needs to be kept track of. + self.args = args + self.task_run = task_run + self.deploy_name = f"{task_run.get_task().task_name}_{task_run.db_id}" + self.build_dir = build_dir_root + + # Cache-able parameters + self.__heroku_app_name: Optional[str] = None + self.__heroku_executable_path: Optional[str] = None + self.__heroku_user_identifier: Optional[str] = None + + def _get_socket_urls(self) -> List[str]: + """Returns the path to the heroku app socket""" + heroku_app_name = self.__get_app_name() + return ["wss://{}.herokuapp.com/".format(heroku_app_name)] + + def get_channels( + self, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, "Packet"], None], + ) -> List["Channel"]: + """ + Return a list of all relevant channels that the Supervisor will + need to register to in order to function + """ + urls = self._get_socket_urls() + return [ + WebsocketChannel( + f"heroku_channel_{self.deploy_name}_{idx}", + on_channel_open=on_channel_open, + on_catastrophic_disconnect=on_catastrophic_disconnect, + on_message=on_message, + socket_url=url, + ) + for idx, url in enumerate(urls) + ] + + def download_file(self, target_filename: str, save_dir: str) -> None: + """ + Heroku architects need to download the file + """ + heroku_app_name = self.__get_app_name() + target_url = ( + f"https://{heroku_app_name}.herokuapp.com/download_file/{target_filename}" + ) + dest_path = os.path.join(save_dir, target_filename) + r = requests.get(target_url, stream=True) + + with open(dest_path, "wb") as out_file: + for chunk in r.iter_content(chunk_size=1024): + if chunk: + out_file.write(chunk) + + @classmethod + def assert_task_args(cls, args: DictConfig, shared_state: "SharedTaskState"): + """ + Assert that the provided arguments are valid. Should + fail if a task launched with these arguments would + not work. + + This should include throwing an exception if the architect + needs login details or something similar given the + arguments passed in. + """ + heroku_executable_path = HerokuArchitect.get_heroku_client_path() + try: + output = subprocess.check_output( + shlex.split(heroku_executable_path + " auth:whoami") + ) + except subprocess.CalledProcessError: + raise Exception( + "A free Heroku account is required for launching tasks via " + "the HerokuArchitect. Please register at " + "https://signup.heroku.com/ and run `{} login` at the terminal " + "to login to Heroku before trying to use HerokuArchitect." + "".format(heroku_executable_path) + ) + return + + @staticmethod + def get_heroku_client_path() -> str: + """ + Get the path to the heroku executable client, download a new one if it + doesnt exist. + """ + print("Locating heroku...") + # Install Heroku CLI + os_name = None + bit_architecture = None + + # Get the platform we are working on + if sys.platform == "darwin": # Mac OS X + os_name = "darwin" + elif sys.platform.startswith("linux"): # Linux + os_name = "linux" + else: + os_name = "windows" + + # Find our architecture + bit_architecture_info = platform.architecture()[0] + if "64bit" in bit_architecture_info: + bit_architecture = "x64" + else: + bit_architecture = "x86" + + # Find existing heroku files to use + existing_heroku_directory_names = glob.glob( + os.path.join(HEROKU_TMP_DIR, "heroku-cli-*") + ) + if len(existing_heroku_directory_names) == 0: + print("Getting heroku") + if os.path.exists(os.path.join(HEROKU_TMP_DIR, "heroku.tar.gz")): + os.remove(os.path.join(HEROKU_TMP_DIR, "heroku.tar.gz")) + + # Get the heroku client and unzip + tar_path = os.path.join(HEROKU_TMP_DIR, "heroku.tar.gz") + sh.wget( + shlex.split( + "{}-{}-{}.tar.gz -O {}".format( + HEROKU_CLIENT_URL, os_name, bit_architecture, tar_path + ) + ) + ) + sh.tar(shlex.split(f"-xvzf {tar_path} -C {HEROKU_TMP_DIR}")) + + # Clean up the tar + if os.path.exists(tar_path): + os.remove(tar_path) + + heroku_directory_name = os.path.basename( + glob.glob(os.path.join(HEROKU_TMP_DIR, "heroku-cli-*"))[0] + ) + heroku_directory_path = os.path.join(HEROKU_TMP_DIR, heroku_directory_name) + return os.path.join(heroku_directory_path, "bin", "heroku") + + def __get_heroku_client(self) -> Tuple[str, str]: + """ + Get an authorized heroku client path and authorization token + """ + if ( + self.__heroku_executable_path is None + or self.__heroku_user_identifier is None + ): + heroku_executable_path = HerokuArchitect.get_heroku_client_path() + + # get heroku credentials + heroku_user_identifier = None + while not heroku_user_identifier: + try: + output = subprocess.check_output( + shlex.split(heroku_executable_path + " auth:whoami") + ) + output = subprocess.check_output( + shlex.split(heroku_executable_path + " auth:token") + ) + heroku_user_identifier = netrc.netrc( + os.path.join(os.path.expanduser("~"), ".netrc") + ).hosts["api.heroku.com"][0] + except subprocess.CalledProcessError: + print( + "A free Heroku account is required for launching MTurk tasks. " + "Please register at https://signup.heroku.com/ and run `{} " + "login` at the terminal to login to Heroku, and then run this " + "program again.".format(heroku_executable_path) + ) + raise Exception("Please login to heroku before trying again.") + self.__heroku_executable_path = heroku_executable_path + self.__heroku_user_identifier = heroku_user_identifier + return self.__heroku_executable_path, self.__heroku_user_identifier + + def __get_build_directory(self) -> str: + """ + Return the string where the server should be built in. + """ + return os.path.join( + self.build_dir, + "{}_{}".format(HEROKU_SERVER_BUILD_DIRECTORY, self.deploy_name), + ) + + def __get_app_name(self) -> str: + """ + Get the name of the heroku app associated with this task + """ + if self.__heroku_app_name is None: + _, heroku_user_identifier = self.__get_heroku_client() + heroku_app_name = ( + "{}-{}-{}".format( + USER_NAME, + self.deploy_name, + hashlib.md5(heroku_user_identifier.encode("utf-8")).hexdigest(), + ) + )[:30] + heroku_app_name = heroku_app_name.replace("_", "-") + while heroku_app_name[-1] == "-": + heroku_app_name = heroku_app_name[:-1] + self.__heroku_app_name = re.sub(r"[^a-zA-Z0-9-]", "", heroku_app_name) + return self.__heroku_app_name + + def __compile_server(self) -> str: + """ + Move the required task files to a specific directory to be deployed to + heroku directly. Return the location that the packaged files are + now prepared in. + """ + print("Building server files...") + heroku_server_development_root = self.__get_build_directory() + os.makedirs(heroku_server_development_root) + heroku_server_development_path = build_router( + heroku_server_development_root, self.task_run + ) + return heroku_server_development_path + + def __setup_heroku_server(self) -> str: + """ + Deploy the server using the setup server directory, return the URL + """ + + heroku_executable_path, heroku_user_identifier = self.__get_heroku_client() + server_dir = self.__get_build_directory() + + print("Heroku: Starting server...") + + heroku_server_directory_path = os.path.join(server_dir, "router") + sh.git(shlex.split(f"-C {heroku_server_directory_path} init")) + + heroku_app_name = self.__get_app_name() + + # Create or attach to the server + return_dir = os.getcwd() + os.chdir(heroku_server_directory_path) + try: + if self.args.architect.get("heroku_team", None) is not None: + subprocess.check_output( + shlex.split( + "{} create {} --team {}".format( + heroku_executable_path, + heroku_app_name, + self.args.architect.heroku_team, + ) + ) + ) + else: + subprocess.check_output( + shlex.split( + "{} create {}".format(heroku_executable_path, heroku_app_name) + ) + ) + except subprocess.CalledProcessError as e: # User has too many apps? + # TODO(#93) check response codes to determine what actually happened + logger.exception(e, exc_info=True) + sh.rm(shlex.split("-rf {}".format(heroku_server_directory_path))) + raise Exception( + "You have hit your limit on concurrent apps with heroku, which are" + " required to run multiple concurrent tasks.\nPlease wait for some" + " of your existing tasks to complete. If you have no tasks " + "running, login to heroku and delete some of the running apps or " + "verify your account to allow more concurrent apps" + ) + + # Enable WebSockets + try: + subprocess.check_output( + shlex.split( + "{} features:enable http-session-affinity".format( + heroku_executable_path + ) + ) + ) + except subprocess.CalledProcessError: # Already enabled WebSockets + pass + os.chdir(return_dir) + + # commit and push to the heroku server + sh.git(shlex.split(f"-C {heroku_server_directory_path} add -A")) + sh.git(shlex.split(f'-C {heroku_server_directory_path} commit -m "app"')) + sh.git(shlex.split(f"-C {heroku_server_directory_path} push -f heroku master")) + + os.chdir(heroku_server_directory_path) + subprocess.check_output( + shlex.split("{} ps:scale web=1".format(heroku_executable_path)) + ) + + if self.args.architect.use_hobby is True: + try: + subprocess.check_output( + shlex.split("{} dyno:type Hobby".format(heroku_executable_path)) + ) + except subprocess.CalledProcessError: # User doesn't have hobby access + self.__delete_heroku_server() + sh.rm(shlex.split("-rf {}".format(heroku_server_directory_path))) + raise Exception( + "Server launched with hobby flag but account cannot create " + "hobby servers." + ) + os.chdir(return_dir) + + time.sleep(HEROKU_WAIT_TIME) + + return "https://{}.herokuapp.com".format(heroku_app_name) + + def __delete_heroku_server(self): + """ + Remove the heroku server associated with this task run + """ + heroku_executable_path, heroku_user_identifier = self.__get_heroku_client() + heroku_app_name = self.__get_app_name() + print("Heroku: Deleting server: {}".format(heroku_app_name)) + subprocess.check_output( + shlex.split( + "{} destroy {} --confirm {}".format( + heroku_executable_path, heroku_app_name, heroku_app_name + ) + ) + ) + time.sleep(HEROKU_WAIT_TIME) + + def server_is_running(self) -> bool: + """ + Utility function to check if the given heroku app (by app-name) is + still running + """ + heroku_executable_path, _token = self.__get_heroku_client() + app_name = self.__get_app_name() + output = subprocess.check_output(shlex.split(heroku_executable_path + " apps")) + all_apps = str(output, "utf-8") + return app_name in all_apps + + def build_is_clean(self) -> bool: + """ + Utility function to see if the build has been cleaned up + """ + server_dir = self.__get_build_directory() + return not os.path.exists(server_dir) + + def prepare(self) -> str: + """ + Produce the server files that will be deployed to the server + """ + return self.__compile_server() + + def deploy(self) -> str: + """ + Launch the server, and push the task files to the server. Return + the server URL + """ + return self.__setup_heroku_server() + + def cleanup(self) -> None: + """ + Remove any files that were used for the deployment process that + no longer need to be kept track of now that the task has + been launched. + """ + server_dir = self.__get_build_directory() + sh.rm(shlex.split("-rf {}".format(server_dir))) + + def shutdown(self) -> None: + """ + Shut down the server launched by this Architect, as stored + in the db. + """ + self.__delete_heroku_server() diff --git a/mephisto/abstractions/architects/local_architect.py b/mephisto/abstractions/architects/local_architect.py new file mode 100644 index 000000000..7bbde866b --- /dev/null +++ b/mephisto/abstractions/architects/local_architect.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 + +# 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 os +import signal +import subprocess +import sh +import shutil +import shlex +import time +import requests + +from mephisto.abstractions.architect import Architect, ArchitectArgs +from dataclasses import dataclass, field +from mephisto.operations.registry import register_mephisto_abstraction +from typing import Any, Optional, Dict, List, TYPE_CHECKING, Callable + +if TYPE_CHECKING: + from mephisto.abstractions.channel import Channel + from mephsito.data_model.packet import Packet + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.database import MephistoDB + from argparse import _ArgumentGroup as ArgumentGroup + from omegaconf import DictConfig + from mephisto.abstractions.blueprint import SharedTaskState + +from mephisto.abstractions.architects.router.build_router import build_router +from mephisto.abstractions.architects.channels.websocket_channel import WebsocketChannel +from mephisto.operations.utils import get_mephisto_tmp_dir + +ARCHITECT_TYPE = "local" + + +@dataclass +class LocalArchitectArgs(ArchitectArgs): + """Additional arguments for configuring a local architect""" + + _architect_type: str = ARCHITECT_TYPE + hostname: str = field( + default="localhost", metadata={"help": "Addressible location of the server"} + ) + port: str = field(default="3000", metadata={"help": "Port to launch the server on"}) + + +@register_mephisto_abstraction() +class LocalArchitect(Architect): + """ + Provides methods for setting up a server locally and deploying tasks + onto that server. + """ + + ArgsClass = LocalArchitectArgs + ARCHITECT_TYPE = ARCHITECT_TYPE + + def __init__( + self, + db: "MephistoDB", + args: "DictConfig", + shared_state: "SharedTaskState", + task_run: "TaskRun", + build_dir_root: str, + ): + """Create an architect for use in testing""" + self.task_run = task_run + self.build_dir = build_dir_root + self.task_run_id = task_run.db_id + # TODO(#102) move some of this into the db, server status + # needs to be in order to restart + self.server_process_pid: Optional[int] = None + self.server_process: Optional[subprocess.Popen] = None + self.server_dir: Optional[str] = None + self.running_dir: Optional[str] = None + self.hostname: Optional[str] = args.architect.hostname + self.port: Optional[str] = args.architect.port + self.cleanup_called = False + + def _get_socket_urls(self) -> List[str]: + """Return the path to the local server socket""" + assert self.hostname is not None, "No hostname for socket" + assert self.port is not None, "No ports for socket" + if "https://" in self.hostname: + basename = self.hostname.split("https://")[1] + protocol = "wss" + elif "http://" in self.hostname: + basename = self.hostname.split("http://")[1] + protocol = "ws" + else: + basename = self.hostname + protocol = "ws" + + if basename in ["localhost", "127.0.0.1"]: + protocol = "ws" + + return [f"{protocol}://{basename}:{self.port}/"] + + def get_channels( + self, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, "Packet"], None], + ) -> List["Channel"]: + """ + Return a list of all relevant channels that the Supervisor will + need to register to in order to function + """ + urls = self._get_socket_urls() + return [ + WebsocketChannel( + f"local_channel_{self.task_run_id}_{idx}", + on_channel_open=on_channel_open, + on_catastrophic_disconnect=on_catastrophic_disconnect, + on_message=on_message, + socket_url=url, + ) + for idx, url in enumerate(urls) + ] + + def download_file(self, target_filename: str, save_dir: str) -> None: + """ + Local architects can just move from the local directory + """ + assert self.running_dir is not None, "cannot download a file if not running" + source_file = os.path.join("/tmp/", target_filename) + dest_path = os.path.join(save_dir, target_filename) + shutil.copy2(source_file, dest_path) + + def prepare(self) -> str: + """Mark the preparation call""" + self.server_dir = build_router(self.build_dir, self.task_run) + return self.server_dir + + def deploy(self) -> str: + """Deploy the server from a local folder for this task""" + assert self.server_dir is not None, "Deploy called before prepare" + self.running_dir = os.path.join( + get_mephisto_tmp_dir(), f"local_server_{self.task_run_id}", "server" + ) + + shutil.copytree(self.server_dir, self.running_dir) + + return_dir = os.getcwd() + os.chdir(self.running_dir) + self.server_process = subprocess.Popen( + ["node", "server.js"], + preexec_fn=os.setpgrp, + env=dict(os.environ, PORT=f"{self.port}"), + ) + self.server_process_pid = self.server_process.pid + os.chdir(return_dir) + + time.sleep(1) + print("Server running locally with pid {}.".format(self.server_process_pid)) + host = self.hostname + port = self.port + if host is None: + host = input( + "Please enter the public server address, like https://hostname.com: " + ) + self.hostname = host + if port is None: + port = input("Please enter the port given above, likely 3000: ") + self.port = port + return "{}:{}".format(host, port) + + def cleanup(self) -> None: + """Cleanup the built directory""" + assert self.server_dir is not None, "Cleanup called before prepare" + sh.rm(shlex.split("-rf " + self.server_dir)) + + def shutdown(self) -> None: + """Find the server process, shut it down, then remove the build directory""" + assert self.running_dir is not None, "shutdown called before deploy" + if self.server_process is None: + assert self.server_process_pid is not None, "No server id to kill" + os.kill(self.server_process_pid, signal.SIGTERM) + else: + self.server_process.terminate() + self.server_process.wait() + sh.rm(shlex.split("-rf " + self.running_dir)) diff --git a/mephisto/abstractions/architects/mock_architect.py b/mephisto/abstractions/architects/mock_architect.py new file mode 100644 index 000000000..70eb07afe --- /dev/null +++ b/mephisto/abstractions/architects/mock_architect.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python3 + +# 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 tornado +from tornado.websocket import WebSocketHandler +import os +import threading +import uuid +import json +import time + +from mephisto.abstractions.architect import Architect, ArchitectArgs +from dataclasses import dataclass, field +from mephisto.data_model.packet import ( + PACKET_TYPE_ALIVE, + PACKET_TYPE_NEW_WORKER, + PACKET_TYPE_NEW_AGENT, + PACKET_TYPE_AGENT_ACTION, + PACKET_TYPE_SUBMIT_ONBOARDING, + PACKET_TYPE_REQUEST_AGENT_STATUS, + PACKET_TYPE_GET_INIT_DATA, +) +from mephisto.operations.registry import register_mephisto_abstraction +from mephisto.abstractions.architects.channels.websocket_channel import WebsocketChannel +from typing import List, Dict, Any, Optional, TYPE_CHECKING, Callable + +if TYPE_CHECKING: + from mephisto.abstractions.channel import Channel + from mephsito.data_model.packet import Packet + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.database import MephistoDB + from argparse import _ArgumentGroup as ArgumentGroup + from omegaconf import DictConfig + from mephisto.abstractions.blueprint import SharedTaskState + +MOCK_DEPLOY_URL = "MOCK_DEPLOY_URL" +ARCHITECT_TYPE = "mock" + + +def get_rand_id(): + return str(uuid.uuid4()) + + +@dataclass +class MockArchitectArgs(ArchitectArgs): + """Additional arguments for configuring a mock architect""" + + _architect_type: str = ARCHITECT_TYPE + should_run_server: bool = field( + default=False, metadata={"help": "Addressible location of the server"} + ) + port: str = field(default="3000", metadata={"help": "Port to launch the server on"}) + + +class SocketHandler(WebSocketHandler): + def __init__(self, *args, **kwargs): + self.subs: Dict[int, "SocketHandler"] = kwargs.pop("subs") + self.app: "MockServer" = kwargs.pop("app") + self.sid = get_rand_id() + super().__init__(*args, **kwargs) + + def open(self): + """ + Opens a websocket and assigns a random UUID that is stored in the class-level + `subs` variable. + """ + if self.sid not in self.subs.values(): + self.subs[self.sid] = self + + def on_close(self): + """ + Runs when a socket is closed. + """ + del self.subs[self.sid] + + def on_message(self, message_text): + """ + Callback that runs when a new message is received from a client See the + chat_service README for the resultant message structure. + Args: + message_text: A stringified JSON object with a text or attachment key. + `text` should contain a string message and `attachment` is a dict. + See `WebsocketAgent.put_data` for more information about the + attachment dict structure. + """ + message = json.loads(message_text) + if message["packet_type"] == PACKET_TYPE_ALIVE: + self.app.last_alive_packet = message + elif message["packet_type"] == PACKET_TYPE_AGENT_ACTION: + self.app.actions_observed += 1 + elif message["packet_type"] != PACKET_TYPE_REQUEST_AGENT_STATUS: + self.app.last_packet = message + + def check_origin(self, origin): + return True + + +class AliveHandler(tornado.web.RequestHandler): + """Simple handler for is_alive""" + + def get(self, eids): + pass # Default behavior returns 200 + + +class MockServer(tornado.web.Application): + """ + Tornado-based server that with hooks for sending specific + messages through socket connections and such + """ + + def __init__(self, port): + self.subs = {} + self.port = port + self.running_instance = None + self.last_alive_packet: Optional[Dict[str, Any]] = None + self.actions_observed = 0 + self.last_packet: Optional[Dict[str, Any]] = None + tornado_settings = { + "autoescape": None, + "debug": "/dbg/" in __file__, + "compiled_template_cache": False, + "static_url_prefix": "/static/", + "debug": True, + } + handlers = [ + ("/socket", SocketHandler, {"subs": self.subs, "app": self}), + ("/is_alive", AliveHandler, {}), + ] + super(MockServer, self).__init__(handlers, **tornado_settings) + + def __server_thread_fn(self): + """ + Main loop for the application + """ + self.running_instance = tornado.ioloop.IOLoop() + http_server = tornado.httpserver.HTTPServer(self, max_buffer_size=1024 ** 3) + http_server.listen(self.port) + self.running_instance.start() + http_server.stop() + + def _get_sub(self): + """Return the subscriber socket to write to""" + return list(self.subs.values())[0] + + def _send_message(self, message): + """Send the given message back to the mephisto client""" + failed_attempts = 0 + last_exception = None + while failed_attempts < 5: + try: + socket = self._get_sub() + message_json = json.dumps(message) + socket.write_message(message_json) + last_exception = None + break + except Exception as e: + last_exception = e + time.sleep(0.2) + failed_attempts += 1 + finally: + time.sleep(0.1) + if last_exception is not None: + raise last_exception + + def send_agent_act(self, agent_id, act_content): + """ + Send a packet from the given agent with + the given content + """ + self._send_message( + { + "packet_type": PACKET_TYPE_AGENT_ACTION, + "sender_id": agent_id, + "receiver_id": "Mephisto", + "data": act_content, + } + ) + + def request_init_data(self, agent_id): + """ + Send a packet from the given agent with + the given content + """ + self._send_message( + { + "packet_type": PACKET_TYPE_GET_INIT_DATA, + "sender_id": agent_id, + "receiver_id": "Mephisto", + "data": { + "request_id": agent_id + str(time.time()), + "provider_data": { + "agent_id": agent_id, + }, + }, + } + ) + + def register_mock_agent(self, worker_id, agent_details): + """ + Send a packet asking to register a mock agent. + """ + self._send_message( + { + "packet_type": PACKET_TYPE_NEW_AGENT, + "sender_id": "MockServer", + "receiver_id": "Mephisto", + "data": { + "request_id": agent_details, + "provider_data": { + "worker_id": worker_id, + "agent_registration_id": agent_details, + }, + }, + } + ) + + def register_mock_agent_after_onboarding(self, worker_id, agent_id, onboard_data): + """ + Send a packet asking to register a mock agent. + """ + onboard_data["request_id"] = "1234" + self._send_message( + { + "packet_type": PACKET_TYPE_SUBMIT_ONBOARDING, + "sender_id": agent_id, + "receiver_id": "Mephisto", + "data": onboard_data, + } + ) + + def register_mock_worker(self, worker_name): + """ + send a packet asking to register a mock worker. + """ + self._send_message( + { + "packet_type": PACKET_TYPE_NEW_WORKER, + "sender_id": "MockServer", + "receiver_id": "Mephisto", + "data": { + "request_id": worker_name, + "provider_data": {"worker_name": worker_name}, + }, + } + ) + + def disconnect_mock_agent(self, agent_id): + """ + Mark a mock agent as disconnected. + """ + # TODO(#97) implement when handling disconnections + pass + + def launch_mock(self): + """ + Start the primary loop for this application + """ + self.__server_thread = threading.Thread(target=self.__server_thread_fn) + self.__server_thread.start() + + def shutdown_mock(self): + """ + Defined to shutown the tornado application. + """ + + def stop_and_free(): + self.running_instance.stop() + + self.running_instance.add_callback(stop_and_free) + self.__server_thread.join() + + +@register_mephisto_abstraction() +class MockArchitect(Architect): + """ + The MockArchitect runs a mock server on the localhost so that + we can send special packets and assert connections have been made + """ + + ArgsClass = MockArchitectArgs + ARCHITECT_TYPE = ARCHITECT_TYPE + + def __init__( + self, + db: "MephistoDB", + args: "DictConfig", + shared_state: "SharedTaskState", + task_run: "TaskRun", + build_dir_root: str, + ): + """Create an architect for use in testing""" + self.task_run = task_run + self.build_dir = build_dir_root + self.task_run_id = task_run.db_id + self.should_run_server = args.architect.should_run_server + self.port = args.architect.port + self.server: Optional["MockServer"] = None + # TODO(#97) track state in parent class? + self.prepared = False + self.deployed = False + self.cleaned = False + self.did_shutdown = False + + def _get_socket_urls(self) -> List[str]: + """Return the path to the local server socket""" + assert self.port is not None, "No ports for socket" + return [f"ws://localhost:{self.port}/socket"] + + def get_channels( + self, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, "Packet"], None], + ) -> List["Channel"]: + """ + Return a list of all relevant channels that the Supervisor will + need to register to in order to function + """ + urls = self._get_socket_urls() + return [ + WebsocketChannel( + f"mock_channel_{self.task_run_id}_{idx}", + on_channel_open=on_channel_open, + on_catastrophic_disconnect=on_catastrophic_disconnect, + on_message=on_message, + socket_url=url, + ) + for idx, url in enumerate(urls) + ] + + def download_file(self, target_filename: str, save_dir: str) -> None: + """ + Mock architects can just pretend to write a file + """ + with open(os.path.join(save_dir, target_filename), "wb") as fp: + fp.write(b"mock\n") + + def prepare(self) -> str: + """Mark the preparation call""" + self.prepared = True + built_dir = os.path.join( + self.build_dir, "mock_build_{}".format(self.task_run_id) + ) + os.makedirs(built_dir) + return built_dir + + def deploy(self) -> str: + """Mock a deploy or deploy a mock server, depending on settings""" + self.deployed = True + if not self.should_run_server: + return MOCK_DEPLOY_URL + else: + self.server = MockServer(self.port) + self.server.launch_mock() + return f"http://localhost:{self.port}/" + + def cleanup(self) -> None: + """Mark the cleanup call""" + self.cleaned = True + + def shutdown(self) -> None: + """Mark the shutdown call""" + self.did_shutdown = True + if self.should_run_server and self.server is not None: + self.server.shutdown_mock() diff --git a/test/providers/mturk_sandbox/__init__.py b/mephisto/abstractions/architects/router/__init__.py similarity index 100% rename from test/providers/mturk_sandbox/__init__.py rename to mephisto/abstractions/architects/router/__init__.py diff --git a/mephisto/abstractions/architects/router/build_router.py b/mephisto/abstractions/architects/router/build_router.py new file mode 100644 index 000000000..e4baaa0ed --- /dev/null +++ b/mephisto/abstractions/architects/router/build_router.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +# 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 mephisto.abstractions.architects.router as router_module +import os +import sh +import shutil +import shlex +import subprocess +import json + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + +ROUTER_ROOT_DIR = os.path.dirname(router_module.__file__) +SERVER_SOURCE_ROOT = os.path.join(ROUTER_ROOT_DIR, "deploy") +CROWD_SOURCE_PATH = "static/wrap_crowd_source.js" +TASK_CONFIG_PATH = "static/task_config.json" + + +def can_build(build_dir: str, task_run: "TaskRun") -> bool: + """Determine if the build dir is properly formatted for + being able to have the router built within. This is a + validation step that should be run before build_router. + """ + # TODO(#97) incorporate this step into the blueprint + # task builder test, as once the task is built, it + # should be able to have the server build as well. + # TODO(#97) actually implement this when the full build + # process for the router is decided + return True + + +def install_router_files() -> None: + """ + Create a new build including the node_modules + """ + return_dir = os.getcwd() + os.chdir(SERVER_SOURCE_ROOT) + + packages_installed = subprocess.call(["npm", "install"]) + if packages_installed != 0: + raise Exception( + "please make sure npm is installed, otherwise view " + "the above error for more info." + ) + os.chdir(return_dir) + + +def build_router(build_dir: str, task_run: "TaskRun") -> str: + """ + Copy expected files from the router source into the build dir, + using existing files in the build dir as replacements for the + defaults if available + """ + install_router_files() + + server_source_directory_path = SERVER_SOURCE_ROOT + local_server_directory_path = os.path.join(build_dir, "router") + + # Delete old server files + sh.rm(shlex.split("-rf " + local_server_directory_path)) + + # Copy over a clean copy into the server directory + shutil.copytree(server_source_directory_path, local_server_directory_path) + + # Copy the required wrap crowd source path + local_crowd_source_path = os.path.join( + local_server_directory_path, CROWD_SOURCE_PATH + ) + crowd_provider = task_run.get_provider() + shutil.copy2(crowd_provider.get_wrapper_js_path(), local_crowd_source_path) + + # Copy the task_run's json configuration + local_task_config_path = os.path.join(local_server_directory_path, TASK_CONFIG_PATH) + blueprint = task_run.get_blueprint() + with open(local_task_config_path, "w+") as task_fp: + json.dump(blueprint.get_frontend_args(), task_fp) + + # Consolidate task files as defined by the task + TaskBuilderClass = blueprint.TaskBuilderClass + task_builder = TaskBuilderClass(task_run, task_run.args) + + task_builder.build_in_dir(local_server_directory_path) + + return local_server_directory_path diff --git a/mephisto/abstractions/architects/router/deploy/package-lock.json b/mephisto/abstractions/architects/router/deploy/package-lock.json new file mode 100644 index 000000000..b549156cb --- /dev/null +++ b/mephisto/abstractions/architects/router/deploy/package-lock.json @@ -0,0 +1,906 @@ +{ + "name": "server", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "async-lock": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.0.0.tgz", + "integrity": "sha1-uBq729Km5RZ3OgRLfmkXriAB83A=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", + "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "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" + } + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.x.x" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.4.tgz", + "integrity": "sha512-8I1sgZHfVwcSOY6mSGpVU3lw/GSIZvusg8dD2+OGehCJpOhQRLNcH0qb9upQnOH4XhgxxFJSg6E2kx95deb1Tw==", + "requires": { + "boom": "5.x.x" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.x.x" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "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": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "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" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" + } + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "requires": { + "mime-db": "1.42.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "request": { + "version": "2.82.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.82.0.tgz", + "integrity": "sha512-/QWqfmyTfQ4OYs6EhB1h2wQsX9ZxbuNePCvCm0Mdz/mxw73mjdg0D4QdIl0TQBFs35CZmMXLjk0iCGK395CUDg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.2", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "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" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.x.x" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "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" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "ws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.0.0.tgz", + "integrity": "sha512-QYslsH44bH8O7/W2815u5DpnCpXWpEK44FmaHffNwgJI4JMaSZONgPBTOfrxJ29mXKbXak+LsJ2uAkDTYq2ptQ==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/mephisto/abstractions/architects/router/deploy/package.json b/mephisto/abstractions/architects/router/deploy/package.json new file mode 100644 index 000000000..db1aa2777 --- /dev/null +++ b/mephisto/abstractions/architects/router/deploy/package.json @@ -0,0 +1,23 @@ +{ + "name": "server", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "engines": { + "node": ">= 7.6.0" + }, + "dependencies": { + "async-lock": "1.0.0", + "body-parser": "^1.19.0", + "express": "^4.17.1", + "multer": "^1.4.2", + "request": "2.82.0", + "ws": "4.0.0" + } +} diff --git a/mephisto/abstractions/architects/router/deploy/server.js b/mephisto/abstractions/architects/router/deploy/server.js new file mode 100644 index 000000000..74f07d5d1 --- /dev/null +++ b/mephisto/abstractions/architects/router/deploy/server.js @@ -0,0 +1,526 @@ +/* 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. + */ +"use strict"; + +const DEBUG = false; + +// TODO add some testing to launch this server and communicate with it + +const bodyParser = require("body-parser"); +const express = require("express"); +const http = require("http"); +const fs = require("fs"); +const WebSocket = require("ws"); +const multer = require("multer"); +const path = require("path"); + +const task_directory_name = "static"; + +const PORT = process.env.PORT || 3000; + +// Generate a random id +function uuidv4() { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { + var r = (Math.random() * 16) | 0, + v = c == "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); +} + +// Initialize app +const app = express(); +app.use(bodyParser.text()); +app.use( + bodyParser.urlencoded({ + extended: true, + }) +); +app.use(bodyParser.json()); + +var storage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, "/tmp/"); + }, + filename: function (req, file, cb) { + const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); + cb(null, uniqueSuffix + "-" + file.fieldname + "-" + file.originalname); + }, +}); + +var upload = multer({ storage: storage }); + +const server = http.createServer(app); + +// ======= ======== + +const FAILED_RECONNECT_TIME = 10000; + +// TODO can we pull all these from somewhere, make sure they're testable +// and show they're the same as the python ones? +const STATUS_INIT = "none"; +const STATUS_CONNECTED = "connected"; +const STATUS_DISCONNECTED = "disconnect"; +const STATUS_COMPLETED = "completed"; + +const SYSTEM_SOCKET_ID = "mephisto"; // TODO pull from somewhere +// TODO use registered socket id from on_alive +const SERVER_SOCKET_ID = "mephisto_server"; + +const PACKET_TYPE_REQUEST_AGENT_STATUS = "request_status"; +const PACKET_TYPE_RETURN_AGENT_STATUS = "return_status"; +const PACKET_TYPE_INIT_DATA = "initial_data_send"; +const PACKET_TYPE_AGENT_ACTION = "agent_action"; +const PACKET_TYPE_REQUEST_ACTION = "request_act"; +const PACKET_TYPE_UPDATE_AGENT_STATUS = "update_status"; +const PACKET_TYPE_NEW_AGENT = "register_agent"; +const PACKET_TYPE_NEW_WORKER = "register_worker"; +const PACKET_TYPE_GET_INIT_DATA = "init_data_request"; +const PACKET_TYPE_ALIVE = "alive"; +const PACKET_TYPE_PROVIDER_DETAILS = "provider_details"; +const PACKET_TYPE_SUBMIT_ONBOARDING = "submit_onboarding"; +const PACKET_TYPE_HEARTBEAT = "heartbeat"; + +// State for agents tracked by the server +class LocalAgentState { + constructor(agent_id) { + this.status = STATUS_INIT; + this.agent_id = agent_id; + this.unsent_messages = []; + this.state = { wants_act: false, done_text: null }; + this.is_alive = false; + } + + get_sendable_messages() { + let sendable_messages = this.unsent_messages; + this.unsent_messages = []; + return sendable_messages; + } +} + +const wss = new WebSocket.Server({ server }); + +// Track connectionss +var agent_id_to_socket = {}; +var socket_id_to_agent = {}; +var mephisto_message_queue = []; +var main_thread_timeout = null; +var mephisto_socket = null; + +// This is a mapping of connection id -> state +var agent_id_to_agent = {}; + +var pending_provider_requests = {}; + +var last_mephisto_ping = Date.now(); + +function debug_log() { + if (DEBUG) { + console.log.apply(null, arguments); + } +} + +// Handles sending a message through the socket +function _send_message(socket, packet) { + if (!socket) { + debug_log("No socket to send packet to", packet); + // Socket doesn't exist - odd + return; + } + + if (socket.readyState == 3) { + // Socket has already closed + return; + } + + // Send the message through, with one retry a half second later + socket.send(JSON.stringify(packet), function ack(error) { + if (error === undefined) { + return; + } + setTimeout(function () { + socket.send(JSON.stringify(packet), function ack2(error2) { + if (error2 === undefined) { + return; + } else { + console.log(error2); + } + }); + }, 500); + }); +} + +function find_or_create_agent(agent_id) { + var agent = agent_id_to_agent[agent_id]; + if (agent === undefined) { + var agent = new LocalAgentState(agent_id); + agent_id_to_agent[agent_id] = agent; + } + return agent; +} + +// Open connections send alives to identify who they are, +// register them correctly here +function handle_alive(socket, alive_packet) { + if (alive_packet.sender_id == SYSTEM_SOCKET_ID) { + mephisto_socket = socket; + console.log(socket._socket.remoteAddress); + if (main_thread_timeout === null) { + debug_log("launching main thread"); + main_thread_timeout = setTimeout(main_thread, 50); + } + } else { + var agent_id = alive_packet.sender_id; + var agent = find_or_create_agent(agent_id); + agent.is_alive = true; + agent_id_to_socket[agent_id] = socket; + socket_id_to_agent[socket.id] = agent; + } +} + +// Return the status of all agents mapped by their agent id +function handle_get_agent_status(status_packet) { + last_mephisto_ping = Date.now(); + let agent_statuses = {}; + for (let agent_id in agent_id_to_agent) { + agent_statuses[agent_id] = agent_id_to_agent[agent_id].status; + let ping_packet = { + packet_type: PACKET_TYPE_REQUEST_AGENT_STATUS, + sender_id: SYSTEM_SOCKET_ID, + receiver_id: agent_id, + data: null, + }; + handle_forward(ping_packet); + } + let packet = { + packet_type: PACKET_TYPE_RETURN_AGENT_STATUS, + sender_id: SERVER_SOCKET_ID, + receiver_id: SYSTEM_SOCKET_ID, + data: agent_statuses, + }; + mephisto_message_queue.push(packet); +} + +function get_agent_state(agent_id) { + let agent = find_or_create_agent(agent_id); + return agent.state; +} + +function handle_update_local_status(status_packet) { + let agent_id = status_packet.receiver_id; + let agent = find_or_create_agent(agent_id); + if (status_packet.data.status != undefined) { + agent.status = status_packet.data.status; + } + agent.state = Object.assign(agent.state, status_packet.data.state); +} + +function update_wanted_acts(agent_id, wants_act) { + let agent = find_or_create_agent(agent_id); + agent.state.wants_act = wants_act; +} + +// Handle a message being sent to or from a frontend agent +function handle_forward(packet) { + if (packet.receiver_id == SYSTEM_SOCKET_ID) { + debug_log("Adding message to mephisto queue", packet); + mephisto_message_queue.push(packet); + } else { + let agent = find_or_create_agent(packet.receiver_id); + debug_log("Adding message to agent queue", packet); + agent.unsent_messages.push(packet); + } +} + +function _followup_possible_disconnect(agent) { + if (!agent.is_alive) { + agent.status = STATUS_DISCONNECTED; + debug_log("Agent disconnected", agent); + } +} + +function handle_possible_disconnect(agent) { + debug_log("Possible disconnect", agent); + agent.is_alive = false; + + // Give the agent some time to possibly reconnect + setTimeout(() => _followup_possible_disconnect(agent), FAILED_RECONNECT_TIME); +} + +function send_status_for_agent(agent_id) { + let agent = find_or_create_agent(agent_id); + let packet = { + packet_type: PACKET_TYPE_UPDATE_AGENT_STATUS, + sender_id: SERVER_SOCKET_ID, + receiver_id: agent_id, + data: { + status: agent.status, + state: agent.state, + }, + }; + handle_forward(packet); +} + +// Register handlers +wss.on("connection", function (socket) { + socket.id = uuidv4(); + console.log("Client connected"); + // Disconnects are logged + socket.on("disconnect", function () { + console.log("socket disconnected"); + var agent = socket_id_to_agent[socket.id]; + if (agent !== undefined) { + handle_possible_disconnect(agent); + } + }); + + socket.on("error", (err) => { + console.log("Caught socket error, probably closed!"); + console.log(err); + var agent = socket_id_to_agent[socket.id]; + if (agent !== undefined) { + handle_possible_disconnect(agent); + } + }); + + // handles routing a packet to the desired recipient + socket.on("message", function (packet) { + try { + packet = JSON.parse(packet); + if (packet["packet_type"] == PACKET_TYPE_REQUEST_AGENT_STATUS) { + debug_log("Mephisto requesting status"); + handle_get_agent_status(packet); + } else if (packet["packet_type"] == PACKET_TYPE_AGENT_ACTION) { + debug_log("Agent action: ", packet); + handle_forward(packet); + if (packet.receiver_id == SYSTEM_SOCKET_ID) { + update_wanted_acts(packet.sender_id, false); + send_status_for_agent(packet.sender_id); + } + } else if (packet["packet_type"] == PACKET_TYPE_ALIVE) { + debug_log("Agent alive: ", packet); + handle_alive(socket, packet); + } else if (packet["packet_type"] == PACKET_TYPE_UPDATE_AGENT_STATUS) { + debug_log("Update agent status", packet); + handle_update_local_status(packet); + packet.data.state = get_agent_state(packet.receiver_id); + handle_forward(packet); + } else if (packet["packet_type"] == PACKET_TYPE_REQUEST_ACTION) { + debug_log("Requesting act", packet); + update_wanted_acts(packet.receiver_id, true); + let agent_id = packet["receiver_id"]; + send_status_for_agent(agent_id); + } else if ( + packet["packet_type"] == PACKET_TYPE_PROVIDER_DETAILS || + packet["packet_type"] == PACKET_TYPE_INIT_DATA + ) { + let request_id = packet["data"]["request_id"]; + if (request_id === undefined) { + request_id = packet["receiver_id"]; + } + let res_obj = pending_provider_requests[request_id]; + if (res_obj) { + res_obj.json(packet); + delete pending_provider_requests[request_id]; + } + } else if (packet["packet_type"] == PACKET_TYPE_HEARTBEAT) { + packet["data"] = { last_mephisto_ping: last_mephisto_ping }; + let agent_id = packet["sender_id"]; + packet["sender_id"] = packet["receiver_id"]; + packet["receiver_id"] = agent_id; + let agent = agent_id_to_agent[agent_id]; + if (agent !== undefined) { + agent.is_alive = true; + packet.data.status = agent.status; + packet.data.state = agent.state; + if (agent_id_to_socket[agent.agent_id] != socket) { + // Not communicating to the correct socket, update + debug_log("Updating socket for ", agent); + agent_id_to_socket[agent.agent_id] = socket; + socket_id_to_agent[socket.id] = agent; + } + } + handle_forward(packet); + } + } catch (error) { + console.log("Transient error on message"); + console.log(error); + } + }); +}); + +server.listen(PORT, function () { + console.log("Listening on %d", server.address().port); +}); + +// ============ ============== + +// ======================= ======================= + +// TODO add crash checking around this thread? +function main_thread() { + try { + // Handle active connections message sends + for (const agent_id in agent_id_to_socket) { + let agent_state = agent_id_to_agent[agent_id]; + if (!agent_state.is_alive) { + continue; + } + let sendable_messages = agent_state.get_sendable_messages(); + if (sendable_messages.length > 0) { + let socket = agent_id_to_socket[agent_id]; + // TODO send all these messages in a batch + for (const packet of sendable_messages) { + _send_message(socket, packet); + } + } + } + + // Handle sending batches to the mephisto python client + let mephisto_messages = []; + while (mephisto_message_queue.length > 0) { + mephisto_messages.push(mephisto_message_queue.shift()); + } + if (mephisto_messages.length > 0) { + for (const packet of mephisto_messages) { + _send_message(mephisto_socket, packet); + } + } + } catch (error) { + console.log("Transient error in main thread?"); + console.log(error); + } + + // Re-call this thead, as it should run forever + main_thread_timeout = setTimeout(main_thread, 50); +} + +// ======================= ====================== + +// ===================== ======================== +function make_provider_request(request_type, provider_data, res) { + var request_id = uuidv4(); + + let request_packet = { + packet_type: request_type, + sender_id: SERVER_SOCKET_ID, + receiver_id: SYSTEM_SOCKET_ID, + data: { + provider_data: provider_data, + request_id: request_id, + }, + }; + + pending_provider_requests[request_id] = res; + _send_message(mephisto_socket, request_packet); + // TODO set a timeout to expire this request rather than leave the worker hanging +} + +app.post("/initial_task_data", function (req, res) { + var provider_data = req.body.provider_data; + make_provider_request(PACKET_TYPE_GET_INIT_DATA, provider_data, res); +}); + +app.post("/register_worker", function (req, res) { + var provider_data = req.body.provider_data; + make_provider_request(PACKET_TYPE_NEW_WORKER, provider_data, res); +}); + +app.post("/request_agent", function (req, res) { + var provider_data = req.body.provider_data; + make_provider_request(PACKET_TYPE_NEW_AGENT, provider_data, res); +}); + +app.post("/submit_onboarding", function (req, res) { + var provider_data = req.body.provider_data; + var request_id = uuidv4(); + + let agent_id = provider_data.USED_AGENT_ID; + delete provider_data.USED_AGENT_ID; + + provider_data.request_id = request_id; + + let submit_packet = { + packet_type: PACKET_TYPE_SUBMIT_ONBOARDING, + sender_id: agent_id, + receiver_id: SYSTEM_SOCKET_ID, + data: provider_data, + }; + + pending_provider_requests[request_id] = res; + _send_message(mephisto_socket, submit_packet); +}); + +app.post("/submit_task", upload.any(), function (req, res) { + var provider_data = req.body; + let agent_id = provider_data.USED_AGENT_ID; + delete provider_data.USED_AGENT_ID; + let submit_packet = { + packet_type: PACKET_TYPE_AGENT_ACTION, + sender_id: agent_id, + receiver_id: SYSTEM_SOCKET_ID, + data: { + task_data: provider_data, + MEPHISTO_is_submit: true, + files: req.files, + }, + }; + _send_message(mephisto_socket, submit_packet); + res.json({ status: "Submitted!" }); + + // Cleanup local state for a task that's already submitted + if (agent_id in agent_id_to_agent) { + delete agent_id_to_agent[agent_id]; + } + if (agent_id in agent_id_to_socket) { + let socket_id = agent_id_to_socket[agent_id].id; + delete agent_id_to_socket[agent_id]; + delete socket_id_to_agent[socket_id]; + } +}); + +// Quick status check for this server +app.get("/is_alive", function (req, res) { + res.json({ status: "Alive!" }); +}); + +// Returns server time for now +app.get("/get_timestamp", function (req, res) { + res.json({ timestamp: Date.now() }); // in milliseconds +}); + +app.get("/task_index", function (req, res) { + // TODO how do we pass the task config to the frontend? + res.render("index.html"); +}); + +app.get("/download_file/:file", function (req, res) { + var ip = + req.ip || + req.headers["x-forwarded-for"] || + req.connection.remoteAddress || + req.socket.remoteAddress || + req.connection.socket.remoteAddress; + if (ip == mephisto_socket._socket.remoteAddress) { + res.sendFile(path.join("/tmp/", req.params.file), function (err) { + if (err) { + console.log(err); + res.status(err.status).end(); + } + }); + } else { + res.sendFile(path.join("/tmp/", req.params.file), function (err) { + if (err) { + console.log(err); + res.status(err.status).end(); + } + }); + // TODO only return the files for requests from the origin + // res.status(403).end(); + } +}); + +app.use(express.static("static")); + +// ======================= ======================= diff --git a/mephisto/abstractions/architects/router/deploy/static/index.html b/mephisto/abstractions/architects/router/deploy/static/index.html new file mode 100644 index 000000000..ee7f159c1 --- /dev/null +++ b/mephisto/abstractions/architects/router/deploy/static/index.html @@ -0,0 +1,25 @@ + + + + + + + + Crowdsourcing Task + + + + + +
+ + + diff --git a/mephisto/abstractions/architects/router/deploy/uploads/exists.txt b/mephisto/abstractions/architects/router/deploy/uploads/exists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mephisto/abstractions/blueprint.py b/mephisto/abstractions/blueprint.py new file mode 100644 index 000000000..63fcbf12f --- /dev/null +++ b/mephisto/abstractions/blueprint.py @@ -0,0 +1,625 @@ +#!/usr/bin/env python3 + +# 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. + +from abc import ABC, abstractmethod +from mephisto.operations.utils import find_or_create_qualification +from typing import ( + ClassVar, + Optional, + List, + Dict, + Any, + Type, + ClassVar, + Union, + Iterable, + AsyncIterator, + Callable, + TYPE_CHECKING, +) + +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig + +from mephisto.data_model.exceptions import ( + AgentReturnedError, + AgentDisconnectedError, + AgentTimeoutError, +) +from mephisto.data_model.constants.assignment_state import AssignmentState + +if TYPE_CHECKING: + from mephisto.data_model.agent import Agent, OnboardingAgent + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Assignment, InitializationData + from mephisto.data_model.unit import Unit + from mephisto.data_model.packet import Packet + from mephisto.data_model.worker import Worker + from argparse import _ArgumentGroup as ArgumentGroup + + +@dataclass +class BlueprintArgs: + _blueprint_type: str = MISSING + onboarding_qualification: str = field( + default=MISSING, + metadata={ + "help": ( + "Specify the name of a qualification used to block workers who fail onboarding, " + "Empty will skip onboarding." + ) + }, + ) + block_qualification: str = field( + default=MISSING, + metadata={ + "help": ("Specify the name of a qualification used to soft block workers.") + }, + ) + + +@dataclass +class SharedTaskState: + """ + Base class for specifying additional state that can't just + be passed as Hydra args, like functions and objects + """ + + onboarding_data: Dict[str, Any] = field(default_factory=dict) + task_config: Dict[str, Any] = field(default_factory=dict) + validate_onboarding: Callable[[Any], bool] = field( + default_factory=lambda: (lambda x: True) + ) + qualifications: List[Any] = field(default_factory=list) + worker_can_do_unit: Callable[["Worker", "Unit"], bool] = field( + default_factory=lambda: (lambda worker, unit: True) + ) + + +class TaskBuilder(ABC): + """ + Class to manage building a task of a specific type in a directory + that will be used to deploy that task. + """ + + def __init__(self, task_run: "TaskRun", args: "DictConfig"): + self.args = args + self.task_run = task_run + + def __new__(cls, task_run: "TaskRun", args: "DictConfig") -> "TaskBuilder": + """Get the correct TaskBuilder for this task run""" + from mephisto.operations.registry import get_blueprint_from_type + + if cls == TaskBuilder: + # We are trying to construct an TaskBuilder, find what type to use and + # create that instead + correct_class = get_blueprint_from_type(task_run.task_type).TaskBuilderClass + return super().__new__(correct_class) + else: + # We are constructing another instance directly + return super().__new__(cls) + + @abstractmethod + def build_in_dir(self, build_dir: str) -> None: + """ + Build the server for the given task run into the provided directory + """ + raise NotImplementedError() + + +class TaskRunner(ABC): + """ + Class to manage running a task of a specific type. Includes + building the dependencies to a directory to be deployed to + the server, and spawning threads that manage the process of + passing agents through a task. + """ + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + self.args = args + self.shared_state = shared_state + self.task_run = task_run + self.running_assignments: Dict[str, "Assignment"] = {} + self.running_units: Dict[str, "Unit"] = {} + self.running_onboardings: Dict[str, "OnboardingAgent"] = {} + self.is_concurrent = False + # TODO(102) populate some kind of local state for tasks that are being run + # by this runner from the database. + + self.block_qualification = args.blueprint.get("block_qualification", None) + if self.block_qualification is not None: + find_or_create_qualification(task_run.db, self.block_qualification) + + def __new__( + cls, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ) -> "TaskRunner": + """Get the correct TaskRunner for this task run""" + if cls == TaskRunner: + from mephisto.operations.registry import get_blueprint_from_type + + # We are trying to construct an AgentState, find what type to use and + # create that instead + correct_class = get_blueprint_from_type(task_run.task_type).TaskRunnerClass + return super().__new__(correct_class) + else: + # We are constructing another instance directly + return super().__new__(cls) + + def launch_onboarding(self, onboarding_agent: "OnboardingAgent") -> None: + """ + Validate that onboarding is ready, then launch. Catch disconnect conditions + """ + onboarding_id = onboarding_agent.get_agent_id() + if onboarding_id in self.running_onboardings: + print(f"Onboarding {onboarding_id} is already running") + return + + print(f"Onboarding {onboarding_id} is launching with {onboarding_agent}") + + # At this point we're sure we want to run Onboarding + self.running_onboardings[onboarding_id] = onboarding_agent + try: + self.run_onboarding(onboarding_agent) + onboarding_agent.mark_done() + except (AgentReturnedError, AgentTimeoutError, AgentDisconnectedError): + self.cleanup_onboarding(onboarding_agent) + except Exception as e: + print(f"Unhandled exception in onboarding {onboarding_agent}: {repr(e)}") + import traceback + + traceback.print_exc() + self.cleanup_onboarding(onboarding_agent) + del self.running_onboardings[onboarding_id] + return + + def launch_unit(self, unit: "Unit", agent: "Agent") -> None: + """ + Validate the unit is prepared to launch, then run it + """ + if unit.db_id in self.running_units: + print(f"Unit {unit.db_id} is already running") + return + + print(f"Unit {unit.db_id} is launching with {agent}") + + # At this point we're sure we want to run the unit + self.running_units[unit.db_id] = unit + try: + self.run_unit(unit, agent) + except (AgentReturnedError, AgentTimeoutError, AgentDisconnectedError): + # A returned Unit can be worked on again by someone else. + if ( + unit.get_status() != AssignmentState.EXPIRED + and unit.get_assigned_agent().db_id == agent.db_id + ): + unit.clear_assigned_agent() + self.cleanup_unit(unit) + except Exception as e: + print(f"Unhandled exception in unit {unit}: {repr(e)}") + import traceback + + traceback.print_exc() + self.cleanup_unit(unit) + del self.running_units[unit.db_id] + return + + def launch_assignment( + self, assignment: "Assignment", agents: List["Agent"] + ) -> None: + """ + Validate the assignment is prepared to launch, then run it + """ + if assignment.db_id in self.running_assignments: + print(f"Assignment {assignment.db_id} is already running") + return + + print(f"Assignment {assignment.db_id} is launching with {agents}") + + # At this point we're sure we want to run the assignment + self.running_assignments[assignment.db_id] = assignment + try: + self.run_assignment(assignment, agents) + except (AgentReturnedError, AgentTimeoutError, AgentDisconnectedError) as e: + # TODO(#99) if some operator flag is set for counting complete tasks, launch a + # new assignment copied from the parameters of this one + disconnected_agent_id = e.agent_id + for agent in agents: + if agent.db_id != e.agent_id: + agent.update_status(AgentState.STATUS_PARTNER_DISCONNECT) + else: + # Must expire the disconnected unit so that + # new workers aren't shown it + agent.get_unit().expire() + self.cleanup_assignment(assignment) + except Exception as e: + print(f"Unhandled exception in assignment {assignment}: {repr(e)}") + import traceback + + traceback.print_exc() + self.cleanup_assignment(assignment) + del self.running_assignments[assignment.db_id] + return + + @staticmethod + def get_data_for_assignment(assignment: "Assignment") -> "InitializationData": + """ + Finds the right data to get for the given assignment. + """ + return assignment.get_assignment_data() + + @abstractmethod + def get_init_data_for_agent(self, agent: "Agent"): + """ + Return the data that an agent will need for their task. + """ + raise NotImplementedError() + + def filter_units_for_worker(self, units: List["Unit"], worker: "Worker"): + """ + Returns the list of Units that the given worker is eligible to work on. + + Some tasks may want more direct control of what units a worker is + allowed to work on, so this method should be overridden by children + classes. + """ + return units + + # TaskRunners must implement either the unit or assignment versions of the + # run and cleanup functions, depending on if the task is run at the assignment + # level rather than on the the unit level. + + def run_onboarding(self, agent: "OnboardingAgent"): + """ + Handle setup for any resources to run an onboarding task. This + will be run in a background thread, and should be tolerant to being + interrupted by cleanup_onboarding. + + Only required by tasks that want to implement onboarding + """ + raise NotImplementedError() + + def cleanup_onboarding(self, agent: "OnboardingAgent"): + """ + Handle cleaning up the resources that were being used to onboard + the given agent. + """ + raise NotImplementedError() + + def run_unit(self, unit: "Unit", agent: "Agent"): + """ + Handle setup for any resources required to get this unit running. + This will be run in a background thread, and should be tolerant to + being interrupted by cleanup_unit. + + Only needs to be implemented by non-concurrent tasks + """ + raise NotImplementedError() + + def cleanup_unit(self, unit: "Unit"): + """ + Handle ensuring resources for a given assignment are cleaned up following + a disconnect or other crash event + + Does not need to be implemented if the run_unit method is + already error catching and handles its own cleanup + """ + raise NotImplementedError() + + def run_assignment(self, assignment: "Assignment", agents: List["Agent"]): + """ + Handle setup for any resources required to get this assignment running. + This will be run in a background thread, and should be tolerant to + being interrupted by cleanup_assignment. + + Only needs to be implemented by concurrent tasks + """ + raise NotImplementedError() + + def cleanup_assignment(self, assignment: "Assignment"): + """ + Handle ensuring resources for a given assignment are cleaned up following + a disconnect or other crash event + + Does not need to be implemented if the run_assignment method is + already error catching and handles its own cleanup + """ + raise NotImplementedError() + + +# TODO(#101) what is the best method for creating new ones of these for different task types +# in ways that are supported by different backends? Perhaps abstract additional +# methods into the required db interface? Move any file manipulations into a +# extra_data_handler subcomponent of the MephistoDB class? +class AgentState(ABC): + """ + Class for holding state information about work by an Agent on a Unit, currently + stored as current task work into a json file. + + Specific state implementations will need to be created for different Task Types, + as different tasks store and load differing data. + """ + + # Possible Agent Status Values + STATUS_NONE = "none" + STATUS_ACCEPTED = "accepted" + STATUS_ONBOARDING = "onboarding" + STATUS_WAITING = "waiting" + STATUS_IN_TASK = "in task" + STATUS_COMPLETED = "completed" + STATUS_DISCONNECT = "disconnect" + STATUS_TIMEOUT = "timeout" + STATUS_PARTNER_DISCONNECT = "partner disconnect" + STATUS_EXPIRED = "expired" + STATUS_RETURNED = "returned" + STATUS_APPROVED = "approved" + STATUS_SOFT_REJECTED = "soft_rejected" + STATUS_REJECTED = "rejected" + + def __new__(cls, agent: Union["Agent", "OnboardingAgent"]) -> "AgentState": + """Return the correct agent state for the given agent""" + if cls == AgentState: + from mephisto.data_model.agent import Agent + from mephisto.operations.registry import get_blueprint_from_type + + # We are trying to construct an AgentState, find what type to use and + # create that instead + if isinstance(agent, Agent): + correct_class = get_blueprint_from_type(agent.task_type).AgentStateClass + else: + correct_class = get_blueprint_from_type( + agent.task_type + ).OnboardingAgentStateClass + return super().__new__(correct_class) + else: + # We are constructing another instance directly + return super().__new__(cls) + + @staticmethod + def complete() -> List[str]: + """Return all final Agent statuses which will not be updated by the supervisor""" + return [ + AgentState.STATUS_COMPLETED, + AgentState.STATUS_DISCONNECT, + AgentState.STATUS_TIMEOUT, + AgentState.STATUS_EXPIRED, + AgentState.STATUS_RETURNED, + AgentState.STATUS_SOFT_REJECTED, + AgentState.STATUS_APPROVED, + AgentState.STATUS_REJECTED, + ] + + @staticmethod + def valid() -> List[str]: + """Return all valid Agent statuses""" + # TODO(#97) write a test that ensures all AgentState statuses are here + return [ + AgentState.STATUS_NONE, + AgentState.STATUS_ACCEPTED, + AgentState.STATUS_ONBOARDING, + AgentState.STATUS_WAITING, + AgentState.STATUS_IN_TASK, + AgentState.STATUS_COMPLETED, + AgentState.STATUS_DISCONNECT, + AgentState.STATUS_TIMEOUT, + AgentState.STATUS_PARTNER_DISCONNECT, + AgentState.STATUS_EXPIRED, + AgentState.STATUS_RETURNED, + AgentState.STATUS_SOFT_REJECTED, + AgentState.STATUS_APPROVED, + AgentState.STATUS_REJECTED, + ] + + # Implementations of an AgentState must implement the following: + + @abstractmethod + def __init__(self, agent: "Agent"): + """ + Create an AgentState to track the state of an agent's work on a Unit + + Implementations should initialize any required files for saving and + loading state data somewhere. + + If said file already exists based on the given agent, load that data + instead. + """ + raise NotImplementedError() + + @abstractmethod + def set_init_state(self, data: Any) -> bool: + """Set the initial state for this agent""" + raise NotImplementedError() + + @abstractmethod + def get_init_state(self) -> Optional[Any]: + """ + Return the initial state for this agent, + None if no such state exists + """ + raise NotImplementedError() + + @abstractmethod + def load_data(self) -> None: + """ + Load stored data from a file to this object + """ + raise NotImplementedError() + + @abstractmethod + def get_data(self) -> Dict[str, Any]: + """ + Return the currently stored data for this task in the format + expected by any frontend displays + """ + raise NotImplementedError() + + def get_parsed_data(self) -> Any: + """ + Return the portion of the data that is relevant to a human + who wants to parse or analyze the data + + Utility function to handle stripping the data of any + context that is only important for reproducing the task + exactly. By default is just `get_data` + """ + return self.get_data() + + @abstractmethod + def save_data(self) -> None: + """ + Save the relevant data from this Unit to a file in the expected location + """ + raise NotImplementedError() + + @abstractmethod + def update_data(self, packet: "Packet") -> None: + """ + Put new current Unit data into this AgentState + """ + # TODO(#100) maybe refine the signature for this function once use cases + # are fully scoped + + # Some use cases might just be appending new data, some + # might instead prefer to maintain a final state. + + # Maybe the correct storage is of a series of actions taken + # on this Unit? Static tasks only have 2 turns max, dynamic + # ones may have multiple turns or steps. + raise NotImplementedError() + + def get_task_start(self) -> Optional[float]: + """ + Return the start time for this task, if it is available + """ + return 0.0 + + def get_task_end(self) -> Optional[float]: + """ + Return the end time for this task, if it is available + """ + return 0.0 + + +class OnboardingRequired(object): + """ + Compositional class for blueprints that may have an onboarding step + """ + + @staticmethod + def get_failed_qual(qual_name: str) -> str: + """Returns the wrapper for a qualification to represent failing an onboarding""" + return qual_name + "-failed" + + def init_onboarding_config( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + self.onboarding_qualification_name: Optional[str] = args.blueprint.get( + "onboarding_qualification", None + ) + self.onboarding_data = shared_state.onboarding_data + self.use_onboarding = self.onboarding_qualification_name is not None + self.onboarding_qualification_id = None + if self.onboarding_qualification_name is not None: + db = task_run.db + found_qualifications = db.find_qualifications( + self.onboarding_qualification_name + ) + if len(found_qualifications) == 0: + self.onboarding_qualification_id = db.make_qualification( + self.onboarding_qualification_name + ) + else: + self.onboarding_qualification_id = found_qualifications[0].db_id + + # We need to keep a separate qualification for failed onboarding + # to push to a crowd provider in order to prevent workers + # who have failed from being shown our task + self.onboarding_failed_name = self.get_failed_qual( + self.onboarding_qualification_name + ) + found_qualifications = db.find_qualifications(self.onboarding_failed_name) + if len(found_qualifications) == 0: + self.onboarding_failed_id = db.make_qualification( + self.onboarding_failed_name + ) + else: + self.onboarding_failed_id = found_qualifications[0].db_id + + def get_onboarding_data(self, worker_id: str) -> Dict[str, Any]: + """ + If the onboarding task on the frontend requires any specialized data, the blueprint + should provide it for the user. + + As onboarding qualifies a worker for all tasks from this blueprint, this should + generally be static data that can later be evaluated against. + """ + return self.onboarding_data + + def validate_onboarding( + self, worker: "Worker", onboarding_agent: "OnboardingAgent" + ) -> bool: + """ + Check the incoming onboarding data and evaluate if the worker + has passed the qualification or not. Return True if the worker + has qualified. + """ + return True + + +class Blueprint(ABC): + """ + Configuration class for the various parts of building, launching, + and running a task of a specific task. Provides utility functions + for managing between the three main components, which are separated + into separate classes in acknowledgement that some tasks may have + particularly complicated processes for them + """ + + AgentStateClass: ClassVar[Type["AgentState"]] + OnboardingAgentStateClass: ClassVar[Type["AgentState"]] = AgentState # type: ignore + TaskRunnerClass: ClassVar[Type["TaskRunner"]] + TaskBuilderClass: ClassVar[Type["TaskBuilder"]] + ArgsClass: ClassVar[Type["BlueprintArgs"]] = BlueprintArgs + SharedStateClass: ClassVar[Type["SharedTaskState"]] = SharedTaskState + supported_architects: ClassVar[List[str]] + BLUEPRINT_TYPE: str + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + self.args = args + self.shared_state = shared_state + self.frontend_task_config = shared_state.task_config + + @classmethod + def assert_task_args(cls, args: DictConfig, shared_state: "SharedTaskState"): + """ + Assert that the provided arguments are valid. Should + fail if a task launched with these arguments would + not work + """ + return + + def get_frontend_args(self) -> Dict[str, Any]: + """ + Specifies what options should be fowarded + to the client for use by the task's frontend + """ + return self.frontend_task_config + + @abstractmethod + def get_initialization_data( + self, + ) -> Union[Iterable["InitializationData"], AsyncIterator["InitializationData"]]: + """ + Get all of the data used to initialize tasks from this blueprint. + Can either be a simple iterable if all the assignments can + be processed at once, or an AsyncIterator if the number + of tasks is unknown or changes based on something running + concurrently with the job. + """ + raise NotImplementedError diff --git a/mephisto/abstractions/blueprints/README.md b/mephisto/abstractions/blueprints/README.md new file mode 100644 index 000000000..f0337c116 --- /dev/null +++ b/mephisto/abstractions/blueprints/README.md @@ -0,0 +1,43 @@ +# Blueprints +## Overview +Blueprints serve to package tasks (and groups of similar tasks) into a reusable format. They can be used to work through piloting tasks, collecting data, testing different formats, etc. They're also used by the architecture to simplify the data accumulation and review processes. The `StaticBlueprint` is a good starting example of how to implement a blueprint. + +## Implementation Details +### `AgentState` +The agent state is responsible for defining the data that is important to store for a specific `Unit`, as well as methods for writing that locally to disk. To abstract this, it must implement the following methods: +- `set_init_state(data)`: given data provided by the `get_init_data_for_agent` method, initialize this agent state to whatever starting state is relevant for this `Unit`. +- `get_init_state()`: Return the initial state to be sent to the agent for use in the frontend. +- `load_data()`: Load data that is saved to file to re-initialize the state for this `AgentState`. Generally data should be stored in `self.agent.get_data_dir()`, however any storage solution will work as long as it remains consistent. +- `get_data()`: Return the stored data for this task in the format expected to render a completed task in the frontend. +- `save_data()`: Save data to a file such that it can be re-initialized later. Generally data should be stored in `self.agent.get_data_dir()`, however any storage solution will work as long as it remains consistent, and `load_data()` will be able to find it. +- `update_data()`: Update the local state stored in this `AgentState` given the data sent from the frontend. Given your frontend is what packages data to send, this is entirely customizable by the task creator. + +(TODO) Specify a format for data to be sent to the frontend for review. + +### `TaskBuilder` +`TaskBuilder`s exist to abstract away the portion of building a frontend to however one would want to, allowing Mephisto users to design tasks however they'd like. They also can take build options to customize what ends up built. They must implement the following: +- `build_in_dir(build_dir)`: Take any important source files and put them into the given build dir. This directory will be deployed to the frontend and will become the static target for completing the task. +- `get_extra_options()`: Return the specific task options that are relevant to customize the frontend when `build_in_dir` is called. +(TODO) Remove all references to the below functon +- `task_dir_is_valid(task_dir)`: Originally this was intended to specify whether the task directory supplied outside of the task for this task to use was properly formatted, however when `Blueprint`s were finalized, the gallery no longer existed and this route of customization is no longer supported. + +### `TaskRunner` +The `TaskRunner` component of a blueprint is responsible for actually stepping `Agent`s through the task when it is live. It is, in short, able to set up task control. A `TaskRunner` needs to implement the following: +- `get_init_data_for_agent`: Provide initial data for an assignment. If this agent is reconnecting (and as such attached to an existing task), update that task to point to the new agent (as the old agent object will no longer receive data from the frontend). +- `run_assignment`: Handle setup for any resources required to get this assignment running. It will be launched in a background thread, and should be tolerant to being interrupted by cleanup_assignment. +- `cleanup_assignment`: Send any signals to the required thread for the given assignment to tell it to terminate, then clean up any resources that were set within it. +- `get_data_for_assignment` (optional): Get the data that an assignment is going to use when run. By default, this pulls from `assignment.get_assignment_data()` however if a task has a special storage mechanism or data type, the assignment data can be fetched here. (TODO) make this optional by having the base class use the `StaticTaskRunner`'s implementation. +(TODO) task launching management at the moment is really sloppy, and the API for it is unclear. Something better needs to be picked, as at the moment `get_init_data_for_assignment` is responsible for ensuring that `run_assignment` is set up in a thread. Perhaps this responsibility should be consolidated into the `TaskLauncher` class. + +## Implementations +### `StaticBlueprint` +The `StaticBlueprint` class allows a replication of the interface that MTurk provides, being able to take a snippet of `HTML` and a `.csv` file and deploy tasks that fill templates of the `HTML` with values from the `.csv`. + +(TODO) support other sources than a .csv + +### `MockBlueprint` +The `MockBlueprint` exists to test other parts of the Mephisto architecture, and doesn't actually provide a real task. + +## Future work +(TODO) - Clean up the notion of galleries and parent task ids, as we're consolidating into blueprints +(TODO) - Allow for using user blueprints diff --git a/test/server/__init__.py b/mephisto/abstractions/blueprints/__init__.py similarity index 100% rename from test/server/__init__.py rename to mephisto/abstractions/blueprints/__init__.py diff --git a/mephisto/abstractions/blueprints/abstract/README.md b/mephisto/abstractions/blueprints/abstract/README.md new file mode 100644 index 000000000..2bd09963f --- /dev/null +++ b/mephisto/abstractions/blueprints/abstract/README.md @@ -0,0 +1,2 @@ +# Abstract blueprints +The blueprints present in this folder provide a set of common underlying blueprint infrastructure, but are incomplete in some form or other. They are not registered as blueprints because they aren't intended to be launched, but rather to be extended upon. \ No newline at end of file diff --git a/test/server/architects/__init__.py b/mephisto/abstractions/blueprints/abstract/__init__.py similarity index 100% rename from test/server/architects/__init__.py rename to mephisto/abstractions/blueprints/abstract/__init__.py diff --git a/test/server/blueprints/__init__.py b/mephisto/abstractions/blueprints/abstract/static_task/__init__.py similarity index 100% rename from test/server/blueprints/__init__.py rename to mephisto/abstractions/blueprints/abstract/static_task/__init__.py diff --git a/mephisto/abstractions/blueprints/abstract/static_task/empty_task_builder.py b/mephisto/abstractions/blueprints/abstract/static_task/empty_task_builder.py new file mode 100644 index 000000000..f4614e016 --- /dev/null +++ b/mephisto/abstractions/blueprints/abstract/static_task/empty_task_builder.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskBuilder + + +class EmptyStaticTaskBuilder(TaskBuilder): + """ + Abstract class for a task builder for static tasks + """ + + def build_in_dir(self, build_dir: str): + """Build the frontend if it doesn't exist, then copy into the server directory""" + raise AssertionError( + "Classes that extend the abstract StaticBlueprint must define a custom " + "TaskBuilder class that pulls the correct frontend together. Examples " + "can be seen in the static_react_task and static_html_task folders. " + "Note that extra static content will be provided in `args.blueprint.extra_source_dir` " + ) diff --git a/mephisto/abstractions/blueprints/abstract/static_task/static_agent_state.py b/mephisto/abstractions/blueprints/abstract/static_task/static_agent_state.py new file mode 100644 index 000000000..8fa64a766 --- /dev/null +++ b/mephisto/abstractions/blueprints/abstract/static_task/static_agent_state.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +# 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. + +from typing import List, Dict, Optional, Any, TYPE_CHECKING +from mephisto.abstractions.blueprint import AgentState +import os +import json +import time + +if TYPE_CHECKING: + from mephisto.data_model.agent import Agent + from mephisto.data_model.packet import Packet + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + +DATA_FILE = "agent_data.json" + + +class StaticAgentState(AgentState): + """ + Agent state for static tasks. + """ + + def _get_empty_state(self) -> Dict[str, Optional[Dict[str, Any]]]: + return { + "inputs": None, + "outputs": None, + "times": {"task_start": 0, "task_end": 0}, + } + + def __init__(self, agent: "Agent"): + """ + Static agent states should store + input dict -> output dict pairs to disc + """ + self.agent = agent + self.state: Dict[str, Optional[Dict[str, Any]]] = self._get_empty_state() + self.load_data() + + def set_init_state(self, data: Any) -> bool: + """Set the initial state for this agent""" + if self.get_init_state() is not None: + # Initial state is already set + return False + else: + self.state["inputs"] = data + times_dict = self.state["times"] + # TODO(#103) this typing may be better handled another way + assert isinstance(times_dict, dict) + times_dict["task_start"] = time.time() + self.save_data() + return True + + def get_init_state(self) -> Optional[Dict[str, Any]]: + """ + Return the initial state for this agent, + None if no such state exists + """ + if self.state["inputs"] is None: + return None + return self.state["inputs"].copy() + + def load_data(self) -> None: + """Load data for this agent from disk""" + data_dir = self.agent.get_data_dir() + data_path = os.path.join(data_dir, DATA_FILE) + if os.path.exists(data_path): + with open(data_path, "r") as data_file: + self.state = json.load(data_file) + else: + self.state = self._get_empty_state() + + def get_data(self) -> Dict[str, Any]: + """Return dict of this agent's state""" + return self.state.copy() + + def save_data(self) -> None: + """Save static agent data to disk""" + data_dir = self.agent.get_data_dir() + os.makedirs(data_dir, exist_ok=True) + out_filename = os.path.join(data_dir, DATA_FILE) + with open(out_filename, "w+") as data_file: + json.dump(self.state, data_file) + logger.info(f"SAVED_DATA_TO_DISC at {out_filename}") + + def update_data(self, packet: "Packet") -> None: + """ + Process the incoming data packet, and handle + updating the state + """ + assert ( + packet.data.get("MEPHISTO_is_submit") is True + or packet.data.get("onboarding_data") is not None + ), "Static tasks should only have final act" + + outputs: Dict[str, Any] + + if packet.data.get("onboarding_data") is not None: + outputs = packet.data["onboarding_data"] + else: + outputs = packet.data["task_data"] + times_dict = self.state["times"] + # TODO(#013) this typing may be better handled another way + assert isinstance(times_dict, dict) + times_dict["task_end"] = time.time() + if packet.data.get("files") != None: + logger.info(f"Got files: {str(packet.data['files'])[:500]}") + outputs["files"] = [f["filename"] for f in packet.data["files"]] + self.state["outputs"] = outputs + self.save_data() diff --git a/mephisto/abstractions/blueprints/abstract/static_task/static_blueprint.py b/mephisto/abstractions/blueprints/abstract/static_task/static_blueprint.py new file mode 100644 index 000000000..3dcd4c482 --- /dev/null +++ b/mephisto/abstractions/blueprints/abstract/static_task/static_blueprint.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import ( + Blueprint, + OnboardingRequired, + BlueprintArgs, + SharedTaskState, +) +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from mephisto.data_model.assignment import InitializationData +from mephisto.abstractions.blueprints.abstract.static_task.static_agent_state import ( + StaticAgentState, +) +from mephisto.abstractions.blueprints.abstract.static_task.static_task_runner import ( + StaticTaskRunner, +) +from mephisto.abstractions.blueprints.abstract.static_task.empty_task_builder import ( + EmptyStaticTaskBuilder, +) +from mephisto.operations.registry import register_mephisto_abstraction + +import os +import time +import csv +import json + +from typing import ClassVar, List, Type, Any, Dict, Iterable, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.blueprint import ( + AgentState, + TaskRunner, + TaskBuilder, + OnboardingAgent, + ) + from mephisto.data_model.assignment import Assignment + from mephisto.data_model.worker import Worker + from argparse import _ArgumentGroup as ArgumentGroup + + +@dataclass +class SharedStaticTaskState(SharedTaskState): + static_task_data: List[Any] = field(default_factory=list) + + +@dataclass +class StaticBlueprintArgs(BlueprintArgs): + units_per_assignment: int = field( + default=1, metadata={"help": "How many workers you want to do each assignment"} + ) + extra_source_dir: str = field( + default=MISSING, + metadata={ + "help": ( + "Optional path to sources that the HTML may " + "refer to (such as images/video/css/scripts)" + ) + }, + ) + data_json: str = field( + default=MISSING, metadata={"help": "Path to JSON file containing task data"} + ) + data_jsonl: str = field( + default=MISSING, metadata={"help": "Path to JSON-L file containing task data"} + ) + data_csv: str = field( + default=MISSING, metadata={"help": "Path to csv file containing task data"} + ) + extra_source_dir: str = field( + default=MISSING, + metadata={ + "help": ( + "Optional path to sources that the HTML may " + "refer to (such as images/video/css/scripts)" + ) + }, + ) + + +class StaticBlueprint(Blueprint, OnboardingRequired): + """ + Abstract blueprint for a task that runs without any extensive backend. + These are generally one-off tasks sending data to the frontend and then + awaiting a response. + """ + + AgentStateClass: ClassVar[Type["AgentState"]] = StaticAgentState + OnboardingAgentStateClass: ClassVar[Type["AgentState"]] = StaticAgentState + TaskBuilderClass: ClassVar[Type["TaskBuilder"]] = EmptyStaticTaskBuilder + TaskRunnerClass: ClassVar[Type["TaskRunner"]] = StaticTaskRunner + ArgsClass: ClassVar[Type["BlueprintArgs"]] = StaticBlueprintArgs + supported_architects: ClassVar[List[str]] = ["mock"] # TODO update + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self.init_onboarding_config(task_run, args, shared_state) + + self._initialization_data_dicts: List[Dict[str, Any]] = [] + blue_args = args.blueprint + if blue_args.get("data_csv", None) is not None: + csv_file = os.path.expanduser(blue_args.data_csv) + with open(csv_file, "r", encoding="utf-8-sig") as csv_fp: + csv_reader = csv.reader(csv_fp) + headers = next(csv_reader) + for row in csv_reader: + row_data = {} + for i, col in enumerate(row): + row_data[headers[i]] = col + self._initialization_data_dicts.append(row_data) + elif blue_args.get("data_json", None) is not None: + json_file = os.path.expanduser(blue_args.data_json) + with open(json_file, "r", encoding="utf-8-sig") as json_fp: + json_data = json.loads(json_fp) + for jd in json_data: + self._initialization_data_dicts.append(jd) + elif blue_args.get("data_jsonl", None) is not None: + jsonl_file = os.path.expanduser(blue_args.data_jsonl) + with open(jsonl_file, "r", encoding="utf-8-sig") as jsonl_fp: + line = jsonl_fp.readline() + while line: + j = json.loads(line) + self._initialization_data_dicts.append(j) + line = jsonl_fp.readline() + elif shared_state.static_task_data is not None: + self._initialization_data_dicts = shared_state.static_task_data + else: + # instantiating a version of the blueprint, but not necessarily needing the data + pass + + @classmethod + def assert_task_args(cls, args: DictConfig, shared_state: "SharedTaskState"): + """Ensure that the data can be properly loaded""" + blue_args = args.blueprint + if blue_args.get("data_csv", None) is not None: + csv_file = os.path.expanduser(blue_args.data_csv) + assert os.path.exists( + csv_file + ), f"Provided csv file {csv_file} doesn't exist" + elif blue_args.get("data_json", None) is not None: + json_file = os.path.expanduser(blue_args.data_json) + assert os.path.exists( + json_file + ), f"Provided JSON file {json_file} doesn't exist" + elif blue_args.get("data_jsonl", None) is not None: + jsonl_file = os.path.expanduser(blue_args.data_jsonl) + assert os.path.exists( + jsonl_file + ), f"Provided JSON-L file {jsonl_file} doesn't exist" + elif shared_state.static_task_data is not None: + assert ( + len(shared_state.static_task_data) > 0 + ), "Length of data dict provided was 0" + else: + raise AssertionError( + "Must provide one of a data csv, json, json-L, or a list of tasks" + ) + + def get_initialization_data(self) -> Iterable["InitializationData"]: + """ + Return the InitializationData retrieved from the specified stream + """ + return [ + InitializationData( + shared=d, unit_data=[{}] * self.args.blueprint.units_per_assignment + ) + for d in self._initialization_data_dicts + ] + + def validate_onboarding( + self, worker: "Worker", onboarding_agent: "OnboardingAgent" + ) -> bool: + """ + Check the incoming onboarding data and evaluate if the worker + has passed the qualification or not. Return True if the worker + has qualified. + """ + data = onboarding_agent.state.get_data() + return self.shared_state.validate_onboarding( + data + ) # data["outputs"].get("success", True) diff --git a/mephisto/abstractions/blueprints/abstract/static_task/static_task_runner.py b/mephisto/abstractions/blueprints/abstract/static_task/static_task_runner.py new file mode 100644 index 000000000..cf8e827af --- /dev/null +++ b/mephisto/abstractions/blueprints/abstract/static_task/static_task_runner.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskRunner + +import os +import time +import threading + +from typing import ClassVar, List, Type, Any, Dict, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Unit, InitializationData + from mephisto.data_model.agent import Agent, OnboardingAgent + from mephisto.abstractions.blueprint import SharedTaskState + from omegaconf import DictConfig + + +SYSTEM_SENDER = "mephisto" # TODO(CLEAN) pull from somewhere + + +class StaticTaskRunner(TaskRunner): + """ + Task runner for a static task + + Static tasks always assume single unit assignments, + as only one person can work on them at a time + """ + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self.is_concurrent = False + self.assignment_duration_in_seconds = ( + task_run.get_task_config().assignment_duration_in_seconds + ) + + def get_init_data_for_agent(self, agent: "Agent") -> Dict[str, Any]: + """ + Return the data for an agent already assigned to a particular unit + """ + init_state = agent.state.get_init_state() + if init_state is not None: + # reconnecting agent, give what we've got + return init_state + else: + assignment = agent.get_unit().get_assignment() + assignment_data = self.get_data_for_assignment(assignment) + agent.state.set_init_state(assignment_data.shared) + return assignment_data.shared + + def run_onboarding(self, agent: "OnboardingAgent"): + """ + Static onboarding flows eaxactly like a regular task, waiting for + the submit to come through + """ + agent_act = agent.act(timeout=self.assignment_duration_in_seconds) + + def cleanup_onboarding(self, agent: "OnboardingAgent"): + """Nothing to clean up in a static onboarding""" + return + + def run_unit(self, unit: "Unit", agent: "Agent") -> None: + """ + Static runners will get the task data, send it to the user, then + wait for the agent to act (the data to be completed) + """ + # Frontend implicitly asks for the initialization data, so we just need + # to wait for a response + agent_act = agent.act(timeout=self.assignment_duration_in_seconds) + + def cleanup_unit(self, unit: "Unit") -> None: + """There is currently no cleanup associated with killing an incomplete task""" + return diff --git a/mephisto/abstractions/blueprints/mock/__init__.py b/mephisto/abstractions/blueprints/mock/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/blueprints/mock/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/blueprints/mock/mock_agent_state.py b/mephisto/abstractions/blueprints/mock/mock_agent_state.py new file mode 100644 index 000000000..a5c623a8a --- /dev/null +++ b/mephisto/abstractions/blueprints/mock/mock_agent_state.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +# 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. + +from typing import List, Optional, Dict, Any, TYPE_CHECKING +from mephisto.abstractions.blueprint import AgentState +import os +import json + +if TYPE_CHECKING: + from mephisto.data_model.agent import Agent + from mephisto.data_model.packet import Packet + + +class MockAgentState(AgentState): + """ + Mock agent state that is to be used for testing + """ + + def __init__(self, agent: "Agent"): + """Mock agent states keep everything in local memory""" + self.agent = agent + self.state: Dict[str, Any] = {} + self.init_state: Any = None + + def set_init_state(self, data: Any) -> bool: + """Set the initial state for this agent""" + if self.init_state is not None: + # Initial state is already set + return False + else: + self.init_state = data + self.save_data() + return True + + def get_init_state(self) -> Optional[Dict[str, Any]]: + """ + Return the initial state for this agent, + None if no such state exists + """ + return self.init_state + + def load_data(self) -> None: + """Mock agent states have no data stored""" + pass + + def get_data(self) -> Dict[str, Any]: + """Return dict of this agent's state""" + return self.state + + def save_data(self) -> None: + """Mock agents don't save data (yet)""" + pass + + def update_data(self, packet: "Packet") -> None: + """Put new data into this mock state""" + self.state = packet.data diff --git a/mephisto/abstractions/blueprints/mock/mock_blueprint.py b/mephisto/abstractions/blueprints/mock/mock_blueprint.py new file mode 100644 index 000000000..e8f5c824d --- /dev/null +++ b/mephisto/abstractions/blueprints/mock/mock_blueprint.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import ( + Blueprint, + OnboardingRequired, + BlueprintArgs, + SharedTaskState, +) +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from mephisto.data_model.assignment import InitializationData +from mephisto.abstractions.blueprints.mock.mock_agent_state import MockAgentState +from mephisto.abstractions.blueprints.mock.mock_task_runner import MockTaskRunner +from mephisto.abstractions.blueprints.mock.mock_task_builder import MockTaskBuilder +from mephisto.operations.registry import register_mephisto_abstraction + +import os +import time + +from typing import ClassVar, List, Type, Any, Dict, Iterable, TYPE_CHECKING, Optional + +if TYPE_CHECKING: + from mephsito.data_model.agent import OnboardingAgent + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.blueprint import AgentState, TaskRunner, TaskBuilder + from mephisto.data_model.assignment import Assignment + from mephisto.data_model.worker import Worker + from argparse import _ArgumentGroup as ArgumentGroup + +BLUEPRINT_TYPE = "mock" + + +@dataclass +class MockBlueprintArgs(BlueprintArgs): + _blueprint_type: str = BLUEPRINT_TYPE + num_assignments: int = field( + default=MISSING, + metadata={ + "help": "How many workers you want to do each assignment", + "required": True, + }, + ) + use_onboarding: bool = field( + default=False, metadata={"help": "Whether onboarding should be required"} + ) + timeout_time: int = field( + default=0, + metadata={"help": "Whether acts in the run assignment should have a timeout"}, + ) + is_concurrent: bool = field( + default=True, + metadata={"help": "Whether to run this mock task as a concurrent task or not"}, + ) + + +@register_mephisto_abstraction() +class MockBlueprint(Blueprint, OnboardingRequired): + """Mock of a task type, for use in testing""" + + AgentStateClass: ClassVar[Type["AgentState"]] = MockAgentState + OnboardingAgentStateClass: ClassVar[Type["AgentState"]] = MockAgentState + TaskBuilderClass: ClassVar[Type["TaskBuilder"]] = MockTaskBuilder + TaskRunnerClass: ClassVar[Type["TaskRunner"]] = MockTaskRunner + ArgsClass: ClassVar[Type["BlueprintArgs"]] = MockBlueprintArgs + supported_architects: ClassVar[List[str]] = ["mock"] + BLUEPRINT_TYPE = BLUEPRINT_TYPE + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self.init_onboarding_config(task_run, args, shared_state) + + def get_initialization_data(self) -> Iterable[InitializationData]: + """ + Return the number of empty assignments specified in --num-assignments + """ + return [ + MockTaskRunner.get_mock_assignment_data() + for i in range(self.args.blueprint.num_assignments) + ] + + def validate_onboarding( + self, worker: "Worker", onboarding_agent: "OnboardingAgent" + ) -> bool: + """ + Onboarding validation for MockBlueprints just returns the 'should_pass' field + """ + return onboarding_agent.state.get_data()["should_pass"] diff --git a/mephisto/abstractions/blueprints/mock/mock_task_builder.py b/mephisto/abstractions/blueprints/mock/mock_task_builder.py new file mode 100644 index 000000000..196f6dbb8 --- /dev/null +++ b/mephisto/abstractions/blueprints/mock/mock_task_builder.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskBuilder + +import os +import time + +from typing import ClassVar, List, Type, Any, Dict, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Assignment + from argparse import _ArgumentGroup as ArgumentGroup + + +class MockTaskBuilder(TaskBuilder): + """Builder for a mock task, for use in testing""" + + BUILT_FILE = "done.built" + BUILT_MESSAGE = "built!" + + def build_in_dir(self, build_dir: str): + """Mock tasks don't really build anything (yet)""" + with open(os.path.join(build_dir, self.BUILT_FILE), "w+") as built_file: + built_file.write(self.BUILT_MESSAGE) diff --git a/mephisto/abstractions/blueprints/mock/mock_task_runner.py b/mephisto/abstractions/blueprints/mock/mock_task_runner.py new file mode 100644 index 000000000..0c0c90f53 --- /dev/null +++ b/mephisto/abstractions/blueprints/mock/mock_task_runner.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskRunner, SharedTaskState +from mephisto.data_model.assignment import InitializationData + +import os +import time + +from typing import ClassVar, List, Type, Any, Dict, Union, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Assignment, Unit + from mephisto.data_model.agent import Agent, OnboardingAgent + from argparse import _ArgumentGroup as ArgumentGroup + from omegaconf import DictConfig + + +class MockTaskRunner(TaskRunner): + """Mock of a task runner, for use in testing""" + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self.timeout = args.blueprint.timeout_time + self.tracked_tasks: Dict[str, Union["Assignment", "Unit"]] = {} + self.is_concurrent = args.blueprint.get("is_concurrent", True) + print(f"Blueprint is concurrent: {self.is_concurrent}, {args}") + + @staticmethod + def get_mock_assignment_data() -> InitializationData: + return InitializationData(shared={}, unit_data=[{}, {}]) + + @staticmethod + def get_data_for_assignment(assignment: "Assignment") -> InitializationData: + """ + Mock tasks have no data unless given during testing + """ + return MockTaskRunner.get_mock_assignment_data() + + def get_init_data_for_agent(self, agent: "Agent") -> Dict[str, Any]: + """ + Return the data for an agent already assigned to a particular unit + """ + # TODO(#97) implement + pass + + def run_onboarding(self, onboarding_agent: "OnboardingAgent"): + """ + Mock runners simply wait for an act to come in with whether + or not onboarding is complete + """ + packet = onboarding_agent.act(timeout=self.timeout) + onboarding_agent.did_submit.set() + onboarding_agent.mark_done() + + def run_unit(self, unit: "Unit", agent: "Agent"): + """ + Mock runners will pass the agents for the given assignment + all of the required messages to finish a task. + """ + self.tracked_tasks[unit.db_id] = unit + time.sleep(0.3) + assigned_agent = unit.get_assigned_agent() + assert assigned_agent is not None, "No agent was assigned" + assert ( + assigned_agent.db_id == agent.db_id + ), "Task was not given to assigned agent" + packet = agent.act(timeout=self.timeout) + if packet is not None: + agent.observe(packet) + agent.did_submit.set() + agent.mark_done() + del self.tracked_tasks[unit.db_id] + + def run_assignment(self, assignment: "Assignment", agents: List["Agent"]): + """ + Mock runners will pass the agents for the given assignment + all of the required messages to finish a task. + """ + self.tracked_tasks[assignment.db_id] = assignment + agent_dict = {a.db_id: a for a in agents} + time.sleep(0.3) + for unit in assignment.get_units(): + assigned_agent = unit.get_assigned_agent() + assert assigned_agent is not None, "Task was not fully assigned" + agent = agent_dict.get(assigned_agent.db_id) + assert agent is not None, "Task was not launched with assigned agents" + packet = agent.act(timeout=self.timeout) + if packet is not None: + agent.observe(packet) + agent.did_submit.set() + agent.mark_done() + del self.tracked_tasks[assignment.db_id] + + def cleanup_assignment(self, assignment: "Assignment"): + """No cleanup required yet for ending mock runs""" + pass + + def cleanup_unit(self, unit: "Unit"): + """No cleanup required yet for ending mock runs""" + pass + + def cleanup_onboarding(self, onboarding_agent: "OnboardingAgent"): + """No cleanup required yet for ending onboarding in mocks""" + pass diff --git a/mephisto/abstractions/blueprints/parlai_chat/__init__.py b/mephisto/abstractions/blueprints/parlai_chat/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_agent_state.py b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_agent_state.py new file mode 100644 index 000000000..031cd7209 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_agent_state.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 + +# 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. + +from typing import List, Optional, Dict, Any, Tuple, TYPE_CHECKING +from mephisto.abstractions.blueprint import AgentState +from mephisto.data_model.packet import ( + PACKET_TYPE_AGENT_ACTION, + PACKET_TYPE_UPDATE_AGENT_STATUS, +) +import os +import json +import time + +if TYPE_CHECKING: + from mephisto.data_model.agent import Agent + from mephisto.data_model.packet import Packet + + +class ParlAIChatAgentState(AgentState): + """ + Holds information about ParlAI-style chat. Data is stored in json files + containing every act from the ParlAI world. + """ + + def __init__(self, agent: "Agent"): + """ + Create an AgentState to track the state of an agent's work on a Unit + + Initialize with an existing file if it exists. + """ + self.agent = agent + data_file = self._get_expected_data_file() + if os.path.exists(data_file): + self.load_data() + else: + self.messages: List[Dict[str, Any]] = [] + self.init_data = None + self.save_data() + + def set_init_state(self, data: Any) -> bool: + """Set the initial state for this agent""" + if self.init_data is not None: + # Initial state is already set + return False + else: + self.init_data = data + self.save_data() + return True + + def get_init_state(self) -> Optional[Dict[str, Any]]: + """ + Return the initial state for this agent, + None if no such state exists + """ + if self.init_data is None: + return None + return {"task_data": self.init_data, "raw_messages": self.messages} + + def _get_expected_data_file(self) -> str: + """Return the place we would expect to find data for this agent state""" + agent_dir = self.agent.get_data_dir() + os.makedirs(agent_dir, exist_ok=True) + return os.path.join(agent_dir, "state.json") + + def load_data(self) -> None: + """Load stored data from a file to this object""" + agent_file = self._get_expected_data_file() + with open(agent_file, "r") as state_json: + state = json.load(state_json) + self.messages = state["outputs"]["messages"] + self.init_data = state["inputs"] + + def get_data(self) -> Dict[str, Any]: + """Return dict with the messages of this agent""" + return {"outputs": {"messages": self.messages}, "inputs": self.init_data} + + def get_parsed_data(self) -> Dict[str, Any]: + """Return the formatted input, conversations, and final data""" + init_data = self.init_data + save_data = None + messages = [ + m["data"] + for m in self.messages + if m["packet_type"] == PACKET_TYPE_AGENT_ACTION + ] + agent_name = None + if len(messages) > 0: + for m in self.messages: + if m["packet_type"] == PACKET_TYPE_UPDATE_AGENT_STATUS: + if "agent_display_name" in m["data"]["state"]: + agent_name = m["data"]["state"]["agent_display_name"] + break + if "MEPHISTO_is_submit" in messages[-1]: + messages = messages[:-1] + if "WORLD_DATA" in messages[-1]: + save_data = messages[-1]["WORLD_DATA"] + messages = messages[:-1] + return { + "agent_name": agent_name, + "initial_data": init_data, + "messages": messages, + "save_data": save_data, + } + + def save_data(self) -> None: + """Save all messages from this agent to """ + agent_file = self._get_expected_data_file() + with open(agent_file, "w+") as state_json: + json.dump(self.get_data(), state_json) + + def update_data(self, packet: "Packet") -> None: + """ + Append the incoming packet as well as who it came from + """ + message_data = packet.to_sendable_dict() + message_data["timestamp"] = time.time() + self.messages.append(message_data) + self.save_data() diff --git a/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_blueprint.py b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_blueprint.py new file mode 100644 index 000000000..8421dafd0 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_blueprint.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import ( + Blueprint, + OnboardingRequired, + BlueprintArgs, + SharedTaskState, +) +from dataclasses import dataclass, field +from mephisto.data_model.assignment import InitializationData +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_agent_state import ( + ParlAIChatAgentState, +) +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_task_runner import ( + ParlAIChatTaskRunner, +) +from mephisto.abstractions.blueprints.parlai_chat.parlai_chat_task_builder import ( + ParlAIChatTaskBuilder, +) +from mephisto.operations.registry import register_mephisto_abstraction +from omegaconf import DictConfig, MISSING + +import os +import time +import csv +import sys + +from importlib import import_module + +from typing import ClassVar, List, Type, Any, Dict, Iterable, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.worker import Worker + from mephisto.data_model.agent import Agent, OnboardingAgent + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.blueprint import AgentState, TaskRunner, TaskBuilder + from mephisto.data_model.assignment import Assignment + from argparse import _ArgumentGroup as ArgumentGroup + +BLUEPRINT_TYPE = "parlai_chat" + + +MISSING_SOMETHING_TEXT = ( + "

" + "You didn't specify a task_description_file and also didn't override the " + "frontend `TaskPreviewView` (if this is a preview) or the `TaskDescription` " + "component (if this is in-task)." + "

" +) + + +@dataclass +class SharedParlAITaskState(SharedTaskState): + frontend_task_opts: Dict[str, Any] = field(default_factory=dict) + world_opt: Dict[str, Any] = field(default_factory=dict) + onboarding_world_opt: Dict[str, Any] = field(default_factory=dict) + + +@dataclass +class ParlAIChatBlueprintArgs(BlueprintArgs): + _blueprint_type: str = BLUEPRINT_TYPE + _group: str = field( + default="ParlAIChatBlueprint", + metadata={ + "help": """ + Tasks launched from static blueprints need a + source html file to display to workers, as well as a csv + containing values that will be inserted into templates in + the html. + """ + }, + ) + world_file: str = field( + default=MISSING, + metadata={"help": "Path to file containing ParlAI world", "required": True}, + ) + preview_source: str = field( + default=MISSING, + metadata={"help": "Optional path to source HTML file to preview the task"}, + ) + task_description_file: str = field( + default=MISSING, + metadata={ + "help": ( + "Path to file for the extended description of the task. " + "Required if not providing a custom source bundle." + ) + }, + ) + custom_source_bundle: str = field( + default=MISSING, + metadata={"help": "Optional path to a fully custom frontend bundle"}, + ) + custom_source_dir: str = field( + default=MISSING, + metadata={"help": "Optional path to a directory containing custom js code"}, + ) + extra_source_dir: str = field( + default=MISSING, + metadata={ + "help": ( + "Optional path to sources that the frontend may " + "refer to (such as images/video/css/scripts)" + ) + }, + ) + context_csv: str = field( + default=MISSING, + metadata={"help": "Optional path to csv containing task context"}, + ) + num_conversations: int = field( + default=MISSING, + metadata={ + "help": "Optional count of conversations to have if no context provided" + }, + ) + + +@register_mephisto_abstraction() +class ParlAIChatBlueprint(Blueprint, OnboardingRequired): + """Blueprint for a task that runs a parlai chat """ + + AgentStateClass: ClassVar[Type["AgentState"]] = ParlAIChatAgentState + OnboardingAgentStateClass: ClassVar[Type["AgentState"]] = ParlAIChatAgentState + TaskBuilderClass: ClassVar[Type["TaskBuilder"]] = ParlAIChatTaskBuilder + TaskRunnerClass: ClassVar[Type["TaskRunner"]] = ParlAIChatTaskRunner + ArgsClass = ParlAIChatBlueprintArgs + SharedStateClass = SharedParlAITaskState + supported_architects: ClassVar[List[str]] = [ + "mock", + "heroku", + "local", + ] # TODO update? + BLUEPRINT_TYPE = BLUEPRINT_TYPE + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self._initialization_data_dicts: List[Dict[str, Any]] = [] + self.init_onboarding_config(task_run, args, shared_state) + + if args.blueprint.get("context_csv", None) is not None: + csv_file = os.path.expanduser(args.blueprint.context_csv) + with open(csv_file, "r", encoding="utf-8-sig") as csv_fp: + csv_reader = csv.reader(csv_fp) + headers = next(csv_reader) + for row in csv_reader: + row_data: Dict[str, Any] = {} + for i, col in enumerate(row): + row_data[headers[i]] = col + self._initialization_data_dicts.append(row_data) + elif args.blueprint.get("num_conversations", None) is not None: + self._initialization_data_dicts = [{}] * args.blueprint.num_conversations + else: + # TODO(#95) handle JSON and python dicts directly + raise NotImplementedError( + "Parsing parlai tasks directly from dicts or JSON is not supported yet" + ) + + world_file_path = os.path.expanduser(args.blueprint.world_file) + world_module_path = world_file_path[:-3] + sys.path.append(world_module_path) + world_module_name = os.path.basename(world_file_path)[:-3] + world_module = import_module(world_module_name) + self.world_module = world_module + assert hasattr(world_module, "make_world") + assert hasattr(world_module, "get_world_params") + self.agent_count = world_module.get_world_params()[ # type: ignore + "agent_count" + ] + + self.full_task_description = MISSING_SOMETHING_TEXT + if args.blueprint.get("task_description_file", None) is not None: + full_path = os.path.expanduser(args.blueprint.task_description_file) + assert os.path.exists( + full_path + ), f"Target task description path {full_path} doesn't exist" + with open(full_path, "r") as description_fp: + self.full_task_description = description_fp.read() + + @classmethod + def assert_task_args( + cls, args: "DictConfig", shared_state: "SharedTaskState" + ) -> None: + """Ensure that arguments are properly configured to launch this task""" + # assert world file is valid + world_file_path = os.path.expanduser(args.blueprint.world_file) + world_module_dir = os.path.dirname(world_file_path) + assert os.path.exists( + world_file_path + ), f"Provided world path {world_file_path} doesn't exist" + sys.path.append(world_module_dir) + world_module_name = os.path.basename(world_file_path)[:-3] + world_module = import_module(world_module_name) + assert hasattr( + world_module, "make_world" + ), "Provided world file has no `make_world` method" + assert hasattr( + world_module, "get_world_params" + ), "Provided world file has no `get_world_params` method" + + # assert some method for determining quantity of conversations + if args.blueprint.get("context_csv", None) is not None: + raise AssertionError( + "Specifying task quantity via context csv is not yet implemented" + ) + elif args.blueprint.get("num_conversations", None) is not None: + assert ( + args.blueprint.num_conversations > 0 + ), "Must have at least one conversation" + else: + raise AssertionError( + "Must specify one of --context-csv or --num-conversations" + ) + + if args.blueprint.get("custom_source_bundle", None) is not None: + custom_source_file_path = os.path.expanduser( + args.blueprint.custom_source_bundle + ) + assert os.path.exists( + custom_source_file_path + ), f"Provided custom bundle doesn't exist at {custom_source_file_path}" + + if args.blueprint.get("custom_source_dir", None) is not None: + custom_source_dir_path = os.path.expanduser( + args.blueprint.custom_source_dir + ) + assert os.path.exists( + custom_source_dir_path + ), f"Provided custom source dir doesn't exist at {custom_source_dir_path}" + + if args.blueprint.get("preview_source", None) is not None: + preview_source_file = os.path.expanduser(args.blueprint.preview_source) + assert os.path.exists( + preview_source_file + ), f"Provided preview source doesn't exist at {preview_source_file}" + + if args.blueprint.get("extra_source_dir", None) is not None: + extra_source_dir = os.path.expanduser(args.blueprint.extra_source_dir) + assert os.path.exists( + extra_source_dir + ), f"Provided extra resource dir doesn't exist at {extra_source_dir}" + + def get_frontend_args(self) -> Dict[str, Any]: + """ + Specifies what options within a task_config should be fowarded + to the client for use by the task's frontend + """ + # TODO move frontend args in + frontend_task_config = { + "task_description": self.full_task_description, + "frame_height": 650, + "chat_title": self.args.task.task_title, + "has_preview": self.args.blueprint.get("preview_source", None) is not None, + "block_mobile": True, + "frontend_task_opts": self.shared_state.frontend_task_opts, + } + frontend_task_config.update(super().get_frontend_args()) + return frontend_task_config + + def get_initialization_data(self) -> Iterable["InitializationData"]: + """ + Return the InitializationData retrieved from the specified stream + """ + return [ + InitializationData(shared=d, unit_data=[{}] * self.agent_count) + for d in self._initialization_data_dicts + ] + + def validate_onboarding( + self, worker: "Worker", onboarding_agent: "OnboardingAgent" + ) -> bool: + if hasattr(self.world_module, "validate_onboarding"): + return self.world_module.validate_onboarding( # type: ignore + onboarding_agent.state.get_data() + ) + return True diff --git a/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_builder.py b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_builder.py new file mode 100644 index 000000000..7551a3807 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_builder.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskBuilder + +from distutils.dir_util import copy_tree +import os +import time +import sh +import shutil +import subprocess + +from typing import ClassVar, List, Type, Any, Dict, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Assignment + +PARLAI_TASK_DIR = os.path.dirname(__file__) +FRONTEND_SOURCE_DIR = os.path.join(PARLAI_TASK_DIR, "webapp") +FRONTEND_BUILD_DIR = os.path.join(FRONTEND_SOURCE_DIR, "build") + +BUILT_FILE = "done.built" +CUSTOM_BUILD_DIRNAME = "_generated" + + +class ParlAIChatTaskBuilder(TaskBuilder): + """ + Builder for a parlai chat task, pulls the appropriate html, + builds the frontend (if a build doesn't already exist), + then puts the file into the server directory + """ + + BUILT_FILE = BUILT_FILE + BUILT_MESSAGE = "built!" + + def rebuild_core(self): + """Rebuild the frontend for this task""" + return_dir = os.getcwd() + os.chdir(FRONTEND_SOURCE_DIR) + if os.path.exists(FRONTEND_BUILD_DIR): + shutil.rmtree(FRONTEND_BUILD_DIR) + packages_installed = subprocess.call(["npm", "install"]) + if packages_installed != 0: + raise Exception( + "please make sure npm is installed, otherwise view " + "the above error for more info." + ) + + webpack_complete = subprocess.call(["npm", "run", "dev"]) + if webpack_complete != 0: + raise Exception( + "Webpack appears to have failed to build your " + "frontend. See the above error for more information." + ) + os.chdir(return_dir) + + def build_and_return_custom_bundle(self, custom_src_dir): + """Locate all of the custom files used for a custom build, create + a prebuild directory containing all of them, then build the + custom source. + + Check dates to only go through this build process when files have changes + """ + # TODO add custom component directories, and recursively check those + TARGET_BUILD_FILES = {"main.js": "src/main.js", "package.json": "package.json"} + + prebuild_path = os.path.join(custom_src_dir, CUSTOM_BUILD_DIRNAME) + build_path = os.path.join(prebuild_path, "build", "bundle.js") + + # see if we need to rebuild + if os.path.exists(build_path): + created_date = os.path.getmtime(build_path) + up_to_date = True + for fn in TARGET_BUILD_FILES.keys(): + possible_conflict = os.path.join(custom_src_dir, fn) + if os.path.exists(possible_conflict): + if os.path.getmtime(possible_conflict) > created_date: + up_to_date = False + break + if up_to_date: + return build_path + + # build anew + REQUIRED_SOURCE_FILES = [ + ".babelrc", + ".eslintrc", + "package.json", + "webpack.config.js", + ] + REQUIRED_SOURCE_DIRS = ["src"] + if not os.path.exists(os.path.join(prebuild_path, "build")): + os.makedirs(os.path.join(prebuild_path, "build"), exist_ok=True) + + # Copy default files + for src_dir in REQUIRED_SOURCE_DIRS: + src_path = os.path.join(FRONTEND_SOURCE_DIR, src_dir) + dst_path = os.path.join(prebuild_path, src_dir) + if os.path.exists(dst_path): + shutil.rmtree(dst_path) + shutil.copytree(src_path, dst_path) + for src_file in REQUIRED_SOURCE_FILES: + src_path = os.path.join(FRONTEND_SOURCE_DIR, src_file) + dst_path = os.path.join(prebuild_path, src_file) + shutil.copy2(src_path, dst_path) + + # copy custom files + for src_file in TARGET_BUILD_FILES.keys(): + src_path = os.path.join(custom_src_dir, src_file) + if os.path.exists(src_path): + dst_path = os.path.join(prebuild_path, TARGET_BUILD_FILES[src_file]) + shutil.copy2(src_path, dst_path) + + # navigate and build + return_dir = os.getcwd() + os.chdir(prebuild_path) + packages_installed = subprocess.call(["npm", "install"]) + if packages_installed != 0: + raise Exception( + "please make sure npm is installed, otherwise view " + "the above error for more info." + ) + + webpack_complete = subprocess.call(["npm", "run", "dev"]) + if webpack_complete != 0: + raise Exception( + "Webpack appears to have failed to build your " + "frontend. See the above error for more information." + ) + + # cleanup and return + os.chdir(return_dir) + return build_path + + def build_in_dir(self, build_dir: str): + """Build the frontend if it doesn't exist, then copy into the server directory""" + # Only build this task if it hasn't already been built + if not os.path.exists(FRONTEND_BUILD_DIR): + self.rebuild_core() + + custom_source_dir = self.args.blueprint.get("custom_source_dir", None) + build_bundle = None + if custom_source_dir is not None: + custom_source_dir = os.path.expanduser(custom_source_dir) + build_bundle = self.build_and_return_custom_bundle(custom_source_dir) + + # Copy over the preview file as preview.html, use the default if none specified + target_resource_dir = os.path.join(build_dir, "static") + preview_file = self.args.blueprint.get("preview_source", None) + if preview_file is not None: + use_preview_file = os.path.expanduser(preview_file) + target_path = os.path.join(target_resource_dir, "preview.html") + shutil.copy2(use_preview_file, target_path) + + # If any additional task files are required via a source_dir, copy those as well + extra_dir_path = self.args.blueprint.get("extra_source_dir", None) + if extra_dir_path is not None: + extra_dir_path = os.path.expanduser(extra_dir_path) + copy_tree(extra_dir_path, target_resource_dir) + + bundle_js_file = self.args.blueprint.get("custom_source_bundle", None) + if bundle_js_file is None: + if build_bundle is not None: + bundle_js_file = build_bundle + else: + bundle_js_file = os.path.join(FRONTEND_BUILD_DIR, "bundle.js") + target_path = os.path.join(target_resource_dir, "bundle.js") + shutil.copy2(bundle_js_file, target_path) + + # Copy over the static files for this task: + for fin_file in ["index.html", "notif.mp3"]: + copied_static_file = os.path.join( + FRONTEND_SOURCE_DIR, "src", "static", fin_file + ) + target_path = os.path.join(target_resource_dir, fin_file) + shutil.copy2(copied_static_file, target_path) + + # Write a built file confirmation + with open(os.path.join(build_dir, self.BUILT_FILE), "w+") as built_file: + built_file.write(self.BUILT_MESSAGE) diff --git a/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_runner.py b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_runner.py new file mode 100644 index 000000000..fd115a39a --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/parlai_chat_task_runner.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskRunner +from mephisto.data_model.agent import Agent, OnboardingAgent + +try: + from parlai.core.agents import Agent as ParlAIAgent + from parlai.core.message import Message +except: + + class ParlAIAgent: + def __init__(self, *args, **kwargs): + raise NotImplementedError( + "You need to install ParlAI to use this blueprint" + ) + + class Message: + def __init__(self, *args, **kwargs): + raise NotImplementedError( + "You need to install ParlAI to use this blueprint" + ) + + pass # ParlAI is not installed. TODO remove when we move this blueprint to ParlAI + +from mephisto.data_model.packet import ( + Packet, + PACKET_TYPE_AGENT_ACTION, + PACKET_TYPE_UPDATE_AGENT_STATUS, +) + +from importlib import import_module + +import os +import sh +import shlex +import shutil +import subprocess +import sys +from uuid import uuid4 + +from typing import ClassVar, List, Type, Any, Dict, Union, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.blueprint import AgentState + from mephsito.data_model.assignment import Assignment + + +class MephistoAgentWrapper(ParlAIAgent): + """ + Class that wraps a mephisto agent to be used as an + agent in ParlAI worlds + """ + + def __init__(self, agent: Union[Agent, OnboardingAgent]): + self.mephisto_agent = agent + self.__agent_id = "unnamed agent" + self.__mephisto_agent_id = agent.get_agent_id() + + @property + def agent_id(self): + """ + Agent IDs in ParlAI are used to identify the speaker, + and often are a label like "teacher" + """ + return self.__agent_id + + @agent_id.setter + def agent_id(self, new_agent_id: str): + """ + We want to be able to display these labels to the + frontend users, so when these are updated by a + world we forward that to the frontend + """ + packaged_act = Packet( + packet_type=PACKET_TYPE_UPDATE_AGENT_STATUS, + sender_id="mephisto", + receiver_id=self.__mephisto_agent_id, + data={"state": {"agent_display_name": new_agent_id}}, + ) + self.mephisto_agent.observe(packaged_act) + self.__agent_id = new_agent_id + + def act(self, timeout=None): + """ + ParlAI Agents send an act dict, we must convert this + """ + if timeout is None: + gotten_act = self.mephisto_agent.act() + else: + gotten_act = self.mephisto_agent.act(timeout=timeout) + if gotten_act is None: + return None + parsed_act = gotten_act.data + parsed_act["id"] = self.__agent_id + return Message(parsed_act) + + def observe(self, act): + """ + ParlAI Agents observe a dict, we must convert these to packets? + """ + if act.get("message_id") is None: + act["message_id"] = str(uuid4()) + packaged_act = Packet( + packet_type=PACKET_TYPE_AGENT_ACTION, + sender_id="mephisto", + receiver_id=self.__mephisto_agent_id, + data=act, + ) + self.mephisto_agent.observe(packaged_act) + + +class ParlAIChatTaskRunner(TaskRunner): + """ + Task runner for a parlai chat task + """ + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + world_file_path = os.path.expanduser(args.blueprint.world_file) + world_module_path = world_file_path[:-3] + sys.path.append(world_module_path) + world_module_name = os.path.basename(world_file_path)[:-3] + self.parlai_world_module = import_module(world_module_name) + world_params = self.parlai_world_module.get_world_params() + self.is_concurrent = world_params["agent_count"] > 1 + self.id_to_worlds: Dict[str, Any] = {} + + def get_init_data_for_agent(self, agent: "Agent") -> Dict[str, Any]: + """ + Return the data for an agent already assigned to a particular unit + """ + init_state = agent.state.get_init_state() + if init_state is not None: + # reconnecting agent, give what we've got + return init_state + else: + assignment = agent.get_unit().get_assignment() + assignment_data = self.get_data_for_assignment(assignment) + agent.state.set_init_state(assignment_data.shared) + new_state = agent.state.get_init_state() + assert new_state is not None, "Recently initialized state still None" + return new_state + + def get_world_id(self, world_type: str, extra_id: str) -> str: + """Get a world id specific to the given world type""" + return f"{world_type}-{extra_id}" + + def run_onboarding(self, agent: "OnboardingAgent") -> None: + """ + ParlAI Onboarding will initialize an onboarding + world, then run it to completion if possible + """ + opt: Dict[str, Any] = self.shared_state.onboarding_world_opt + parlai_agent = MephistoAgentWrapper(agent) + world = self.parlai_world_module.make_onboarding_world( # type: ignore + opt, parlai_agent + ) + world_id = self.get_world_id("onboard", agent.get_agent_id()) + self.id_to_worlds[world_id] = world + while ( + not world.episode_done() + and agent.get_agent_id() in self.running_onboardings + ): + world.parley() + world.shutdown() + if hasattr(world, "prep_save_data"): + agent.observe( + Packet( + packet_type=PACKET_TYPE_AGENT_ACTION, + sender_id="mephisto", + receiver_id=agent.db_id, + data={ + "id": "SUBMIT_WORLD_DATA", + "WORLD_DATA": world.prep_save_data([parlai_agent]), + "text": "", + }, + ) + ) + + def cleanup_onboarding(self, agent: "OnboardingAgent") -> None: + """Shutdown the world""" + onboarding_id = agent.get_agent_id() + world_id = self.get_world_id("onboard", onboarding_id) + self.id_to_worlds[world_id].shutdown() + del self.id_to_worlds[world_id] + + def run_assignment(self, assignment: "Assignment", agents: List["Agent"]) -> None: + """ + ParlAI runners will initialize a task world, then run them to completion + if possible + """ + for agent in agents: + assert agent is not None, "task was not fully assigned" + opt: Dict[str, Any] = self.shared_state.world_opt + parlai_agents = [MephistoAgentWrapper(a) for a in agents] + world = self.parlai_world_module.make_world(opt, parlai_agents) # type: ignore + world_id = self.get_world_id("assignment", assignment.db_id) + self.id_to_worlds[world_id] = world + while not world.episode_done() and assignment.db_id in self.running_assignments: + world.parley() + + # TODO(WISH) it would be nice to have individual agents be able to submit their + # final things without needing to wait for their partner, such + # as if one needs to rate and the other doesn't + + world.shutdown() + if hasattr(world, "prep_save_data"): + for idx in range(len(parlai_agents)): + agents[idx].observe( + Packet( + packet_type=PACKET_TYPE_AGENT_ACTION, + sender_id="mephisto", + receiver_id=agents[idx].db_id, + data={ + "id": "SUBMIT_WORLD_DATA", + "WORLD_DATA": world.prep_save_data([parlai_agents[idx]]), + "text": "", + }, + ) + ) + + def cleanup_assignment(self, assignment: "Assignment") -> None: + """Handle cleanup for a specific assignment""" + world_id = self.get_world_id("assignment", assignment.db_id) + self.id_to_worlds[world_id].shutdown() + del self.id_to_worlds[world_id] + + def run_unit(self, unit: "Unit", agent: "Agent") -> None: + """ + ParlAI runners will initialize a task world, then run them to completion + if possible + """ + agents = [agent] + opt: Dict[str, Any] = self.shared_state.world_opt + parlai_agents = [MephistoAgentWrapper(a) for a in agents] + world = self.parlai_world_module.make_world(opt, parlai_agents) # type: ignore + world_id = self.get_world_id("unit", unit.db_id) + self.id_to_worlds[world_id] = world + while not world.episode_done() and unit.db_id in self.running_units: + world.parley() + + # TODO(WISH) it would be nice to have individual agents be able to submit their + # final things without needing to wait for their partner, such + # as if one needs to rate and the other doesn't + + world.shutdown() + if hasattr(world, "prep_save_data"): + agent.observe( + Packet( + packet_type=PACKET_TYPE_AGENT_ACTION, + sender_id="mephisto", + receiver_id=agent.db_id, + data={ + "id": "SUBMIT_WORLD_DATA", + "WORLD_DATA": world.prep_save_data(parlai_agents), + "text": "", + }, + ) + ) + + def cleanup_unit(self, unit: "Unit") -> None: + """Handle cleanup for a specific unit""" + world_id = self.get_world_id("unit", unit.db_id) + self.id_to_worlds[world_id].shutdown() + del self.id_to_worlds[world_id] diff --git a/mephisto/abstractions/blueprints/parlai_chat/source/package-lock.json b/mephisto/abstractions/blueprints/parlai_chat/source/package-lock.json new file mode 100644 index 000000000..f26b5125a --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/source/package-lock.json @@ -0,0 +1,5490 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/cli": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", + "requires": { + "chokidar": "^2.1.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } + }, + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/compat-data": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", + "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", + "requires": { + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", + "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.7", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.7", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/generator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.7.tgz", + "integrity": "sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew==", + "requires": { + "@babel/types": "^7.8.7", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz", + "integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==", + "requires": { + "@babel/types": "^7.8.3", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz", + "integrity": "sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.7" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", + "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", + "requires": { + "@babel/compat-data": "^7.8.6", + "browserslist": "^4.9.1", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz", + "integrity": "sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz", + "integrity": "sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.6.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", + "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.8.6", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.7.tgz", + "integrity": "sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", + "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz", + "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", + "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", + "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz", + "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", + "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", + "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", + "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", + "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", + "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.7.tgz", + "integrity": "sha512-brYWaEPTRimOctz2NDA3jnBbDi7SVN2T4wYuu0aqSzxC3nozFZngGaw29CJ9ZPweB7k+iFmZuoG3IVPIcXmD2g==", + "requires": { + "@babel/helper-call-delegate": "^7.8.7", + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", + "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz", + "integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.8.3.tgz", + "integrity": "sha512-01OT7s5oa0XTLf2I8XGsL8+KqV9lx3EZV+jxn/L2LQ97CGKila2YMroTkCEIE0HV/FF7CMSRsIAybopdN9NTdg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz", + "integrity": "sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/preset-env": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.7.tgz", + "integrity": "sha512-BYftCVOdAYJk5ASsznKAUl53EMhfBbr8CJ1X+AJLfGPscQkwJFiaV/Wn9DPH/7fzm2v6iRYJKYHSqyynTGw0nw==", + "requires": { + "@babel/compat-data": "^7.8.6", + "@babel/helper-compilation-targets": "^7.8.7", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@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-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.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.6", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.6", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.8.3", + "@babel/plugin-transform-modules-systemjs": "^7.8.3", + "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.7", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/types": "^7.8.7", + "browserslist": "^4.8.5", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-react": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.8.3.tgz", + "integrity": "sha512-9hx0CwZg92jGb7iHYQVgi0tOEHP/kM60CtWJQnmbATSPIQQ2xYzfoCI3EdqAhFBeeJwYMdWQuDUHMsuDbH9hyQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.8.3", + "@babel/plugin-transform-react-jsx-self": "^7.8.3", + "@babel/plugin-transform-react-jsx-source": "^7.8.3" + } + }, + "@babel/runtime": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", + "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "requires": { + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", + "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==" + } + } + }, + "@babel/runtime-corejs2": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.8.7.tgz", + "integrity": "sha512-R8zbPiv25S0pGfMqAr55dRRxWB8vUeo3wicI4g9PFVBKmsy/9wmQUV1AaYW/kxRHUhx42TTh6F0+QO+4pwfYWg==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", + "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==" + } + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.6", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", + "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + }, + "@types/react": { + "version": "16.9.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.23.tgz", + "integrity": "sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/react-table": { + "version": "6.8.7", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.7.tgz", + "integrity": "sha512-1U0xl47jk0BzE+HNHgxZYSLvtybSvnlLhOpW9Mfqf9iuRm/fGqgRab3TKivPCY6Tl7WPFM2hWEJ1GnsuSFc9AQ==", + "requires": { + "@types/react": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "requires": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "requires": { + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==" + }, + "add-dom-event-listener": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/add-dom-event-listener/-/add-dom-event-listener-1.1.0.tgz", + "integrity": "sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw==", + "requires": { + "object-assign": "4.x" + } + }, + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "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" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "biskviit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/biskviit/-/biskviit-1.0.1.tgz", + "integrity": "sha1-A3oM1LcbnjMf2QoRIt4X3EnkIKc=", + "requires": { + "psl": "^1.1.7" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "bootstrap": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.4.1.tgz", + "integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==" + }, + "bowser": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz", + "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "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" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", + "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", + "requires": { + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.363", + "node-releases": "^1.1.50" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "requires": { + "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" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "caniuse-lite": { + "version": "1.0.30001032", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001032.tgz", + "integrity": "sha512-8joOm7BwcpEN4BfVHtfh0hBXSAPVYk+eUIcNntGtMkUWy/6AKRCDZINCLe3kB1vHhT2vBxBF85Hh9VlPXi/qjA==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "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" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "component-classes": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz", + "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=", + "requires": { + "component-indexof": "0.0.3" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "component-indexof": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz", + "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "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": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "core-js-compat": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", + "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", + "requires": { + "browserslist": "^4.8.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "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": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "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": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "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-animation": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/css-animation/-/css-animation-1.6.1.tgz", + "integrity": "sha512-/48+/BaEaHRY6kNQ2OIPzKf9A6g8WjZYjhiNDNuIVbsm5tXCGIAsHDjB4Xu1C4vXJtUWZo26O68OQkDpNBaPog==", + "requires": { + "babel-runtime": "6.x", + "component-classes": "^1.2.5" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + } + }, + "css-selector-tokenizer": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", + "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2", + "regexpu-core": "^4.6.0" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "csstype": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz", + "integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==" + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dom-align": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.10.4.tgz", + "integrity": "sha512-wytDzaru67AmqFOY4B9GUb/hrwWagezoYYK97D/vpK+ezg+cnuZO0Q2gltUPa7KfNmIqfRIYVCF8UhRDEHAmgQ==" + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "electron-to-chromium": { + "version": "1.3.372", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.372.tgz", + "integrity": "sha512-77a4jYC52OdisHM+Tne7dgWEvQT1FoNu/jYl279pP88ZtG4ZRIPyhQwAKxj6C2rzsyC1OwsOds9JlZtNncSz6g==" + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "requires": { + "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": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "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" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-CoJ58Gvjf58Ou1Z1YKMKSA2lmi4=", + "requires": { + "biskviit": "1.0.1", + "encoding": "0.1.12" + } + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "requires": { + "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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "requires": { + "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" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "sax": { + "version": "1.2.4", + "bundled": true + }, + "semver": { + "version": "5.7.1", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "requires": { + "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" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "requires": { + "postcss": "^6.0.1" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "keycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "requires": { + "leven": "^3.1.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "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" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "requires": { + "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": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "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" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "requires": { + "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" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "node-releases": { + "version": "1.1.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.51.tgz", + "integrity": "sha512-1eQEs6HFYY1kMXQPOLzCf7HdjReErmvn85tZESMczdCNVWP3Y7URYLBAyYynuI7yef1zj4HN5q+oB2x67QU0lw==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "requires": { + "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-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + } + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "rc-align": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-2.4.5.tgz", + "integrity": "sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw==", + "requires": { + "babel-runtime": "^6.26.0", + "dom-align": "^1.7.0", + "prop-types": "^15.5.8", + "rc-util": "^4.0.4" + } + }, + "rc-animate": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/rc-animate/-/rc-animate-2.10.3.tgz", + "integrity": "sha512-A9qQ5Y8BLlM7EhuCO3fWb/dChndlbWtY/P5QvPqBU7h4r5Q2QsvsbpTGgdYZATRDZbTRnJXXfVk9UtlyS7MBLg==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.6", + "css-animation": "^1.3.2", + "prop-types": "15.x", + "raf": "^3.4.0", + "rc-util": "^4.15.3", + "react-lifecycles-compat": "^3.0.4" + } + }, + "rc-slider": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-8.7.1.tgz", + "integrity": "sha512-WMT5mRFUEcrLWwTxsyS8jYmlaMsTVCZIGENLikHsNv+tE8ThU2lCoPfi/xFNUfJFNFSBFP3MwPez9ZsJmNp13g==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.5", + "prop-types": "^15.5.4", + "rc-tooltip": "^3.7.0", + "rc-util": "^4.0.4", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0", + "warning": "^4.0.3" + } + }, + "rc-tooltip": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-3.7.3.tgz", + "integrity": "sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww==", + "requires": { + "babel-runtime": "6.x", + "prop-types": "^15.5.8", + "rc-trigger": "^2.2.2" + } + }, + "rc-trigger": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-2.6.5.tgz", + "integrity": "sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.6", + "prop-types": "15.x", + "rc-align": "^2.4.0", + "rc-animate": "2.x", + "rc-util": "^4.4.0", + "react-lifecycles-compat": "^3.0.4" + } + }, + "rc-util": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-4.20.0.tgz", + "integrity": "sha512-rUqk4RqtDe4OfTsSk2GpbvIQNVtfmmebw4Rn7ZAA1TO1zLMLfyOF78ZyrEKqs8RDwoE3S1aXp0AX0ogLfSxXrQ==", + "requires": { + "add-dom-event-listener": "^1.1.0", + "babel-runtime": "6.x", + "prop-types": "^15.5.10", + "react-is": "^16.12.0", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0" + } + }, + "react": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz", + "integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-bootstrap": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.4.tgz", + "integrity": "sha512-xj+JfaPOvnvr3ow0aHC7Y3HaBKZNR1mm361hVxVzVX3fcdJNIrfiodbQ0m9nLBpNxiKG6FTU2lq/SbTDYT2vew==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0", + "classnames": "^2.2.5", + "dom-helpers": "^3.2.0", + "invariant": "^2.2.4", + "keycode": "^2.2.0", + "prop-types": "^15.6.1", + "prop-types-extra": "^1.0.1", + "react-overlays": "^0.8.0", + "react-prop-types": "^0.4.0", + "react-transition-group": "^2.0.0", + "uncontrollable": "^5.0.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-dom": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz", + "integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.0" + } + }, + "react-is": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", + "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-overlays": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", + "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", + "requires": { + "classnames": "^2.2.5", + "dom-helpers": "^3.2.1", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-transition-group": "^2.2.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-prop-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", + "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", + "requires": { + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-table": { + "version": "6.11.5", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz", + "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==", + "requires": { + "@types/react-table": "^6.8.5", + "classnames": "^2.2.5", + "react-is": "^16.8.1" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.2.tgz", + "integrity": "sha512-V4+lGplCM/ikqi5/mkkpJ06e9Bujq1NFmNLvsCs56zg3ZbzrnUzAtizZ24TXxtRX/W2jcdScwQCnbL0CICTFkQ==", + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" + }, + "regjsparser": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", + "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scheduler": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.0.tgz", + "integrity": "sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "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": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + }, + "terser": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz", + "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "uncontrollable": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz", + "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==", + "requires": { + "invariant": "^2.2.4" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", + "requires": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "dependencies": { + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" + } + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", + "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.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.1", + "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.0", + "webpack-sources": "^1.4.1" + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "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.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/.babelrc b/mephisto/abstractions/blueprints/parlai_chat/webapp/.babelrc new file mode 100644 index 000000000..5507f2e86 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@babel/env", "@babel/preset-react"], + "plugins": ["@babel/plugin-proposal-class-properties"] +} diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/.eslintrc b/mephisto/abstractions/blueprints/parlai_chat/webapp/.eslintrc new file mode 100644 index 000000000..fcf5ef32e --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": ["react-app"] +} diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/README.md b/mephisto/abstractions/blueprints/parlai_chat/webapp/README.md new file mode 100644 index 000000000..f7047eae4 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/README.md @@ -0,0 +1,16 @@ +## Description + +`parlai/mturk/core/react_server` contains several files and folders that comprise the server that is built to serve the task into the MTurk UI: + +### Folders + +- **dev/**: contains the react frontend components that comprise the frontend, as well as the css and main javascript file that ties it all together. Of these, the `dev/components/core_components.jsx` file is likely the most interesting, as it contains the frontend components that are rendered in a normal task. To replace them, you'll need to create a `custom.jsx` file following the formatting in the dummy version in the same folder. See an example of this in the `react_task_demo` task in the `parlai/mturk/tasks` folder. +- **server/**: contains the package that is actually served by the heroku server for the task. `server.js` is what ends up running on the heroku server, which is a simple one-page server with a router for socket messages. The `parlai/mturk/core/server_utils.py` file handles building the components from dev into a new copy of this folder when launching a new task. + +### Files + +The rest of the files are associated with the process of building the finalized javascript main via node and outputting it into the server directory. + +- **.babelrc**: links presets and plugins required for babel to transpile the react jsx files into pure js. +- **package.json**: contains the build dependencies and directs the main build process to run the contents of the webpack config file. +- **webpack.config.js**: configures webpack to grab the contents of the `dev` folder and output the final built file to `server/static`. diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/package-lock.json b/mephisto/abstractions/blueprints/parlai_chat/webapp/package-lock.json new file mode 100644 index 000000000..b60370c1a --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/package-lock.json @@ -0,0 +1,7914 @@ +{ + "name": "parlai-mephisto-task-compiler", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/cli": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } + }, + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/compat-data": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz", + "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==", + "dev": true, + "requires": { + "browserslist": "^4.11.1", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", + "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/types": "^7.9.0" + } + }, + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.5.tgz", + "integrity": "sha512-HAagjAC93tk748jcXpZ7oYRZH485RCq/+yEv9SIWezHRPv9moZArTnkUNciUNzvwHUABmiWKlcxJvMcu59UwTg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-module-imports": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz", + "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.9.6", + "browserslist": "^4.11.1", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.6.tgz", + "integrity": "sha512-6N9IeuyHvMBRyjNYOMJHrhwtu4WJMrYf8hVbEHD3pbbbmNOk1kmXSQs7bA4dYDUaIx4ZEzdnvo6NwC3WHd/Qow==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.9.6", + "@babel/helper-split-export-declaration": "^7.8.3" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==" + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz", + "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==", + "dev": true, + "requires": { + "@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-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.8", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", + "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", + "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", + "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz", + "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz", + "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz", + "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", + "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", + "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", + "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.9.0", + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz", + "integrity": "sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz", + "integrity": "sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz", + "integrity": "sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/preset-env": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz", + "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.9.6", + "@babel/helper-compilation-targets": "^7.9.6", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.6", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@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.8.0", + "@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.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.9.5", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.9.5", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.9.0", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.6", + "@babel/plugin-transform-modules-commonjs": "^7.9.6", + "@babel/plugin-transform-modules-systemjs": "^7.9.6", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.9.5", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.6", + "browserslist": "^4.11.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "requires": { + "@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": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.4.tgz", + "integrity": "sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.9.4", + "@babel/plugin-transform-react-jsx-development": "^7.9.0", + "@babel/plugin-transform-react-jsx-self": "^7.9.0", + "@babel/plugin-transform-react-jsx-source": "^7.9.0" + } + }, + "@babel/runtime": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", + "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + } + } + }, + "@babel/runtime-corejs2": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.9.6.tgz", + "integrity": "sha512-TcdM3xc7weMrwTawuG3BTjtVE3mQLXUPQ9CxTbSKOrhn3QAcqCJ2fz+IIv25wztzUnhNZat7hr655YJa61F3zg==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + } + } + }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + }, + "@types/react": { + "version": "16.9.34", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.34.tgz", + "integrity": "sha512-8AJlYMOfPe1KGLKyHpflCg5z46n0b5DbRfqDksxBLBTUpB75ypDBAO9eCUcjNwE6LCUslwTz00yyG/X9gaVtow==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/react-table": { + "version": "6.8.7", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.7.tgz", + "integrity": "sha512-1U0xl47jk0BzE+HNHgxZYSLvtybSvnlLhOpW9Mfqf9iuRm/fGqgRab3TKivPCY6Tl7WPFM2hWEJ1GnsuSFc9AQ==", + "requires": { + "@types/react": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@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": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "add-dom-event-listener": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/add-dom-event-listener/-/add-dom-event-listener-1.1.0.tgz", + "integrity": "sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw==", + "requires": { + "object-assign": "4.x" + } + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "axe-core": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", + "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", + "dev": true + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "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" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "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-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "bootstrap": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.4.1.tgz", + "integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==" + }, + "bootstrap-chat": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bootstrap-chat/-/bootstrap-chat-1.0.4.tgz", + "integrity": "sha512-TCuc41O1sGMXQ5ETKtEV5TotL9ge8M8iav3TBQgHyODZ/g3sqsLG4qHJ8ArH9tqftO2TxgXc1qfAaLp/9wEX3g==", + "requires": { + "axios": "^0.19.2", + "babel-eslint": "10.x", + "bootstrap": "4.3.1", + "bowser": "^2.9.0", + "jquery": "3.5.0", + "rc-slider": "^9.3.1", + "react-bootstrap": "0.32.4" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "bootstrap": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", + "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" + }, + "rc-align": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.8.tgz", + "integrity": "sha512-2sRUkmB8z4UEXzaS+lDHzXMoR8HrtKH9nn2yHlHVNyUTnaucjMFbdEoCk+hO1g7cpIgW0MphG8i0EH2scSesfw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-slider": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.5.4.tgz", + "integrity": "sha512-24goJnWhmWi0ojNZMoPSMni2wh73IPqEK0TJh7rWn10hPLLKgG8x3KRR0g4uUdCS9APHyosqxGXUIJKGydJXVg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + } + }, + "rc-tooltip": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.0.1.tgz", + "integrity": "sha512-3AnxhUS0j74xAV3khrKw8o6rg+Ima3nw09DJBezMPnX3ImQUAnayWsPSlN1mEnihjA43rcFkGM1emiKE+CXyMQ==", + "requires": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + } + }, + "rc-trigger": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.0.7.tgz", + "integrity": "sha512-4QzwHL0IaXmSZnMfJV45dR3Cy4XgsQy2m0LySBAFiZYaH5EN3qnq2lOtg5aU4T36g4146fHpfGa7mtJpCgkwhg==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.3.4" + } + }, + "rc-util": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.4.0.tgz", + "integrity": "sha512-kXDn1JyLJTAWLBFt+fjkTcUtXhxKkipQCobQmxIEVrX62iXgo24z8YKoWehWfMxPZFPE+RXqrmEu9j5kHz/Lrg==", + "requires": { + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + } + } + }, + "bowser": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz", + "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "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" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "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" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001050", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001050.tgz", + "integrity": "sha512-OvGZqalCwmapci76ISq5q4kuAskb1ebqF3FEQBv1LE1kWht0pojlDDqzFlmk5jgYkuZN7MNZ1n+ULwe/7MaDNQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "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" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-classes": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz", + "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=", + "requires": { + "component-indexof": "0.0.3" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "component-indexof": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz", + "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "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": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "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": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "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": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "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-animation": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/css-animation/-/css-animation-1.6.1.tgz", + "integrity": "sha512-/48+/BaEaHRY6kNQ2OIPzKf9A6g8WjZYjhiNDNuIVbsm5tXCGIAsHDjB4Xu1C4vXJtUWZo26O68OQkDpNBaPog==", + "requires": { + "babel-runtime": "6.x", + "component-classes": "^1.2.5" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + } + }, + "css-selector-tokenizer": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", + "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2", + "regexpu-core": "^4.6.0" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "csstype": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", + "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-align": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.11.1.tgz", + "integrity": "sha512-hN42DmUgtweBx0iBjDLO4WtKOMcK8yBmPx/fgdsgQadLuzPu/8co3oLdK5yMmeM/vnUd3yDyV6qV8/NzxBexQg==" + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "electron-to-chromium": { + "version": "1.3.427", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz", + "integrity": "sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "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": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "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": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "eslint-config-react-app": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz", + "integrity": "sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.9" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.7.0.tgz", + "integrity": "sha512-M+hxhSCk5QBEValO5/UqrS4UunT+MgplIJK5wA1sCtXjzBcZkpTGRwxmLHhGpbHcrmQecgt6ZL/KDdXWqGB7VA==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "eslint-plugin-import": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", + "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", + "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^3.5.4", + "axobject-query": "^2.1.2", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "emoji-regex": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", + "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "eslint-plugin-react": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", + "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz", + "integrity": "sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g==", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "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" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.0.tgz", + "integrity": "sha512-K+LZp6L/6eE5swqIcVXrxl21aGDU4S50gKH0/d96OMQnSBCyGyZl/oZhbkVmdp5sBoINHd4xZvFSARh2dk6DWA==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jquery": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", + "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsx-ast-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "keycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "language-subtag-registry": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", + "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "mephisto-task": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/mephisto-task/-/mephisto-task-1.0.10.tgz", + "integrity": "sha512-xzZOzOya4m2B+xBtyodap3LhWAbkAnNYfbGhZhGubN/UA9UrDtCoWWpyXrfc1+rS/bb1jZARqgvYYrbS8OQSDQ==", + "requires": { + "axios": "^0.19.2", + "bowser": "^2.9.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "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" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", + "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "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": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "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" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-releases": { + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "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-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "dev": true, + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "rc-align": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-2.4.5.tgz", + "integrity": "sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw==", + "requires": { + "babel-runtime": "^6.26.0", + "dom-align": "^1.7.0", + "prop-types": "^15.5.8", + "rc-util": "^4.0.4" + } + }, + "rc-animate": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/rc-animate/-/rc-animate-2.11.1.tgz", + "integrity": "sha512-1NyuCGFJG/0Y+9RKh5y/i/AalUCA51opyyS/jO2seELpgymZm2u9QV3xwODwEuzkmeQ1BDPxMLmYLcTJedPlkQ==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.6", + "css-animation": "^1.3.2", + "prop-types": "15.x", + "raf": "^3.4.0", + "rc-util": "^4.15.3", + "react-lifecycles-compat": "^3.0.4" + } + }, + "rc-motion": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.3.3.tgz", + "integrity": "sha512-eOpPDFz6Y+gX1Nd3/AZOhS+Cqv9CiyJ+hrfAinfemJv+fiiVLv/NkFYe2fqw0onNeGiTKJaDF5Ah4Hm006K5yw==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "rc-util": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.4.0.tgz", + "integrity": "sha512-kXDn1JyLJTAWLBFt+fjkTcUtXhxKkipQCobQmxIEVrX62iXgo24z8YKoWehWfMxPZFPE+RXqrmEu9j5kHz/Lrg==", + "requires": { + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + } + } + }, + "rc-slider": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-8.7.1.tgz", + "integrity": "sha512-WMT5mRFUEcrLWwTxsyS8jYmlaMsTVCZIGENLikHsNv+tE8ThU2lCoPfi/xFNUfJFNFSBFP3MwPez9ZsJmNp13g==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.5", + "prop-types": "^15.5.4", + "rc-tooltip": "^3.7.0", + "rc-util": "^4.0.4", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0", + "warning": "^4.0.3" + } + }, + "rc-tooltip": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-3.7.3.tgz", + "integrity": "sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww==", + "requires": { + "babel-runtime": "6.x", + "prop-types": "^15.5.8", + "rc-trigger": "^2.2.2" + } + }, + "rc-trigger": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-2.6.5.tgz", + "integrity": "sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw==", + "requires": { + "babel-runtime": "6.x", + "classnames": "^2.2.6", + "prop-types": "15.x", + "rc-align": "^2.4.0", + "rc-animate": "2.x", + "rc-util": "^4.4.0", + "react-lifecycles-compat": "^3.0.4" + } + }, + "rc-util": { + "version": "4.20.5", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-4.20.5.tgz", + "integrity": "sha512-f67s4Dt1quBYhrVPq5QMKmK3eS2hN1NNIAyhaiG0HmvqiGYAXMQ7SP2AlGqv750vnzhJs38JklbkWT1/wjhFPg==", + "requires": { + "add-dom-event-listener": "^1.1.0", + "prop-types": "^15.5.10", + "react-is": "^16.12.0", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0" + } + }, + "react": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-bootstrap": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.4.tgz", + "integrity": "sha512-xj+JfaPOvnvr3ow0aHC7Y3HaBKZNR1mm361hVxVzVX3fcdJNIrfiodbQ0m9nLBpNxiKG6FTU2lq/SbTDYT2vew==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0", + "classnames": "^2.2.5", + "dom-helpers": "^3.2.0", + "invariant": "^2.2.4", + "keycode": "^2.2.0", + "prop-types": "^15.6.1", + "prop-types-extra": "^1.0.1", + "react-overlays": "^0.8.0", + "react-prop-types": "^0.4.0", + "react-transition-group": "^2.0.0", + "uncontrollable": "^5.0.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-dom": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-overlays": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", + "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", + "requires": { + "classnames": "^2.2.5", + "dom-helpers": "^3.2.1", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-transition-group": "^2.2.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-prop-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", + "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", + "requires": { + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-table": { + "version": "6.11.5", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz", + "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==", + "requires": { + "@types/react-table": "^6.8.5", + "classnames": "^2.2.5", + "react-is": "^16.8.1" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "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": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rxjs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", + "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "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": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true + }, + "style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uncontrollable": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz", + "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==", + "requires": { + "invariant": "^2.2.4" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "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.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/package.json b/mephisto/abstractions/blueprints/parlai_chat/webapp/package.json new file mode 100644 index 000000000..7474a7b88 --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/package.json @@ -0,0 +1,44 @@ +{ + "name": "parlai-mephisto-task-compiler", + "version": "1.0.0", + "description": "", + "main": "webpack.config.js", + "scripts": { + "dev": "webpack --mode development -q" + }, + "keywords": [], + "author": "", + "dependencies": { + "bootstrap": "^4.3.1", + "bootstrap-chat": "^1.0.1", + "mephisto-task": "^1.0.10", + "rc-slider": "^8.6.3", + "react": "16.13.1", + "react-bootstrap": "^0.32.4", + "react-dom": "16.13.1", + "react-table": "^6.8.6" + }, + "devDependencies": { + "@babel/cli": "^7.1.0", + "@babel/core": "^7.1.0", + "@babel/plugin-proposal-class-properties": "^7.1.0", + "@babel/preset-env": "^7.1.0", + "@babel/preset-react": "^7.0.0", + "@typescript-eslint/eslint-plugin": "^2.34.0", + "@typescript-eslint/parser": "^2.34.0", + "babel-eslint": "^10.1.0", + "babel-loader": "^8.0.2", + "css-loader": "^1.0.0", + "eslint": "^6.8.0", + "eslint-config-react-app": "^5.2.1", + "eslint-plugin-flowtype": "^4.7.0", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^2.5.1", + "style-loader": "^0.23.0", + "url-loader": "^2.0.1", + "webpack": "^4.19.1", + "webpack-cli": "^3.1.1" + } +} diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/src/main.js b/mephisto/abstractions/blueprints/parlai_chat/webapp/src/main.js new file mode 100644 index 000000000..1b8bce93d --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/src/main.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +import React from "react"; +import ReactDOM from "react-dom"; +import "bootstrap-chat/styles.css"; + +import { ChatApp, ChatMessage, DefaultTaskDescription } from "bootstrap-chat"; + +function RenderChatMessage({ message, mephistoContext, appContext, idx }) { + const { agentId } = mephistoContext; + const { currentAgentNames } = appContext.taskContext; + + return ( + + ); +} + +function MainApp() { + return ( + ( + + )} + renderSidePane={({ mephistoContext: { taskConfig } }) => ( + + )} + /> + ); +} + +ReactDOM.render(, document.getElementById("app")); diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/index.html b/mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/index.html new file mode 100644 index 000000000..5a1a77bfb --- /dev/null +++ b/mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/index.html @@ -0,0 +1,32 @@ + + + + + + + + MTurk Chat + + + + + + + +
+ + + diff --git a/mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/notif.mp3 b/mephisto/abstractions/blueprints/parlai_chat/webapp/src/static/notif.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..baf6a4a4adaf1cd8466d0e1f1742eeed16b27b3e GIT binary patch literal 46393 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 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" + integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI= + dependencies: + postcss "^6.0.1" + +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@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0: + 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-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= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +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.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.4, ini@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + 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.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +internal-slot@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" + integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== + dependencies: + es-abstract "^1.17.0-next.1" + has "^1.0.3" + side-channel "^1.0.2" + +interpret@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +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" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +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-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-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.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-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +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-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-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@^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-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-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-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.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +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-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +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-windows@^1.0.1, 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-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= + +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= + +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= + +jquery@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== + +"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.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +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.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-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +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" + +jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" + integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== + dependencies: + array-includes "^3.0.3" + object.assign "^4.1.0" + +keycode@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" + integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ= + +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== + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +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" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +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.0.2, 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" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +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" + +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + +loose-envify@^1.0.0, loose-envify@^1.1.0, 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" + +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, make-dir@^2.1.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" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.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" + +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" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, 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" + +mephisto-task@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/mephisto-task/-/mephisto-task-1.0.10.tgz#10ab1cf9a9db9c2155bcc014bb443a63e1d6f6bc" + integrity sha512-xzZOzOya4m2B+xBtyodap3LhWAbkAnNYfbGhZhGubN/UA9UrDtCoWWpyXrfc1+rS/bb1jZARqgvYYrbS8OQSDQ== + dependencies: + axios "^0.19.2" + bowser "^2.9.0" + +micromatch@^3.0.4, 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" + +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@^2.4.4: + version "2.4.5" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.5.tgz#d8de2ecb92982dedbb6541c9b6841d7f218ea009" + integrity sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w== + +mimic-fn@^2.0.0, 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== + +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: + 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.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +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" + +mkdirp@^0.5.1, mkdirp@^0.5.3: + 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.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +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: + 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" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +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== + +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.53: + version "1.1.56" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.56.tgz#bc054a417d316e3adac90eafb7e1932802f28705" + integrity sha512-EVo605FhWLygH8a64TjgpjyHYOihkxECwX1bHHr8tETJKWEiWS2YJjPbvsX2jFjnjTNEgBCmk9mLjKG1Mf11cw== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.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== + +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" + +object-assign@4.x, 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.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, 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.entries@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" + integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +object.fromentries@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" + integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +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, object.values@^1.1.1: + 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" + +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" + +optionator@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.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-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +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-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +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-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.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@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.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-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +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: + 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" + +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-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +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-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-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-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-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + 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= + +picomatch@^2.0.4, 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@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.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-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +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-modules-extract-imports@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" + integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw== + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-value-parser@^3.3.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@^6.0.1, postcss@^6.0.23: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +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= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +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-extra@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== + dependencies: + react-is "^16.3.2" + warning "^4.0.0" + +prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.1, 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" + +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= + +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: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +querystring-es3@^0.2.0: + 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= + +raf@^3.4.0, raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + 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" + +rc-align@^2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-2.4.5.tgz#c941a586f59d1017f23a428f0b468663fb7102ab" + integrity sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw== + dependencies: + babel-runtime "^6.26.0" + dom-align "^1.7.0" + prop-types "^15.5.8" + rc-util "^4.0.4" + +rc-align@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.1.tgz#0566de141a82d9a1923b7672c70bdb19dcde6e23" + integrity sha512-RQ5Fhxl0LW+zsxbY8dxAcpXdaHkHH2jzRSSpvBTS7G9LMK3T+WRcn4ovjg/eqAESM6TdTx0hfqWF2S1pO75jxQ== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + dom-align "^1.7.0" + rc-util "^5.0.1" + resize-observer-polyfill "^1.5.1" + +rc-animate@2.x: + version "2.11.1" + resolved "https://registry.yarnpkg.com/rc-animate/-/rc-animate-2.11.1.tgz#2666eeb6f1f2a495a13b2af09e236712278fdb2c" + integrity sha512-1NyuCGFJG/0Y+9RKh5y/i/AalUCA51opyyS/jO2seELpgymZm2u9QV3xwODwEuzkmeQ1BDPxMLmYLcTJedPlkQ== + dependencies: + babel-runtime "6.x" + classnames "^2.2.6" + css-animation "^1.3.2" + prop-types "15.x" + raf "^3.4.0" + rc-util "^4.15.3" + react-lifecycles-compat "^3.0.4" + +rc-animate@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/rc-animate/-/rc-animate-3.1.0.tgz#051b689c2c7194e4c8ae016d32a0e5f9de6c8baa" + integrity sha512-8FsM+3B1H+0AyTyGggY6JyVldHTs1CyYT8CfTmG/nGHHXlecvSLeICJhcKgRLjUiQlctNnRtB1rwz79cvBVmrw== + dependencies: + "@ant-design/css-animation" "^1.7.2" + classnames "^2.2.6" + raf "^3.4.0" + rc-util "^5.0.1" + +rc-slider@^8.6.3: + version "8.7.1" + resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-8.7.1.tgz#9ed07362dc93489a38e654b21b8122ad70fd3c42" + integrity sha512-WMT5mRFUEcrLWwTxsyS8jYmlaMsTVCZIGENLikHsNv+tE8ThU2lCoPfi/xFNUfJFNFSBFP3MwPez9ZsJmNp13g== + dependencies: + babel-runtime "6.x" + classnames "^2.2.5" + prop-types "^15.5.4" + rc-tooltip "^3.7.0" + rc-util "^4.0.4" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.1.0" + warning "^4.0.3" + +rc-slider@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-9.3.1.tgz#444012f3b4847d592b167a9cee6a1a46779a6ef4" + integrity sha512-c52PWPyrfJWh28K6dixAm0906L3/4MUIxqrNQA4TLnC/Z+cBNycWJUZoJerpwSOE1HdM3XDwixCsmtFc/7aWlQ== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.5" + rc-tooltip "^4.0.0" + rc-util "^5.0.0" + shallowequal "^1.1.0" + +rc-tooltip@^3.7.0: + version "3.7.3" + resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-3.7.3.tgz#280aec6afcaa44e8dff0480fbaff9e87fc00aecc" + integrity sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww== + dependencies: + babel-runtime "6.x" + prop-types "^15.5.8" + rc-trigger "^2.2.2" + +rc-tooltip@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-4.2.1.tgz#c1a2d5017ee03a771a9301c0dfdb46dfdf8fef94" + integrity sha512-oykuaGsHg7RFvPUaxUpxo7ScEqtH61C66x4JUmjlFlSS8gSx2L8JFtfwM1D68SLBxUqGqJObtxj4TED75gQTiA== + dependencies: + rc-trigger "^4.2.1" + +rc-trigger@^2.2.2: + version "2.6.5" + resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-2.6.5.tgz#140a857cf28bd0fa01b9aecb1e26a50a700e9885" + integrity sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw== + dependencies: + babel-runtime "6.x" + classnames "^2.2.6" + prop-types "15.x" + rc-align "^2.4.0" + rc-animate "2.x" + rc-util "^4.4.0" + react-lifecycles-compat "^3.0.4" + +rc-trigger@^4.2.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-4.3.0.tgz#94ea1851d123359716d1dc3030083c015a92ecfb" + integrity sha512-jnGNzosXmDdivMBjPCYe/AfOXTpJU2/xQ9XukgoXDQEoZq/9lcI1r7eUIfq70WlWpLxlUEqQktiV3hwyy6Nw9g== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.6" + raf "^3.4.1" + rc-align "^4.0.0" + rc-animate "^3.0.0" + rc-util "^5.0.1" + +rc-util@^4.0.4, rc-util@^4.15.3, rc-util@^4.4.0: + version "4.20.5" + resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-4.20.5.tgz#f7c77569e971ae6a8ad56f899cadd22275398325" + integrity sha512-f67s4Dt1quBYhrVPq5QMKmK3eS2hN1NNIAyhaiG0HmvqiGYAXMQ7SP2AlGqv750vnzhJs38JklbkWT1/wjhFPg== + dependencies: + add-dom-event-listener "^1.1.0" + prop-types "^15.5.10" + react-is "^16.12.0" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.1.0" + +rc-util@^5.0.0, rc-util@^5.0.1: + version "5.0.4" + resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.0.4.tgz#297bd719b1bd00b3c947a884ab7ef0a07c55dce6" + integrity sha512-cd19RCrE0DJH6UcJ9+V3eaXA/5sNWyVKOKkWl8ZM2OqgNzVb8fv0obf/TkuvSN43tmTsgqY8k7OqpFYHhmef8g== + dependencies: + react-is "^16.12.0" + shallowequal "^1.1.0" + +react-bootstrap@0.32.4, react-bootstrap@^0.32.4: + version "0.32.4" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-0.32.4.tgz#8efc4cbfc4807215d75b7639bee0d324c8d740d1" + integrity sha512-xj+JfaPOvnvr3ow0aHC7Y3HaBKZNR1mm361hVxVzVX3fcdJNIrfiodbQ0m9nLBpNxiKG6FTU2lq/SbTDYT2vew== + dependencies: + "@babel/runtime-corejs2" "^7.0.0" + classnames "^2.2.5" + dom-helpers "^3.2.0" + invariant "^2.2.4" + keycode "^2.2.0" + prop-types "^15.6.1" + prop-types-extra "^1.0.1" + react-overlays "^0.8.0" + react-prop-types "^0.4.0" + react-transition-group "^2.0.0" + uncontrollable "^5.0.0" + warning "^3.0.0" + +react-dom@16.13.1: + 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-is@^16.12.0, react-is@^16.3.2, 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-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-overlays@^0.8.0: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5" + integrity sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA== + dependencies: + classnames "^2.2.5" + dom-helpers "^3.2.1" + prop-types "^15.5.10" + prop-types-extra "^1.0.1" + react-transition-group "^2.2.0" + warning "^3.0.0" + +react-prop-types@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/react-prop-types/-/react-prop-types-0.4.0.tgz#f99b0bfb4006929c9af2051e7c1414a5c75b93d0" + integrity sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A= + dependencies: + warning "^3.0.0" + +react-table@^6.8.6: + version "6.11.5" + resolved "https://registry.yarnpkg.com/react-table/-/react-table-6.11.5.tgz#84e52885db426a07a6c4ce2c7e942f2cd4e2aa58" + integrity sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g== + dependencies: + "@types/react-table" "^6.8.5" + classnames "^2.2.5" + react-is "^16.8.1" + +react-transition-group@^2.0.0, react-transition-group@^2.2.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react@16.13.1: + 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" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, 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.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" + +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.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +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.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + +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.3.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" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpp@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +regexpu-core@^4.6.0, 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.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +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" + +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= + +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.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +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-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== + +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +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-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.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-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.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2: + 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== + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.3: + 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" + +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.4.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-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" + +rxjs@^6.5.3: + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== + dependencies: + tslib "^1.9.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-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-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": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +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.5.0, schema-utils@^2.6.5: + version "2.6.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" + integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, 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@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + +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== + +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= + +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" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +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-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= + +side-channel@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" + integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== + dependencies: + es-abstract "^1.17.0-next.1" + object-inspect "^1.7.0" + +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== + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +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" + +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.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +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= + +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" + +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" + +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== + +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.matchall@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" + integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + has-symbols "^1.0.1" + internal-slot "^1.0.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.2" + +string.prototype.trimend@^1.0.0: + 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.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + 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" + +strip-ansi@^3.0.0: + 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@^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-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-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +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-json-comments@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" + integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== + +style-loader@^0.23.0: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.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@^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, supports-color@^5.4.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@^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" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.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== + +terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.7.0.tgz#15852cf1a08e3256a80428e865a2fa893ffba006" + integrity sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +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: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +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" + +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-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" + +tslib@^1.8.1, 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== + +tsutils@^3.17.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + +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= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +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-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uncontrollable@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-5.1.0.tgz#7e9a1c50ea24e3c78b625e52d21ff3f758c7bd59" + integrity sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw== + dependencies: + invariant "^2.2.4" + +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== + +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" + +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" + +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-loader@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" + integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== + dependencies: + loader-utils "^1.2.3" + mime "^2.4.4" + schema-utils "^2.5.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== + +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@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" + +v8-compile-cache@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.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== + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + +warning@^4.0.0, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.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" + +webpack-cli@^3.1.1: + version "3.3.11" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" + integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== + dependencies: + chalk "2.4.2" + cross-spawn "6.0.5" + enhanced-resolve "4.1.0" + findup-sync "3.0.0" + global-modules "2.0.0" + import-local "2.0.0" + interpret "1.2.0" + loader-utils "1.2.3" + supports-color "6.1.0" + v8-compile-cache "2.0.3" + yargs "13.2.4" + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + 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.19.1: + 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" + +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@^1.2.14, 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" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +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" + +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" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +xregexp@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50" + integrity sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g== + dependencies: + "@babel/runtime-corejs3" "^7.8.3" + +xtend@^4.0.0, 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.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^13.1.0: + 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.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + 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.0" diff --git a/mephisto/abstractions/blueprints/static_html_task/__init__.py b/mephisto/abstractions/blueprints/static_html_task/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_html_task/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/blueprints/static_html_task/source/.babelrc b/mephisto/abstractions/blueprints/static_html_task/source/.babelrc new file mode 100644 index 000000000..5507f2e86 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_html_task/source/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@babel/env", "@babel/preset-react"], + "plugins": ["@babel/plugin-proposal-class-properties"] +} diff --git a/mephisto/abstractions/blueprints/static_html_task/source/dev/app.jsx b/mephisto/abstractions/blueprints/static_html_task/source/dev/app.jsx new file mode 100644 index 000000000..80e3f8448 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_html_task/source/dev/app.jsx @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +import React from "react"; +import ReactDOM from "react-dom"; +import { Button } from "react-bootstrap"; +import { useMephistoTask, postData } from "mephisto-task"; +const axios = require("axios"); + +/* global + getWorkerName, getAssignmentId, getWorkerRegistrationInfo, + getAgentRegistration, handleSubmitToProvider +*/ + +/* ================= Utility functions ================= */ + +function requestTaskHMTL(targetHtml) { + var url = new URL(window.location.origin + "/" + targetHtml); + return axios.get(url).then((res) => res.data); +} + +/* ================= Application Components ================= */ + +function MainApp() { + const { + blockedReason, + blockedExplanation, + isPreview, + isLoading, + initialTaskData, + handleSubmit, + isOnboarding, + agentId, + } = useMephistoTask(); + + function submitFromFrame(formData, objData) { + if (isOnboarding) { + handleSubmit(objData); + } else { + formData.append("USED_AGENT_ID", agentId); + formData.append("final_data", JSON.stringify(objData)); + postData("/submit_task", formData) + .then((data) => { + handleSubmitToProvider(objData); + return data; + }) + .then(function (data) { + console.log("Submitted"); + console.log(formData); + console.table(objData); + }); + } + } + + if (blockedReason !== null) { + return

{blockedExplanation}

; + } + if (isPreview) { + return ; + } + if (isLoading) { + return
Loading..
; + } + if (isOnboarding) { + return ( + + + + ); + } + if (initialTaskData === null) { + return
Loading...
; + } + return ( + + + + ); +} + +function SubmitFrame({ children, onSubmit }) { + const [submitting, setSubmitting] = React.useState(false); + + function handleFormSubmit(event) { + event.preventDefault(); + setSubmitting(true); + const formData = new FormData(event.target); + let objData = {}; + formData.forEach((value, key) => { + objData[key] = value; + }); + onSubmit(formData, objData); + } + + return ( +
+
+ {children} +
+
+ +
+
+
+
+ ); +} + +function ShowURL({ url, data = null }) { + const [retrievedHtml, setRetrievedHtml] = React.useState( + "
Loading..
" + ); + + React.useEffect(() => { + requestTaskHMTL(url).then((data) => setRetrievedHtml(data)); + }, []); + + return ; +} + +function HtmlRenderer({ html, data }) { + const elRef = React.useRef(); + + function handleUpdatingRemainingScripts(curr_counter, scripts_left) { + if (scripts_left.length == 0) { + return; + } + let script_to_load = scripts_left.shift(); + if (script_to_load.text == "") { + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement("script"); + script.onload = () => { + handleUpdatingRemainingScripts(curr_counter + 1, scripts_left); + }; + script.async = 1; + script.src = script_to_load.src; + head.appendChild(script); + } else { + const script_text = script_to_load.text; + // This magic lets us evaluate a script from the global context + (1, eval)(script_text); + handleUpdatingRemainingScripts(curr_counter + 1, scripts_left); + } + } + + function interpolateHtml(html, dataObj = null) { + let base_html = html; + let fin_html = base_html; + + if (dataObj !== null) { + for (let [key, value] of Object.entries(dataObj)) { + let find_string = "${" + key + "}"; + // Could be better done with a regex for performant code + fin_html = fin_html.split(find_string).join(value); + } + } + + return fin_html; + } + + React.useEffect(() => { + let children = elRef.current.children; + let scripts_to_load = []; + for (let child of children) { + if (child.tagName == "SCRIPT") { + scripts_to_load.push(child); + } + } + if (scripts_to_load.length > 0) { + handleUpdatingRemainingScripts(0, scripts_to_load); + } + }, [elRef.current]); + + return ( +
+ ); +} + +ReactDOM.render(, document.getElementById("app")); diff --git a/mephisto/abstractions/blueprints/static_html_task/source/dev/main.js b/mephisto/abstractions/blueprints/static_html_task/source/dev/main.js new file mode 100644 index 000000000..8afaf4641 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_html_task/source/dev/main.js @@ -0,0 +1,6 @@ +/* + * 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 "./app.jsx"; diff --git a/mephisto/abstractions/blueprints/static_react_task/__init__.py b/mephisto/abstractions/blueprints/static_react_task/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_react_task/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/blueprints/static_react_task/static_react_blueprint.py b/mephisto/abstractions/blueprints/static_react_task/static_react_blueprint.py new file mode 100644 index 000000000..cd139d327 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_react_task/static_react_blueprint.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.assignment import InitializationData +from dataclasses import dataclass, field +from omegaconf import MISSING +from mephisto.abstractions.blueprints.abstract.static_task.static_blueprint import ( + StaticBlueprint, + StaticBlueprintArgs, +) +from mephisto.abstractions.blueprints.static_react_task.static_react_task_builder import ( + StaticReactTaskBuilder, +) +from mephisto.operations.registry import register_mephisto_abstraction + +import os +import time +import csv + +from typing import ClassVar, List, Type, Any, Dict, Iterable, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.blueprint import AgentState, TaskRunner, TaskBuilder + from mephisto.data_model.assignment import Assignment + from argparse import _ArgumentGroup as ArgumentGroup + +BLUEPRINT_TYPE = "static_react_task" + + +@dataclass +class StaticReactBlueprintArgs(StaticBlueprintArgs): + """ + StaticReactBlueprint: Tasks launched from static blueprints need + a prebuilt javascript bundle containing the task. We suggest building + with our provided useMephistoTask hook. + """ + + _blueprint_type: str = BLUEPRINT_TYPE + _group: str = field( + default="StaticReactBlueprint", + metadata={ + "help": """ + Tasks launched from static blueprints need + a prebuilt javascript bundle containing the task. We suggest building + with our provided useMephistoTask hook. + """ + }, + ) + task_source: str = field( + default=MISSING, + metadata={ + "help": "Path to file containing javascript bundle for the task", + "required": True, + }, + ) + + +@register_mephisto_abstraction() +class StaticReactBlueprint(StaticBlueprint): + """Blueprint for a task that runs off of a built react javascript bundle""" + + TaskBuilderClass: ClassVar[Type["TaskBuilder"]] = StaticReactTaskBuilder + ArgsClass = StaticReactBlueprintArgs + BLUEPRINT_TYPE = BLUEPRINT_TYPE + + def __init__( + self, task_run: "TaskRun", args: "DictConfig", shared_state: "SharedTaskState" + ): + super().__init__(task_run, args, shared_state) + self.js_bundle = os.path.expanduser(args.blueprint.task_source) + if not os.path.exists(self.js_bundle): + raise FileNotFoundError( + f"Specified bundle file {self.js_bundle} was not found from {os.getcwd()}" + ) + + @classmethod + def assert_task_args( + cls, args: "DictConfig", shared_state: "SharedTaskState" + ) -> None: + """Ensure that static requirements are fulfilled, and source file exists""" + super().assert_task_args(args, shared_state) + + found_task_source = args.blueprint.task_source + assert ( + found_task_source is not None + ), "Must provide a path to a javascript bundle in `task_source`" + found_task_path = os.path.expanduser(found_task_source) + assert os.path.exists( + found_task_path + ), f"Provided task source {found_task_path} does not exist." diff --git a/mephisto/abstractions/blueprints/static_react_task/static_react_task_builder.py b/mephisto/abstractions/blueprints/static_react_task/static_react_task_builder.py new file mode 100644 index 000000000..16080d2f4 --- /dev/null +++ b/mephisto/abstractions/blueprints/static_react_task/static_react_task_builder.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.blueprint import TaskBuilder + +from distutils.dir_util import copy_tree +import os +import shutil + + +class StaticReactTaskBuilder(TaskBuilder): + """ + Builder for a static task, puts required files into + the server directory for deployment. + """ + + BUILT_FILE = "done.built" + BUILT_MESSAGE = "built!" + + def build_in_dir(self, build_dir: str): + """Build the frontend if it doesn't exist, then copy into the server directory""" + target_resource_dir = os.path.join(build_dir, "static") + + # If any additional task files are required via a source_dir, copy those as well + extra_dir_path = self.args.blueprint.get("extra_source_dir", None) + if extra_dir_path is not None: + extra_dir_path = os.path.expanduser(extra_dir_path) + copy_tree(extra_dir_path, target_resource_dir) + + # Copy the built core and the given task file to the target path + use_bundle = os.path.expanduser(self.args.blueprint.task_source) + target_path = os.path.join(target_resource_dir, "bundle.js") + shutil.copy2(use_bundle, target_path) + + # Write a built file confirmation + with open(os.path.join(build_dir, self.BUILT_FILE), "w+") as built_file: + built_file.write(self.BUILT_MESSAGE) diff --git a/mephisto/abstractions/channel.py b/mephisto/abstractions/channel.py new file mode 100644 index 000000000..e9bd52bc1 --- /dev/null +++ b/mephisto/abstractions/channel.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +# 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. + +from abc import ABC, abstractmethod + +from typing import Callable +from mephisto.data_model.packet import Packet + +STATUS_CHECK_TIME = 4 + + +class Channel(ABC): + """ + Manages the API between the Supervisor and the server that is produced + by the architect. + + Should be able to be configured by an architect, and used to communicate + with that server based on the queries that a Supervisor needs to run a job + """ + + def __init__( + self, + channel_id: str, + on_channel_open: Callable[[str], None], + on_catastrophic_disconnect: Callable[[str], None], + on_message: Callable[[str, Packet], None], + ): + """ + Create a channel by the given id, and initialize any resources that + will later be required during the `open` call. + + Children classes will likely need to accept additional parameters + + on_channel_open should be called when the channel is first alive. + It takes the channel id as the only argument. + on_catastrophic_disconnect should only be called if the channel + is entirely unable to connect to the server and any ongoing + jobs should be killed. + It takes the channel id as the only argument. + on_message should be called whenever this channel receives a message + from the server. + It takes the channel id as the first argument and the received + packet as the second argument. + """ + self.channel_id = channel_id + self.on_channel_open = on_channel_open + self.on_catastrophic_disconnect = on_catastrophic_disconnect + self.on_message = on_message + + @abstractmethod + def is_closed(self): + """ + Return whether or not this connection has been explicitly closed + by the supervisor or another source. + """ + + @abstractmethod + def close(self): + """ + Close this channel, and ensure that all threads and surrounding + resources are cleaned up + """ + + @abstractmethod + def is_alive(self): + """ + Return if this channel is actively able to send/recieve messages. + Should be False until a connection has been established with the + server. + """ + + @abstractmethod + def open(self): + """ + Do whatever is necessary to 'connect' this socket to the server + """ + + @abstractmethod + def send(self, packet: "Packet") -> bool: + """ + Send the packet given to the intended recipient. + Return True on success and False on failure. + """ diff --git a/mephisto/abstractions/crowd_provider.py b/mephisto/abstractions/crowd_provider.py new file mode 100644 index 000000000..30d920846 --- /dev/null +++ b/mephisto/abstractions/crowd_provider.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 + +# 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. + +from abc import ABC, abstractmethod, abstractproperty +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from mephisto.abstractions.blueprint import AgentState, SharedTaskState +from mephisto.data_model.assignment import Unit +from mephisto.data_model.requester import Requester +from mephisto.data_model.worker import Worker +from mephisto.data_model.agent import Agent + +from typing import List, Optional, Tuple, Dict, Any, ClassVar, Type, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.task_run import TaskRun + from argparse import _ArgumentGroup as ArgumentGroup + + +@dataclass +class ProviderArgs: + """Base class for arguments to configure Crowd Providers""" + + _provider_type: str = MISSING + requester_name: str = MISSING + + +class CrowdProvider(ABC): + """ + Base class that defines the required functionality for + the mephisto system to be able to interface with an + external crowdsourcing vendor. + + Implementing the methods within, as well as supplying + wrapped Unit, Requester, Worker, and Agent classes + should ensure support for a vendor. + """ + + PROVIDER_TYPE = "__PROVIDER_BASE_CLASS__" + + UnitClass: ClassVar[Type[Unit]] = Unit + + RequesterClass: ClassVar[Type[Requester]] = Requester + + WorkerClass: ClassVar[Type[Worker]] = Worker + + AgentClass: ClassVar[Type[Agent]] = Agent + + ArgsClass: ClassVar[Type[ProviderArgs]] = ProviderArgs + + SUPPORTED_TASK_TYPES: ClassVar[List[str]] + + def __init__(self, db: "MephistoDB"): + """ + Crowd provider classes should keep as much of their state + as possible in their non-python datastore. This way + the system can work even after shutdowns, and the + state of the system can be managed or observed from + other processes. + + In order to set up a datastore, init should check to see + if one is already set (using get_datastore_for_provider) + and use that one if available, otherwise make a new one + and register it with the database. + """ + self.db = db + if db.has_datastore_for_provider(self.PROVIDER_TYPE): + self.datastore = db.get_datastore_for_provider(self.PROVIDER_TYPE) + else: + self.datastore_root = db.get_db_path_for_provider(self.PROVIDER_TYPE) + self.datastore = self.initialize_provider_datastore(self.datastore_root) + db.set_datastore_for_provider(self.PROVIDER_TYPE, self.datastore) + + @classmethod + def assert_task_args(cls, args: DictConfig, shared_state: "SharedTaskState"): + """ + Assert that the provided arguments are valid. Should + fail if a task launched with these arguments would + not work + """ + return + + @classmethod + @abstractmethod + def get_wrapper_js_path(cls): + """ + Return the path to the `wrap_crowd_source.js` file for this + provider to be deployed to the server + """ + raise NotImplementedError + + @abstractmethod + def initialize_provider_datastore(self, storage_path: str) -> Any: + """ + Do whatever is required to initialize this provider insofar + as setting up local or external state is required to ensure + that this vendor is usable. + + Local data storage should be put into the given root path. + + This method should return the local data storage component that + is required to do any object initialization, as it will be available + from the MephistoDB in a db.get_provider_datastore(PROVIDER_TYPE). + """ + raise NotImplementedError() + + @abstractmethod + def setup_resources_for_task_run( + self, + task_run: "TaskRun", + args: DictConfig, + shared_state: "SharedTaskState", + server_url: str, + ) -> None: + """ + Setup any required resources for managing any additional resources + surrounding a specific task run. + """ + raise NotImplementedError() + + @abstractmethod + def cleanup_resources_from_task_run( + self, task_run: "TaskRun", server_url: str + ) -> None: + """ + Destroy any resources set up specifically for this task run + """ + raise NotImplementedError() + + def cleanup_qualification(self, qualification_name: str) -> None: + """ + Remove the linked qualification from the crowdprovider if it exists + """ + return None diff --git a/mephisto/abstractions/database.py b/mephisto/abstractions/database.py new file mode 100644 index 000000000..3433f10b7 --- /dev/null +++ b/mephisto/abstractions/database.py @@ -0,0 +1,582 @@ +#!/usr/bin/env python3 + +# 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 os +import sqlite3 + +from abc import ABC, abstractmethod +from mephisto.operations.utils import get_data_dir +from mephisto.operations.registry import ( + get_crowd_provider_from_type, + get_valid_provider_types, +) +from typing import Mapping, Optional, Any, List +from mephisto.data_model.agent import Agent, OnboardingAgent +from mephisto.data_model.assignment import Assignment, Unit +from mephisto.data_model.project import Project +from mephisto.data_model.requester import Requester +from mephisto.data_model.task import Task +from mephisto.data_model.task_run import TaskRun +from mephisto.data_model.worker import Worker +from mephisto.data_model.qualification import Qualification, GrantedQualification + +# TODO(#101) investigate rate limiting against the db by caching locally where appropriate across the data model? +# TODO(#101) investigate cursors for DB queries as the project scales + + +class MephistoDBException(Exception): + pass + + +class EntryAlreadyExistsException(MephistoDBException): + pass + + +class EntryDoesNotExistException(MephistoDBException): + pass + + +class MephistoDB(ABC): + """ + Provides the interface for all queries that are necessary for the Mephisto + architecture to run as expected. All other databases should implement + these methods to be used as the database that backs Mephisto. + + By default, we use a LocalMesphistoDB located at `mephisto/data/database.db` + """ + + def __init__(self, database_path=None): + """Ensure the database is set up and ready to handle data""" + if database_path is None: + database_path = os.path.join(get_data_dir(), "database.db") + self.db_path = database_path + self.db_root = os.path.dirname(self.db_path) + self.init_tables() + self.__provider_datastores: Dict[str, Any] = {} + + def get_db_path_for_provider(self, provider_type) -> str: + """Get the path to store data for a specific provider in""" + database_root = os.path.dirname(self.db_path) + provider_root = os.path.join(database_root, provider_type) + os.makedirs(provider_root, exist_ok=True) + return provider_root + + def has_datastore_for_provider(self, provider_type: str) -> bool: + """Determine if a datastore has been registered for the given provider""" + return provider_type in self.__provider_datastores + + def get_datastore_for_provider(self, provider_type: str) -> Any: + """Get the provider datastore registered with this db""" + if provider_type not in self.__provider_datastores: + # Register this provider for usage now + ProviderClass = get_crowd_provider_from_type(provider_type) + provider = ProviderClass(self) + return self.__provider_datastores.get(provider_type) + + def set_datastore_for_provider(self, provider_type: str, datastore: Any) -> None: + """Set the provider datastore registered with this db""" + self.__provider_datastores[provider_type] = datastore + + def delete_qualification(self, qualification_name: str) -> None: + """ + Remove this qualification from all workers that have it, then delete the qualification + """ + self._delete_qualification(qualification_name) + for crowd_provider_name in get_valid_provider_types(): + ProviderClass = get_crowd_provider_from_type(crowd_provider_name) + provider = ProviderClass(self) + provider.cleanup_qualification(qualification_name) + + @abstractmethod + def shutdown(self) -> None: + """Do whatever is required to shut this server off""" + raise NotImplementedError() + + @abstractmethod + def init_tables(self) -> None: + """ + Initialize any tables that may be required to run this database. If this is an expensive + operation, check to see if they already exist before trying to initialize + """ + raise NotImplementedError() + + @abstractmethod + def new_project(self, project_name: str) -> str: + """ + Create a new project with the given project name. Raise EntryAlreadyExistsException if a project + with this name has already been created. + + Project names are permanent, as changing directories later is painful. + """ + raise NotImplementedError() + + @abstractmethod + def get_project(self, project_id: str) -> Mapping[str, Any]: + """ + Return project's fields by the given project_id, raise EntryDoesNotExistException if no id exists + in projects + + See Project for the expected returned mapping's fields + """ + raise NotImplementedError() + + @abstractmethod + def find_projects(self, project_name: Optional[str] = None) -> List[Project]: + """ + Try to find any project that matches the above. When called with no arguments, + return all projects. + """ + raise NotImplementedError() + + @abstractmethod + def new_task( + self, + task_name: str, + task_type: str, + project_id: Optional[str] = None, + parent_task_id: Optional[str] = None, + ) -> str: + """ + Create a new task with the given task name. Raise EntryAlreadyExistsException if a task + with this name has already been created. + """ + raise NotImplementedError() + + @abstractmethod + def get_task(self, task_id: str) -> Mapping[str, Any]: + """ + Return task's fields by task_id, raise EntryDoesNotExistException if no id exists + in tasks + + See Task for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_tasks( + self, + task_name: Optional[str] = None, + project_id: Optional[str] = None, + parent_task_id: Optional[str] = None, + ) -> List[Task]: + """ + Try to find any task that matches the above. When called with no arguments, + return all tasks. + """ + raise NotImplementedError() + + @abstractmethod + def update_task( + self, + task_id: str, + task_name: Optional[str] = None, + project_id: Optional[str] = None, + ) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + + Should only be runable if no runs have been created for this task + """ + raise NotImplementedError() + + @abstractmethod + def new_task_run( + self, + task_id: str, + requester_id: str, + init_params: str, + provider_type: str, + task_type: str, + sandbox: bool = True, + ) -> str: + """ + Create a new task_run for the given task. + + Once a run is created, it should no longer be altered. The assignments and + subassignments depend on the data set up within, as the launched task + cannot be replaced and the requester can not be swapped mid-run. + """ + raise NotImplementedError() + + @abstractmethod + def get_task_run(self, task_run_id: str) -> Mapping[str, Any]: + """ + Return the given task_run's fields by task_run_id, raise EntryDoesNotExistException if no id exists + in task_runs. + + See TaskRun for the expected fields to populate in the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_task_runs( + self, + task_id: Optional[str] = None, + requester_id: Optional[str] = None, + is_completed: Optional[bool] = None, + ) -> List[TaskRun]: + """ + Try to find any task_run that matches the above. When called with no arguments, + return all task_runs. + """ + raise NotImplementedError() + + @abstractmethod + def update_task_run(self, task_run_id: str, is_completed: bool): + """ + Update a task run. At the moment, can only update completion status + """ + raise NotImplementedError() + + @abstractmethod + def new_assignment( + self, + task_id: str, + task_run_id: str, + requester_id: str, + task_type: str, + provider_type: str, + sandbox: bool = True, + ) -> str: + """ + Create a new assignment for the given task + + Assignments should not be edited or altered once created + """ + raise NotImplementedError() + + @abstractmethod + def get_assignment(self, assignment_id: str) -> Mapping[str, Any]: + """ + Return assignment's fields by assignment_id, raise EntryDoesNotExistException if + no id exists in tasks + + See Assignment for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_assignments( + self, + task_run_id: Optional[str] = None, + task_id: Optional[str] = None, + requester_id: Optional[str] = None, + task_type: Optional[str] = None, + provider_type: Optional[str] = None, + sandbox: Optional[bool] = None, + ) -> List[Assignment]: + """ + Try to find any task that matches the above. When called with no arguments, + return all tasks. + """ + raise NotImplementedError() + + @abstractmethod + def new_unit( + self, + task_id: str, + task_run_id: str, + requester_id: str, + assignment_id: str, + unit_index: int, + pay_amount: float, + provider_type: str, + task_type: str, + sandbox: bool = True, + ) -> str: + """ + Create a new unit with the given index. Raises EntryAlreadyExistsException + if there is already a unit for the given assignment with the given index. + """ + raise NotImplementedError() + + @abstractmethod + def get_unit(self, unit_id: str) -> Mapping[str, Any]: + """ + Return unit's fields by unit_id, raise EntryDoesNotExistException + if no id exists in units + + See unit for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_units( + self, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + requester_id: Optional[str] = None, + assignment_id: Optional[str] = None, + unit_index: Optional[int] = None, + provider_type: Optional[str] = None, + task_type: Optional[str] = None, + agent_id: Optional[str] = None, + worker_id: Optional[str] = None, + sandbox: Optional[bool] = None, + status: Optional[str] = None, + ) -> List[Unit]: + """ + Try to find any unit that matches the above. When called with no arguments, + return all units. + """ + raise NotImplementedError() + + @abstractmethod + def clear_unit_agent_assignment(self, unit_id: str) -> None: + """ + Update the given unit by removing the agent that is assigned to it, thus updating + the status to assignable. + """ + raise NotImplementedError() + + @abstractmethod + def update_unit( + self, unit_id: str, agent_id: Optional[str] = None, status: Optional[str] = None + ) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + """ + raise NotImplementedError() + + @abstractmethod + def new_requester(self, requester_name: str, provider_type: str) -> str: + """ + Create a new requester with the given name and provider type. + Raises EntryAlreadyExistsException + if there is already a requester with this name + """ + raise NotImplementedError() + + @abstractmethod + def get_requester(self, requester_id: str) -> Mapping[str, Any]: + """ + Return requester's fields by requester_id, raise EntryDoesNotExistException + if no id exists in requesters + + See requester for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_requesters( + self, requester_name: Optional[str] = None, provider_type: Optional[str] = None + ) -> List[Requester]: + """ + Try to find any requester that matches the above. When called with no arguments, + return all requesters. + """ + raise NotImplementedError() + + @abstractmethod + def new_worker(self, worker_name: str, provider_type: str) -> str: + """ + Create a new worker with the given name and provider type. + Raises EntryAlreadyExistsException + if there is already a worker with this name + + worker_name should be the unique identifier by which the crowd provider + is using to keep track of this worker + """ + raise NotImplementedError() + + @abstractmethod + def get_worker(self, worker_id: str) -> Mapping[str, Any]: + """ + Return worker's fields by worker_id, raise EntryDoesNotExistException + if no id exists in workers + + See worker for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def find_workers( + self, worker_name: Optional[str] = None, provider_type: Optional[str] = None + ) -> List[Worker]: + """ + Try to find any worker that matches the above. When called with no arguments, + return all workers. + """ + raise NotImplementedError() + + @abstractmethod + def new_agent( + self, + worker_id: str, + unit_id: str, + task_id: str, + task_run_id: str, + assignment_id: str, + task_type: str, + provider_type: str, + ) -> str: + """ + Create a new agent for the given worker id to assign to the given unit + Raises EntryAlreadyExistsException + + Should update the unit's status to ASSIGNED and the assigned agent to + this one. + """ + raise NotImplementedError() + + @abstractmethod + def get_agent(self, agent_id: str) -> Mapping[str, Any]: + """ + Return agent's fields by agent_id, raise EntryDoesNotExistException + if no id exists in agents + + See Agent for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def update_agent(self, agent_id: str, status: Optional[str] = None) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + """ + raise NotImplementedError() + + @abstractmethod + def find_agents( + self, + status: Optional[str] = None, + unit_id: Optional[str] = None, + worker_id: Optional[str] = None, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + assignment_id: Optional[str] = None, + task_type: Optional[str] = None, + provider_type: Optional[str] = None, + ) -> List[Agent]: + """ + Try to find any agent that matches the above. When called with no arguments, + return all agents. + """ + raise NotImplementedError() + + @abstractmethod + def new_onboarding_agent( + self, worker_id: str, task_id: str, task_run_id: str, task_type: str + ) -> str: + """ + Create a new agent for the given worker id to assign to the given unit + Raises EntryAlreadyExistsException + + Should update the unit's status to ASSIGNED and the assigned agent to + this one. + """ + raise NotImplementedError() + + @abstractmethod + def get_onboarding_agent(self, onboarding_agent_id: str) -> Mapping[str, Any]: + """ + Return onboarding agent's fields by onboarding_agent_id, raise + EntryDoesNotExistException if no id exists in onboarding_agents + + See OnboardingAgent for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def update_onboarding_agent( + self, onboarding_agent_id: str, status: Optional[str] = None + ) -> None: + """ + Update the given onboarding agent with the given parameters if possible, + raise appropriate exception otherwise. + """ + raise NotImplementedError() + + @abstractmethod + def find_onboarding_agents( + self, + status: Optional[str] = None, + worker_id: Optional[str] = None, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + task_type: Optional[str] = None, + ) -> List[OnboardingAgent]: + """ + Try to find any onboarding agent that matches the above. When called with no arguments, + return all onboarding agents. + """ + raise NotImplementedError() + + @abstractmethod + def make_qualification(self, qualification_name: str) -> str: + """ + Make a new qualification, throws an error if a qualification by the given name + already exists. Return the id for the qualification. + """ + raise NotImplementedError() + + @abstractmethod + def find_qualifications( + self, qualification_name: Optional[str] = None + ) -> List[Qualification]: + """ + Find a qualification. If no name is supplied, returns all qualifications. + """ + raise NotImplementedError() + + @abstractmethod + def get_qualification(self, qualification_id: str) -> Mapping[str, Any]: + """ + Return qualification's fields by qualification_id, raise + EntryDoesNotExistException if no id exists in qualifications + + See Qualification for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def _delete_qualification(self, qualification_name: str) -> None: + """ + Remove this qualification from all workers that have it, then delete the qualification + """ + raise NotImplementedError() + + @abstractmethod + def grant_qualification( + self, qualification_id: str, worker_id: str, value: int = 1 + ) -> None: + """ + Grant a worker the given qualification. Update the qualification value if it + already exists + """ + raise NotImplementedError() + + @abstractmethod + def check_granted_qualifications( + self, + qualification_id: Optional[str] = None, + worker_id: Optional[str] = None, + value: Optional[int] = None, + ) -> List[GrantedQualification]: + """ + Find granted qualifications that match the given specifications + """ + raise NotImplementedError() + + @abstractmethod + def get_granted_qualification( + self, qualification_id: Optional[str] = None, worker_id: Optional[str] = None + ) -> Mapping[str, Any]: + """ + Return the granted qualification in the database between the given + worker and qualification id + + See GrantedQualification for the expected fields for the returned mapping + """ + raise NotImplementedError() + + @abstractmethod + def revoke_qualification(self, qualification_id: str, worker_id: str) -> None: + """ + Remove the given qualification from the given worker + """ + raise NotImplementedError() diff --git a/mephisto/abstractions/databases/__init__.py b/mephisto/abstractions/databases/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/databases/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/databases/local_database.py b/mephisto/abstractions/databases/local_database.py new file mode 100644 index 000000000..42f9a8d29 --- /dev/null +++ b/mephisto/abstractions/databases/local_database.py @@ -0,0 +1,1369 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.database import ( + MephistoDB, + MephistoDBException, + EntryAlreadyExistsException, + EntryDoesNotExistException, +) +from typing import Mapping, Optional, Any, List, Dict +from mephisto.operations.utils import get_data_dir +from mephisto.operations.registry import get_valid_provider_types +from mephisto.data_model.agent import Agent, AgentState, OnboardingAgent +from mephisto.data_model.assignment import Assignment, Unit, AssignmentState +from mephisto.data_model.constants import NO_PROJECT_NAME +from mephisto.data_model.project import Project +from mephisto.data_model.requester import Requester +from mephisto.data_model.task import Task +from mephisto.data_model.task_run import TaskRun +from mephisto.data_model.worker import Worker +from mephisto.data_model.qualification import Qualification, GrantedQualification + +import sqlite3 +from sqlite3 import Connection, Cursor +import threading + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + + +def nonesafe_int(in_string: Optional[str]) -> Optional[int]: + """Cast input to an int or None""" + if in_string is None: + return None + return int(in_string) + + +def assert_valid_provider(provider_type: str) -> None: + """Throw an assertion error if the given provider type is not valid""" + valid_types = get_valid_provider_types() + if provider_type not in valid_types: + raise MephistoDBException( + f"Supplied provider {provider_type} is not in supported list of providers {valid_types}." + ) + + +def is_key_failure(e: sqlite3.IntegrityError) -> bool: + """ + Return if the given error is representing a foreign key + failure, where an insertion was expecting something to + exist already in the DB but it didn't. + """ + return str(e) == "FOREIGN KEY constraint failed" + + +def is_unique_failure(e: sqlite3.IntegrityError) -> bool: + """ + Return if the given error is representing a foreign key + failure, where an insertion was expecting something to + exist already in the DB but it didn't. + """ + return str(e).startswith("UNIQUE constraint") + + +CREATE_PROJECTS_TABLE = """CREATE TABLE IF NOT EXISTS projects ( + project_id INTEGER PRIMARY KEY AUTOINCREMENT, + project_name TEXT NOT NULL UNIQUE, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_TASKS_TABLE = """CREATE TABLE IF NOT EXISTS tasks ( + task_id INTEGER PRIMARY KEY AUTOINCREMENT, + task_name TEXT NOT NULL UNIQUE, + task_type TEXT NOT NULL, + project_id INTEGER, + parent_task_id INTEGER, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (parent_task_id) REFERENCES tasks (task_id), + FOREIGN KEY (project_id) REFERENCES projects (project_id) +); +""" + +CREATE_REQUESTERS_TABLE = """CREATE TABLE IF NOT EXISTS requesters ( + requester_id INTEGER PRIMARY KEY AUTOINCREMENT, + requester_name TEXT NOT NULL UNIQUE, + provider_type TEXT NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_TASK_RUNS_TABLE = """ + CREATE TABLE IF NOT EXISTS task_runs ( + task_run_id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id INTEGER NOT NULL, + requester_id INTEGER NOT NULL, + init_params TEXT NOT NULL, + is_completed BOOLEAN NOT NULL, + provider_type TEXT NOT NULL, + task_type TEXT NOT NULL, + sandbox BOOLEAN NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (task_id) REFERENCES tasks (task_id), + FOREIGN KEY (requester_id) REFERENCES requesters (requester_id) +); +""" + +CREATE_ASSIGNMENTS_TABLE = """CREATE TABLE IF NOT EXISTS assignments ( + assignment_id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id INTEGER NOT NULL, + task_run_id INTEGER NOT NULL, + requester_id INTEGER NOT NULL, + task_type TEXT NOT NULL, + provider_type TEXT NOT NULL, + sandbox BOOLEAN NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (task_id) REFERENCES tasks (task_id), + FOREIGN KEY (task_run_id) REFERENCES task_runs (task_run_id), + FOREIGN KEY (requester_id) REFERENCES requesters (requester_id) +); +""" + +CREATE_UNITS_TABLE = """CREATE TABLE IF NOT EXISTS units ( + unit_id INTEGER PRIMARY KEY AUTOINCREMENT, + assignment_id INTEGER NOT NULL, + unit_index INTEGER NOT NULL, + pay_amount FLOAT NOT NULL, + provider_type TEXT NOT NULL, + status TEXT NOT NULL, + agent_id INTEGER, + worker_id INTEGER, + task_type TEXT NOT NULL, + task_id INTEGER NOT NULL, + task_run_id INTEGER NOT NULL, + sandbox BOOLEAN NOT NULL, + requester_id INTEGER NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (assignment_id) REFERENCES assignments (assignment_id), + FOREIGN KEY (agent_id) REFERENCES agents (agent_id), + FOREIGN KEY (task_run_id) REFERENCES task_runs (task_run_id), + FOREIGN KEY (task_id) REFERENCES tasks (task_id), + FOREIGN KEY (requester_id) REFERENCES requesters (requester_id), + FOREIGN KEY (worker_id) REFERENCES workers (worker_id), + UNIQUE (assignment_id, unit_index) +); +""" + +CREATE_WORKERS_TABLE = """CREATE TABLE IF NOT EXISTS workers ( + worker_id INTEGER PRIMARY KEY AUTOINCREMENT, + worker_name TEXT NOT NULL UNIQUE, + provider_type TEXT NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_AGENTS_TABLE = """CREATE TABLE IF NOT EXISTS agents ( + agent_id INTEGER PRIMARY KEY AUTOINCREMENT, + worker_id INTEGER NOT NULL, + unit_id INTEGER NOT NULL, + task_id INTEGER NOT NULL, + task_run_id INTEGER NOT NULL, + assignment_id INTEGER NOT NULL, + task_type TEXT NOT NULL, + provider_type TEXT NOT NULL, + status TEXT NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (worker_id) REFERENCES workers (worker_id), + FOREIGN KEY (unit_id) REFERENCES units (unit_id) +); +""" + +CREATE_ONBOARDING_AGENTS_TABLE = """CREATE TABLE IF NOT EXISTS onboarding_agents ( + onboarding_agent_id INTEGER PRIMARY KEY AUTOINCREMENT, + worker_id INTEGER NOT NULL, + task_id INTEGER NOT NULL, + task_run_id INTEGER NOT NULL, + task_type TEXT NOT NULL, + status TEXT NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (worker_id) REFERENCES workers (worker_id), + FOREIGN KEY (task_run_id) REFERENCES task_runs (task_run_id) +); +""" + +CREATE_QUALIFICATIONS_TABLE = """CREATE TABLE IF NOT EXISTS qualifications ( + qualification_id INTEGER PRIMARY KEY AUTOINCREMENT, + qualification_name TEXT NOT NULL UNIQUE, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_GRANTED_QUALIFICATIONS_TABLE = """ +CREATE TABLE IF NOT EXISTS granted_qualifications ( + granted_qualification_id INTEGER PRIMARY KEY AUTOINCREMENT, + worker_id INTEGER NOT NULL, + qualification_id INTEGER NOT NULL, + value INTEGER NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (worker_id) REFERENCES workers (worker_id), + FOREIGN KEY (qualification_id) REFERENCES qualifications (qualification_id), + UNIQUE (worker_id, qualification_id) +); +""" + + +class StringIDRow(sqlite3.Row): + def __getitem__(self, key: str) -> Any: + val = super().__getitem__(key) + if key.endswith("_id") and val is not None: + return str(val) + else: + return val + + +# TODO(101) find_x queries are pretty slow right now, as we query the same table once to get +# all of the rows, but only select the ids, then we later construct them individually, +# making a second set of requests. +# It would be better to expose an init param for DB Objects that takes in the full row +# and inits with that if provided, and queries the database if not. +class LocalMephistoDB(MephistoDB): + """ + Local database for core Mephisto data storage, the LocalMephistoDatabase handles + grounding all of the python interactions with the Mephisto architecture to + local files and a database. + """ + + def __init__(self, database_path=None): + logger.debug(f"database path: {database_path}") + self.conn: Dict[int, Connection] = {} + self.table_access_condition = threading.Condition() + super().__init__(database_path) + + def _get_connection(self) -> Connection: + """Returns a singular database connection to be shared amongst all + calls for a given thread. + """ + # TODO(101) is there a problem with having just one db connection? + # Will this cause bugs with failed commits? + curr_thread = threading.get_ident() + if curr_thread not in self.conn or self.conn[curr_thread] is None: + try: + conn = sqlite3.connect(self.db_path) + conn.row_factory = StringIDRow + self.conn[curr_thread] = conn + except sqlite3.Error as e: + raise MephistoDBException(e) + return self.conn[curr_thread] + + def shutdown(self) -> None: + """Close all open connections""" + with self.table_access_condition: + curr_thread = threading.get_ident() + self.conn[curr_thread].close() + del self.conn[curr_thread] + + def init_tables(self) -> None: + """ + Run all the table creation SQL queries to ensure the expected tables exist + """ + # TODO(#93) maybe raise flag when the schema of existing tables isn't what we expect + # it to be? + # "How to know that schema changes?" + # logger.warning("some message") + with self.table_access_condition: + conn = self._get_connection() + conn.execute("PRAGMA foreign_keys = 1") + with conn: + c = conn.cursor() + c.execute(CREATE_PROJECTS_TABLE) + c.execute(CREATE_TASKS_TABLE) + c.execute(CREATE_REQUESTERS_TABLE) + c.execute(CREATE_TASK_RUNS_TABLE) + c.execute(CREATE_ASSIGNMENTS_TABLE) + c.execute(CREATE_UNITS_TABLE) + c.execute(CREATE_WORKERS_TABLE) + c.execute(CREATE_AGENTS_TABLE) + c.execute(CREATE_QUALIFICATIONS_TABLE) + c.execute(CREATE_GRANTED_QUALIFICATIONS_TABLE) + c.execute(CREATE_ONBOARDING_AGENTS_TABLE) + + def __get_one_by_id( + self, table_name: str, id_name: str, db_id: str + ) -> Mapping[str, Any]: + """ + Try to request the row for the given table and entry, + raise EntryDoesNotExistException if it isn't present + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + f""" + SELECT * FROM {table_name} + WHERE ({id_name} = ?) + """, + (int(db_id),), + ) + results = c.fetchall() + if len(results) != 1: + raise EntryDoesNotExistException( + f"Table {table_name} has no {id_name} {db_id}" + ) + return results[0] + + def new_project(self, project_name: str) -> str: + """ + Create a new project with the given project name. Raise EntryAlreadyExistsException if a project + with this name has already been created. + """ + if project_name in [NO_PROJECT_NAME, ""]: + raise MephistoDBException(f'Invalid project name "{project_name}') + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + "INSERT INTO projects(project_name) VALUES (?);", (project_name,) + ) + project_id = str(c.lastrowid) + return project_id + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException() + elif is_unique_failure(e): + raise EntryAlreadyExistsException( + f"Project {project_name} already exists" + ) + raise MephistoDBException(e) + + def get_project(self, project_id: str) -> Mapping[str, Any]: + """ + Return project's fields by the given project_id, raise EntryDoesNotExistException + if no id exists in projects + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("projects", "project_id", project_id) + + def find_projects(self, project_name: Optional[str] = None) -> List[Project]: + """ + Try to find any project that matches the above. When called with no arguments, + return all projects. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from projects + WHERE (?1 IS NULL OR project_name = ?1) + """, + (project_name,), + ) + rows = c.fetchall() + return [Project(self, str(r["project_id"]), row=r) for r in rows] + + def new_task( + self, + task_name: str, + task_type: str, + project_id: Optional[str] = None, + parent_task_id: Optional[str] = None, + ) -> str: + """ + Create a new task with the given task name. Raise EntryAlreadyExistsException if a task + with this name has already been created. + """ + if task_name in [""]: + raise MephistoDBException(f'Invalid task name "{task_name}') + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """INSERT INTO tasks( + task_name, + task_type, + project_id, + parent_task_id + ) VALUES (?, ?, ?, ?);""", + ( + task_name, + task_type, + nonesafe_int(project_id), + nonesafe_int(parent_task_id), + ), + ) + task_id = str(c.lastrowid) + return task_id + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + elif is_unique_failure(e): + raise EntryAlreadyExistsException(e) + raise MephistoDBException(e) + + def get_task(self, task_id: str) -> Mapping[str, Any]: + """ + Return task's fields by task_id, raise EntryDoesNotExistException if no id exists + in tasks + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("tasks", "task_id", task_id) + + def find_tasks( + self, + task_name: Optional[str] = None, + project_id: Optional[str] = None, + parent_task_id: Optional[str] = None, + ) -> List[Task]: + """ + Try to find any task that matches the above. When called with no arguments, + return all tasks. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from tasks + WHERE (?1 IS NULL OR task_name = ?1) + AND (?2 IS NULL OR project_id = ?2) + AND (?3 IS NULL OR parent_task_id = ?3) + """, + (task_name, nonesafe_int(project_id), nonesafe_int(parent_task_id)), + ) + rows = c.fetchall() + return [Task(self, str(r["task_id"]), row=r) for r in rows] + + def update_task( + self, + task_id: str, + task_name: Optional[str] = None, + project_id: Optional[str] = None, + ) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + + Tasks can only be updated if no runs exist for this task yet, otherwise there's too much state + and we shouldn't make changes. + """ + if len(self.find_task_runs(task_id=task_id)) != 0: + raise MephistoDBException( + "Cannot edit a task that has already been run, for risk of data corruption." + ) + if task_name in [""]: + raise MephistoDBException(f'Invalid task name "{task_name}') + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + if task_name is not None: + c.execute( + """ + UPDATE tasks + SET task_name = ? + WHERE task_id = ?; + """, + (task_name, int(task_id)), + ) + if project_id is not None: + c.execute( + """ + UPDATE tasks + SET project_id = ? + WHERE task_id = ?; + """, + (int(project_id), int(task_id)), + ) + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + elif is_unique_failure(e): + raise EntryAlreadyExistsException( + f"Task name {task_name} is already in use" + ) + raise MephistoDBException(e) + + def new_task_run( + self, + task_id: str, + requester_id: str, + init_params: str, + provider_type: str, + task_type: str, + sandbox: bool = True, + ) -> str: + """Create a new task_run for the given task.""" + with self.table_access_condition, self._get_connection() as conn: + # Ensure given ids are valid + c = conn.cursor() + try: + c.execute( + """ + INSERT INTO task_runs( + task_id, + requester_id, + init_params, + is_completed, + provider_type, + task_type, + sandbox + ) + VALUES (?, ?, ?, ?, ?, ?, ?);""", + ( + int(task_id), + int(requester_id), + init_params, + False, + provider_type, + task_type, + sandbox, + ), + ) + task_run_id = str(c.lastrowid) + return task_run_id + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + raise MephistoDBException(e) + + def get_task_run(self, task_run_id: str) -> Mapping[str, Any]: + """ + Return the given task_run's fields by task_run_id, raise EntryDoesNotExistException if no id exists + in task_runs. + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("task_runs", "task_run_id", task_run_id) + + def find_task_runs( + self, + task_id: Optional[str] = None, + requester_id: Optional[str] = None, + is_completed: Optional[bool] = None, + ) -> List[TaskRun]: + """ + Try to find any task_run that matches the above. When called with no arguments, + return all task_runs. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from task_runs + WHERE (?1 IS NULL OR task_id = ?1) + AND (?2 IS NULL OR requester_id = ?2) + AND (?3 IS NULL OR is_completed = ?3) + """, + (nonesafe_int(task_id), nonesafe_int(requester_id), is_completed), + ) + rows = c.fetchall() + return [TaskRun(self, str(r["task_run_id"]), row=r) for r in rows] + + def update_task_run(self, task_run_id: str, is_completed: bool): + """ + Update a task run. At the moment, can only update completion status + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """ + UPDATE task_runs + SET is_completed = ? + WHERE task_run_id = ?; + """, + (is_completed, int(task_run_id)), + ) + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + raise MephistoDBException(e) + + def new_assignment( + self, + task_id: str, + task_run_id: str, + requester_id: str, + task_type: str, + provider_type: str, + sandbox: bool = True, + ) -> str: + """Create a new assignment for the given task""" + # Ensure task run exists + self.get_task_run(task_run_id) + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """ + INSERT INTO assignments( + task_id, + task_run_id, + requester_id, + task_type, + provider_type, + sandbox + ) VALUES (?, ?, ?, ?, ?, ?);""", + ( + int(task_id), + int(task_run_id), + int(requester_id), + task_type, + provider_type, + sandbox, + ), + ) + assignment_id = str(c.lastrowid) + return assignment_id + + def get_assignment(self, assignment_id: str) -> Mapping[str, Any]: + """ + Return assignment's fields by assignment_id, raise EntryDoesNotExistException + if no id exists in tasks + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("assignments", "assignment_id", assignment_id) + + def find_assignments( + self, + task_run_id: Optional[str] = None, + task_id: Optional[str] = None, + requester_id: Optional[str] = None, + task_type: Optional[str] = None, + provider_type: Optional[str] = None, + sandbox: Optional[bool] = None, + ) -> List[Assignment]: + """ + Try to find any task that matches the above. When called with no arguments, + return all tasks. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from assignments + WHERE (?1 IS NULL OR task_run_id = ?1) + AND (?2 IS NULL OR task_id = ?2) + AND (?3 IS NULL OR requester_id = ?3) + AND (?4 IS NULL OR task_type = ?4) + AND (?5 IS NULL OR provider_type = ?5) + AND (?6 IS NULL OR sandbox = ?6) + """, + ( + nonesafe_int(task_run_id), + nonesafe_int(task_id), + nonesafe_int(requester_id), + task_type, + provider_type, + sandbox, + ), + ) + rows = c.fetchall() + return [Assignment(self, str(r["assignment_id"]), row=r) for r in rows] + + def new_unit( + self, + task_id: str, + task_run_id: str, + requester_id: str, + assignment_id: str, + unit_index: int, + pay_amount: float, + provider_type: str, + task_type: str, + sandbox: bool = True, + ) -> str: + """ + Create a new unit with the given index. Raises EntryAlreadyExistsException + if there is already a unit for the given assignment with the given index. + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """INSERT INTO units( + task_id, + task_run_id, + requester_id, + assignment_id, + unit_index, + pay_amount, + provider_type, + task_type, + sandbox, + status + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);""", + ( + int(task_id), + int(task_run_id), + int(requester_id), + int(assignment_id), + unit_index, + pay_amount, + provider_type, + task_type, + sandbox, + AssignmentState.CREATED, + ), + ) + unit_id = str(c.lastrowid) + return unit_id + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + elif is_unique_failure(e): + raise EntryAlreadyExistsException(e) + raise MephistoDBException(e) + + def get_unit(self, unit_id: str) -> Mapping[str, Any]: + """ + Return unit's fields by unit_id, raise EntryDoesNotExistException + if no id exists in units + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("units", "unit_id", unit_id) + + def find_units( + self, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + requester_id: Optional[str] = None, + assignment_id: Optional[str] = None, + unit_index: Optional[int] = None, + provider_type: Optional[str] = None, + task_type: Optional[str] = None, + agent_id: Optional[str] = None, + worker_id: Optional[str] = None, + sandbox: Optional[bool] = None, + status: Optional[str] = None, + ) -> List[Unit]: + """ + Try to find any unit that matches the above. When called with no arguments, + return all units. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from units + WHERE (?1 IS NULL OR task_id = ?1) + AND (?2 IS NULL OR task_run_id = ?2) + AND (?3 IS NULL OR requester_id = ?3) + AND (?4 IS NULL OR assignment_id = ?4) + AND (?5 IS NULL OR unit_index = ?5) + AND (?6 IS NULL OR provider_type = ?6) + AND (?7 IS NULL OR task_type = ?7) + AND (?8 IS NULL OR agent_id = ?8) + AND (?9 IS NULL OR worker_id = ?9) + AND (?10 IS NULL OR sandbox = ?10) + AND (?11 IS NULL OR status = ?11) + """, + ( + nonesafe_int(task_id), + nonesafe_int(task_run_id), + nonesafe_int(requester_id), + nonesafe_int(assignment_id), + unit_index, + provider_type, + task_type, + nonesafe_int(agent_id), + nonesafe_int(worker_id), + sandbox, + status, + ), + ) + rows = c.fetchall() + return [Unit(self, str(r["unit_id"]), row=r) for r in rows] + + def clear_unit_agent_assignment(self, unit_id: str) -> None: + """ + Update the given unit by removing the agent that is assigned to it, thus updating + the status to assignable. + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """ + UPDATE units + SET agent_id = ?, worker_id = ?, status = ? + WHERE unit_id = ?; + """, + (None, None, AssignmentState.LAUNCHED, int(unit_id)), + ) + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException( + f"Given unit_id {unit_id} not found in the database" + ) + raise MephistoDBException(e) + + def update_unit( + self, unit_id: str, agent_id: Optional[str] = None, status: Optional[str] = None + ) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + """ + if status not in AssignmentState.valid_unit(): + raise MephistoDBException(f"Invalid status {status} for a unit") + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + if agent_id is not None: + c.execute( + """ + UPDATE units + SET agent_id = ? + WHERE unit_id = ?; + """, + (int(agent_id), int(unit_id)), + ) + if status is not None: + c.execute( + """ + UPDATE units + SET status = ? + WHERE unit_id = ?; + """, + (status, int(unit_id)), + ) + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException( + f"Given unit_id {unit_id} not found in the database" + ) + raise MephistoDBException(e) + + def new_requester(self, requester_name: str, provider_type: str) -> str: + """ + Create a new requester with the given name and provider type. + Raises EntryAlreadyExistsException + if there is already a requester with this name + """ + if requester_name == "": + raise MephistoDBException("Empty string is not a valid requester name") + assert_valid_provider(provider_type) + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + "INSERT INTO requesters(requester_name, provider_type) VALUES (?, ?);", + (requester_name, provider_type), + ) + requester_id = str(c.lastrowid) + return requester_id + except sqlite3.IntegrityError as e: + if is_unique_failure(e): + raise EntryAlreadyExistsException() + raise MephistoDBException(e) + + def get_requester(self, requester_id: str) -> Mapping[str, Any]: + """ + Return requester's fields by requester_id, raise EntryDoesNotExistException + if no id exists in requesters + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("requesters", "requester_id", requester_id) + + def find_requesters( + self, requester_name: Optional[str] = None, provider_type: Optional[str] = None + ) -> List[Requester]: + """ + Try to find any requester that matches the above. When called with no arguments, + return all requesters. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from requesters + WHERE (?1 IS NULL OR requester_name = ?1) + AND (?2 IS NULL OR provider_type = ?2) + """, + (requester_name, provider_type), + ) + rows = c.fetchall() + return [Requester(self, str(r["requester_id"]), row=r) for r in rows] + + def new_worker(self, worker_name: str, provider_type: str) -> str: + """ + Create a new worker with the given name and provider type. + Raises EntryAlreadyExistsException + if there is already a worker with this name + + worker_name should be the unique identifier by which the crowd provider + is using to keep track of this worker + """ + if worker_name == "": + raise MephistoDBException("Empty string is not a valid requester name") + assert_valid_provider(provider_type) + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + "INSERT INTO workers(worker_name, provider_type) VALUES (?, ?);", + (worker_name, provider_type), + ) + worker_id = str(c.lastrowid) + return worker_id + except sqlite3.IntegrityError as e: + if is_unique_failure(e): + raise EntryAlreadyExistsException() + raise MephistoDBException(e) + + def get_worker(self, worker_id: str) -> Mapping[str, Any]: + """ + Return worker's fields by worker_id, raise EntryDoesNotExistException + if no id exists in workers + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("workers", "worker_id", worker_id) + + def find_workers( + self, worker_name: Optional[str] = None, provider_type: Optional[str] = None + ) -> List[Worker]: + """ + Try to find any worker that matches the above. When called with no arguments, + return all workers. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from workers + WHERE (?1 IS NULL OR worker_name = ?1) + AND (?2 IS NULL OR provider_type = ?2) + """, + (worker_name, provider_type), + ) + rows = c.fetchall() + return [Worker(self, str(r["worker_id"]), row=r) for r in rows] + + def new_agent( + self, + worker_id: str, + unit_id: str, + task_id: str, + task_run_id: str, + assignment_id: str, + task_type: str, + provider_type: str, + ) -> str: + """ + Create a new agent with the given name and provider type. + Raises EntryAlreadyExistsException + if there is already a agent with this name + """ + assert_valid_provider(provider_type) + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """INSERT INTO agents( + worker_id, + unit_id, + task_id, + task_run_id, + assignment_id, + task_type, + provider_type, + status + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?);""", + ( + int(worker_id), + int(unit_id), + int(task_id), + int(task_run_id), + int(assignment_id), + task_type, + provider_type, + AgentState.STATUS_NONE, + ), + ) + agent_id = str(c.lastrowid) + c.execute( + """ + UPDATE units + SET status = ?, agent_id = ?, worker_id = ? + WHERE unit_id = ?; + """, + ( + AssignmentState.ASSIGNED, + int(agent_id), + int(worker_id), + int(unit_id), + ), + ) + return agent_id + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + raise MephistoDBException(e) + + def get_agent(self, agent_id: str) -> Mapping[str, Any]: + """ + Return agent's fields by agent_id, raise EntryDoesNotExistException + if no id exists in agents + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id("agents", "agent_id", agent_id) + + def update_agent(self, agent_id: str, status: Optional[str] = None) -> None: + """ + Update the given task with the given parameters if possible, raise appropriate exception otherwise. + """ + if status not in AgentState.valid(): + raise MephistoDBException(f"Invalid status {status} for an agent") + + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """ + UPDATE agents + SET status = ? + WHERE agent_id = ?; + """, + (status, int(agent_id)), + ) + + def find_agents( + self, + status: Optional[str] = None, + unit_id: Optional[str] = None, + worker_id: Optional[str] = None, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + assignment_id: Optional[str] = None, + task_type: Optional[str] = None, + provider_type: Optional[str] = None, + ) -> List[Agent]: + """ + Try to find any agent that matches the above. When called with no arguments, + return all agents. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from agents + WHERE (?1 IS NULL OR status = ?1) + AND (?2 IS NULL OR unit_id = ?2) + AND (?3 IS NULL OR worker_id = ?3) + AND (?4 IS NULL OR task_id = ?4) + AND (?5 IS NULL OR task_run_id = ?5) + AND (?6 IS NULL OR assignment_id = ?6) + AND (?7 IS NULL OR task_type = ?7) + AND (?8 IS NULL OR provider_type = ?8) + """, + ( + status, + nonesafe_int(unit_id), + nonesafe_int(worker_id), + nonesafe_int(task_id), + nonesafe_int(task_run_id), + nonesafe_int(assignment_id), + task_type, + provider_type, + ), + ) + rows = c.fetchall() + return [Agent(self, str(r["agent_id"]), row=r) for r in rows] + + def make_qualification(self, qualification_name: str) -> str: + """ + Make a new qualification, throws an error if a qualification by the given name + already exists. Return the id for the qualification. + """ + if qualification_name == "": + raise MephistoDBException("Empty string is not a valid qualification name") + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + "INSERT INTO qualifications(qualification_name) VALUES (?);", + (qualification_name,), + ) + qualification_id = str(c.lastrowid) + return qualification_id + except sqlite3.IntegrityError as e: + if is_unique_failure(e): + raise EntryAlreadyExistsException() + raise MephistoDBException(e) + + def find_qualifications( + self, qualification_name: Optional[str] = None + ) -> List[Qualification]: + """ + Find a qualification. If no name is supplied, returns all qualifications. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from qualifications + WHERE (?1 IS NULL OR qualification_name = ?1) + """, + (qualification_name,), + ) + rows = c.fetchall() + return [ + Qualification(self, str(r["qualification_id"]), row=r) for r in rows + ] + + def get_qualification(self, qualification_id: str) -> Mapping[str, Any]: + """ + Return qualification's fields by qualification_id, raise + EntryDoesNotExistException if no id exists in qualifications + + See Qualification for the expected fields for the returned mapping + """ + return self.__get_one_by_id( + "qualifications", "qualification_id", qualification_id + ) + + def _delete_qualification(self, qualification_name: str) -> None: + """ + Remove this qualification from all workers that have it, then delete the qualification + """ + qualifications = self.find_qualifications(qualification_name=qualification_name) + if len(qualifications) == 0: + raise EntryDoesNotExistException( + f"No qualification found by name {qualification_name}" + ) + qualification = qualifications[0] + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + "DELETE FROM granted_qualifications WHERE qualification_id = ?1;", + (int(qualification.db_id),), + ) + c.execute( + "DELETE FROM qualifications WHERE qualification_name = ?1;", + (qualification_name,), + ) + + def grant_qualification( + self, qualification_id: str, worker_id: str, value: int = 1 + ) -> None: + """ + Grant a worker the given qualification. Update the qualification value if it + already exists + """ + # Note that better syntax exists for python 3.8+, as described in PR #223 + try: + # Update existing entry + qual_row = self.get_granted_qualification(qualification_id, worker_id) + with self.table_access_condition, self._get_connection() as conn: + if value != qual_row["value"]: + c = conn.cursor() + c.execute( + """ + UPDATE granted_qualifications + SET value = ? + WHERE (qualification_id = ?) + AND (worker_id = ?); + """, + (value, int(qualification_id), int(worker_id)), + ) + conn.commit() + return None + except EntryDoesNotExistException: + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """ + INSERT INTO granted_qualifications( + qualification_id, + worker_id, + value + ) VALUES (?, ?, ?); + """, + (int(qualification_id), int(worker_id), value), + ) + qualification_id = str(c.lastrowid) + conn.commit() + return None + except sqlite3.IntegrityError as e: + if is_unique_failure(e): + raise EntryAlreadyExistsException() + raise MephistoDBException(e) + + def check_granted_qualifications( + self, + qualification_id: Optional[str] = None, + worker_id: Optional[str] = None, + value: Optional[int] = None, + ) -> List[GrantedQualification]: + """ + Find granted qualifications that match the given specifications + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from granted_qualifications + WHERE (?1 IS NULL OR qualification_id = ?1) + AND (?2 IS NULL OR worker_id = ?2) + AND (?3 IS NULL OR value = ?3) + """, + (qualification_id, worker_id, value), + ) + rows = c.fetchall() + return [ + GrantedQualification( + self, str(r["qualification_id"]), str(r["worker_id"]) + ) + for r in rows + ] + + # TODO(101) these should not be optional + def get_granted_qualification( + self, qualification_id: Optional[str] = None, worker_id: Optional[str] = None + ) -> Mapping[str, Any]: + """ + Return the granted qualification in the database between the given + worker and qualification id + + See GrantedQualification for the expected fields for the returned mapping + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + f""" + SELECT * FROM granted_qualifications + WHERE (qualification_id = ?1) + AND (worker_id = ?2); + """, + (nonesafe_int(qualification_id), nonesafe_int(worker_id)), + ) + results = c.fetchall() + if len(results) != 1: + raise EntryDoesNotExistException( + f"No such granted qualification {qualification_id}, {worker_id}" + ) + return results[0] + + def revoke_qualification(self, qualification_id: str, worker_id: str) -> None: + """ + Remove the given qualification from the given worker + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """DELETE FROM granted_qualifications + WHERE (qualification_id = ?1) + AND (worker_id = ?2); + """, + (int(qualification_id), int(worker_id)), + ) + + def new_onboarding_agent( + self, worker_id: str, task_id: str, task_run_id: str, task_type: str + ) -> str: + """ + Create a new agent for the given worker id to assign to the given unit + Raises EntryAlreadyExistsException + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + try: + c.execute( + """INSERT INTO onboarding_agents( + worker_id, + task_id, + task_run_id, + task_type, + status + ) VALUES (?, ?, ?, ?, ?);""", + ( + int(worker_id), + int(task_id), + int(task_run_id), + task_type, + AgentState.STATUS_NONE, + ), + ) + return str(c.lastrowid) + except sqlite3.IntegrityError as e: + if is_key_failure(e): + raise EntryDoesNotExistException(e) + raise MephistoDBException(e) + + def get_onboarding_agent(self, onboarding_agent_id: str) -> Mapping[str, Any]: + """ + Return onboarding agent's fields by onboarding_agent_id, raise + EntryDoesNotExistException if no id exists in onboarding_agents + + Returns a SQLite Row object with the expected fields + """ + return self.__get_one_by_id( + "onboarding_agents", "onboarding_agent_id", onboarding_agent_id + ) + + def update_onboarding_agent( + self, onboarding_agent_id: str, status: Optional[str] = None + ) -> None: + """ + Update the given onboarding agent with the given parameters if possible, + raise appropriate exception otherwise. + """ + if status not in AgentState.valid(): + raise MephistoDBException(f"Invalid status {status} for an agent") + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + if status is not None: + c.execute( + """ + UPDATE onboarding_agents + SET status = ? + WHERE onboarding_agent_id = ?; + """, + (status, int(onboarding_agent_id)), + ) + + def find_onboarding_agents( + self, + status: Optional[str] = None, + worker_id: Optional[str] = None, + task_id: Optional[str] = None, + task_run_id: Optional[str] = None, + task_type: Optional[str] = None, + ) -> List[OnboardingAgent]: + """ + Try to find any onboarding agent that matches the above. When called with no arguments, + return all onboarding agents. + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from onboarding_agents + WHERE (?1 IS NULL OR status = ?1) + AND (?2 IS NULL OR worker_id = ?2) + AND (?3 IS NULL OR task_id = ?3) + AND (?4 IS NULL OR task_run_id = ?4) + AND (?5 IS NULL OR task_type = ?5) + """, + ( + status, + nonesafe_int(worker_id), + nonesafe_int(task_id), + nonesafe_int(task_run_id), + task_type, + ), + ) + rows = c.fetchall() + return [ + OnboardingAgent(self, str(r["onboarding_agent_id"]), row=r) + for r in rows + ] diff --git a/mephisto/providers/README.md b/mephisto/abstractions/providers/README.md similarity index 100% rename from mephisto/providers/README.md rename to mephisto/abstractions/providers/README.md diff --git a/mephisto/abstractions/providers/__init__.py b/mephisto/abstractions/providers/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/providers/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/providers/mock/__init__.py b/mephisto/abstractions/providers/mock/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/providers/mock/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/providers/mock/mock_agent.py b/mephisto/abstractions/providers/mock/mock_agent.py new file mode 100644 index 000000000..76282e355 --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_agent.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.agent import Agent +from mephisto.abstractions.blueprint import AgentState +from mephisto.abstractions.providers.mock.provider_type import PROVIDER_TYPE + +from typing import List, Optional, Tuple, Dict, Mapping, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.assignment import Unit + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.worker import Worker + from mephisto.data_model.packet import Packet + from mephisto.abstractions.providers.mock.mock_datastore import MockDatastore + + +class MockAgent(Agent): + """ + This class encompasses a worker as they are working on an individual assignment. + It maintains details for the current task at hand such as start and end time, + connection status, etc. + """ + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MockDatastore" = db.get_datastore_for_provider(PROVIDER_TYPE) + if db_id not in self.datastore.agent_data: + self.datastore.agent_data[db_id] = { + "observed": [], + "pending_acts": [], + "acts": [], + } + + def observe(self, packet: "Packet") -> None: + """Put observations into this mock agent's observation list""" + self.datastore.agent_data[self.db_id]["observed"].append(packet) + super().observe(packet) + + def act(self, timeout=None) -> Optional["Packet"]: + """ + Either take an act from this mock agent's act queue (for use + by tests and other mock purposes) or request a regular act + (for use in manual testing). + """ + if len(self.datastore.agent_data[self.db_id]["pending_acts"]) > 0: + act = self.datastore.agent_data[self.db_id]["pending_acts"].pop(0) + else: + act = super().act(timeout=timeout) + + if act is not None: + self.datastore.agent_data[self.db_id]["acts"].append(act) + return act + + def approve_work(self) -> None: + """ + Approve the work done on this specific Unit + + Mock Units + """ + self.update_status(AgentState.STATUS_APPROVED) + + def reject_work(self, reason) -> None: + """ + Reject the work done on this specific Unit + """ + self.update_status(AgentState.STATUS_REJECTED) + + def mark_done(self) -> None: + """ + Take any required step with the crowd_provider to ensure that + the worker can submit their work and be marked as complete via + a call to get_status + """ + if self.get_status() not in AgentState.complete(): + self.db.update_agent( + agent_id=self.db_id, status=AgentState.STATUS_COMPLETED + ) + + def mark_disconnected(self) -> None: + """Mark this mock agent as having disconnected""" + self.db.update_agent(agent_id=self.db_id, status=AgentState.STATUS_DISCONNECT) + + @staticmethod + def new(db: "MephistoDB", worker: "Worker", unit: "Unit") -> "Agent": + """Create an agent for this worker to be used for work on the given Unit.""" + return MockAgent._register_agent(db, worker, unit, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mock/mock_datastore.py b/mephisto/abstractions/providers/mock/mock_datastore.py new file mode 100644 index 000000000..ae4f910cf --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_datastore.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 + +# 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 boto3 +import sqlite3 +import os +import threading + +from datetime import datetime + + +from botocore.exceptions import ClientError +from botocore.exceptions import ProfileNotFound + +from typing import Dict, Any, Optional + +MTURK_REGION_NAME = "us-east-1" + +CREATE_REQUESTERS_TABLE = """CREATE TABLE IF NOT EXISTS requesters ( + requester_id TEXT PRIMARY KEY UNIQUE, + is_registered BOOLEAN +); +""" + +CREATE_UNITS_TABLE = """CREATE TABLE IF NOT EXISTS units ( + unit_id TEXT PRIMARY KEY UNIQUE, + is_expired BOOLEAN +); +""" + +CREATE_WORKERS_TABLE = """CREATE TABLE IF NOT EXISTS workers ( + worker_id TEXT PRIMARY KEY UNIQUE, + is_blocked BOOLEAN +); +""" + + +class MockDatastore: + """ + Handles storing mock results and statuses across processes for use + in unit testing and manual experimentation. + """ + + def __init__(self, datastore_root: str): + """Initialize local storage of active agents, connect to the database""" + self.agent_data: Dict[str, Dict[str, Any]] = {} + self.table_access_condition = threading.Condition() + self.conn: Dict[int, sqlite3.Connection] = {} + self.db_path = os.path.join(datastore_root, "mock.db") + self.init_tables() + self.datastore_root = datastore_root + + def _get_connection(self) -> sqlite3.Connection: + """Returns a singular database connection to be shared amongst all + calls for a given thread. + """ + curr_thread = threading.get_ident() + if curr_thread not in self.conn or self.conn[curr_thread] is None: + conn = sqlite3.connect(self.db_path) + conn.row_factory = sqlite3.Row + self.conn[curr_thread] = conn + return self.conn[curr_thread] + + def init_tables(self) -> None: + """ + Run all the table creation SQL queries to ensure the expected tables exist + """ + with self.table_access_condition: + conn = self._get_connection() + conn.execute("PRAGMA foreign_keys = 1") + c = conn.cursor() + c.execute(CREATE_REQUESTERS_TABLE) + c.execute(CREATE_UNITS_TABLE) + c.execute(CREATE_WORKERS_TABLE) + conn.commit() + + def ensure_requester_exists(self, requester_id: str) -> None: + """Create a record of this requester if it doesn't exist""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """INSERT OR IGNORE INTO requesters( + requester_id, + is_registered + ) VALUES (?, ?);""", + (requester_id, False), + ) + conn.commit() + return None + + def set_requester_registered(self, requester_id: str, val: bool) -> None: + """Set the requester registration status for the given id""" + self.ensure_requester_exists(requester_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """UPDATE requesters + SET is_registered = ? + WHERE requester_id = ? + """, + (val, requester_id), + ) + conn.commit() + return None + + def get_requester_registered(self, requester_id: str) -> bool: + """Get the registration status of a requester""" + self.ensure_requester_exists(requester_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT is_registered from requesters + WHERE requester_id = ? + """, + (requester_id,), + ) + results = c.fetchall() + return bool(results[0]["is_registered"]) + + def ensure_worker_exists(self, worker_id: str) -> None: + """Create a record of this worker if it doesn't exist""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """INSERT OR IGNORE INTO workers( + worker_id, + is_blocked + ) VALUES (?, ?);""", + (worker_id, False), + ) + conn.commit() + return None + + def set_worker_blocked(self, worker_id: str, val: bool) -> None: + """Set the worker registration status for the given id""" + self.ensure_worker_exists(worker_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """UPDATE workers + SET is_blocked = ? + WHERE worker_id = ? + """, + (val, worker_id), + ) + conn.commit() + return None + + def get_worker_blocked(self, worker_id: str) -> bool: + """Get the registration status of a worker""" + self.ensure_worker_exists(worker_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT is_blocked from workers + WHERE worker_id = ? + """, + (worker_id,), + ) + results = c.fetchall() + return bool(results[0]["is_blocked"]) + + def ensure_unit_exists(self, unit_id: str) -> None: + """Create a record of this unit if it doesn't exist""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """INSERT OR IGNORE INTO units( + unit_id, + is_expired + ) VALUES (?, ?);""", + (unit_id, False), + ) + conn.commit() + return None + + def set_unit_expired(self, unit_id: str, val: bool) -> None: + """Set the unit registration status for the given id""" + self.ensure_unit_exists(unit_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """UPDATE units + SET is_expired = ? + WHERE unit_id = ? + """, + (val, unit_id), + ) + conn.commit() + return None + + def get_unit_expired(self, unit_id: str) -> bool: + """Get the registration status of a unit""" + self.ensure_unit_exists(unit_id) + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT is_expired from units + WHERE unit_id = ? + """, + (unit_id,), + ) + results = c.fetchall() + return bool(results[0]["is_expired"]) diff --git a/mephisto/abstractions/providers/mock/mock_provider.py b/mephisto/abstractions/providers/mock/mock_provider.py new file mode 100644 index 000000000..86a003825 --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_provider.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.crowd_provider import CrowdProvider, ProviderArgs +from mephisto.abstractions.providers.mock.mock_agent import MockAgent +from mephisto.abstractions.providers.mock.mock_requester import MockRequester +from mephisto.abstractions.providers.mock.mock_unit import MockUnit +from mephisto.abstractions.providers.mock.mock_worker import MockWorker +from mephisto.abstractions.providers.mock.mock_datastore import MockDatastore +from mephisto.abstractions.providers.mock.provider_type import PROVIDER_TYPE +from mephisto.data_model.requester import RequesterArgs +from mephisto.operations.registry import register_mephisto_abstraction +from dataclasses import dataclass, field + +from typing import ClassVar, Dict, Any, Optional, Type, List, TYPE_CHECKING + +import os + +if TYPE_CHECKING: + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Unit + from mephisto.data_model.worker import Worker + from mephisto.data_model.requester import Requester + from mephisto.data_model.agent import Agent + from mephisto.abstractions.blueprint import SharedTaskState + from omegaconf import DictConfig + + +@dataclass +class MockProviderArgs(ProviderArgs): + """Base class for arguments to configure Crowd Providers""" + + _provider_type: str = PROVIDER_TYPE + + +@register_mephisto_abstraction() +class MockProvider(CrowdProvider): + """ + Mock implementation of a CrowdProvider that stores everything + in a local state in the class for use in tests. + """ + + UnitClass: ClassVar[Type["Unit"]] = MockUnit + + RequesterClass: ClassVar[Type["Requester"]] = MockRequester + + WorkerClass: ClassVar[Type["Worker"]] = MockWorker + + AgentClass: ClassVar[Type["Agent"]] = MockAgent + + ArgsClass = MockProviderArgs + + SUPPORTED_TASK_TYPES: ClassVar[List[str]] = ["mock"] + + PROVIDER_TYPE = PROVIDER_TYPE + + curr_db_location: ClassVar[str] + + def initialize_provider_datastore(self, storage_path: str) -> Any: + """Mocks don't need any initialization""" + return MockDatastore(datastore_root=storage_path) + + def setup_resources_for_task_run( + self, + task_run: "TaskRun", + args: "DictConfig", + shared_state: "SharedTaskState", + server_url: str, + ) -> None: + """Mocks don't do any initialization""" + return None + + def cleanup_resources_from_task_run( + self, task_run: "TaskRun", server_url: str + ) -> None: + """Mocks don't do any initialization""" + return None + + @classmethod + def get_wrapper_js_path(cls): + """ + Return the path to the `wrap_crowd_source.js` file for this + provider to be deployed to the server + """ + return os.path.join(os.path.dirname(__file__), "wrap_crowd_source.js") diff --git a/mephisto/abstractions/providers/mock/mock_requester.py b/mephisto/abstractions/providers/mock/mock_requester.py new file mode 100644 index 000000000..1cd0dbd25 --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_requester.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +# 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. + +from dataclasses import dataclass, field +from mephisto.data_model.requester import Requester, RequesterArgs +from mephisto.abstractions.providers.mock.provider_type import PROVIDER_TYPE + +from typing import Optional, Dict, List, Mapping, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.providers.mock.mock_datastore import MockDatastore + from argparse import _ArgumentGroup as ArgumentGroup + from omegaconf import DictConfig + +MOCK_BUDGET = 100000.0 + + +@dataclass +class MockRequesterArgs(RequesterArgs): + name: str = field( + default="MOCK_REQUESTER", + metadata={ + "help": "Name for the requester in the Mephisto DB.", + "required": True, + }, + ) + force_fail: bool = field( + default=False, metadata={"help": "Trigger a failed registration"} + ) + + +class MockRequester(Requester): + """ + High level class representing a requester on some kind of crowd provider. Sets some default + initializations, but mostly should be extended by the specific requesters for crowd providers + with whatever implementation details are required to get those to work. + """ + + ArgsClass = MockRequesterArgs + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MockDatastore" = db.get_datastore_for_provider(PROVIDER_TYPE) + + def register(self, args: Optional["DictConfig"] = None) -> None: + """Mock requesters don't actually register credentials""" + if args is not None: + if args.get("force_fail") is True: + raise Exception("Forced failure test exception was set") + else: + self.datastore.set_requester_registered(self.db_id, True) + + def is_registered(self) -> bool: + """Return the registration status""" + return self.datastore.get_requester_registered(self.db_id) + + def get_available_budget(self) -> float: + """MockRequesters have $100000 to spend""" + return MOCK_BUDGET + + def is_sandbox(self) -> bool: + """MockRequesters are for testing only, and are thus treated as sandbox""" + return True + + @staticmethod + def new(db: "MephistoDB", requester_name: str) -> "Requester": + return MockRequester._register_requester(db, requester_name, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mock/mock_unit.py b/mephisto/abstractions/providers/mock/mock_unit.py new file mode 100644 index 000000000..cfe1b58d7 --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_unit.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.assignment import Unit +from mephisto.data_model.constants.assignment_state import AssignmentState +from mephisto.abstractions.blueprint import AgentState + +from mephisto.abstractions.providers.mock.provider_type import PROVIDER_TYPE +from typing import List, Optional, Tuple, Dict, Mapping, Any, Type, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.assignment import Assignment + from mephisto.abstractions.providers.mock.mock_datastore import MockDatastore + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + + +class MockUnit(Unit): + """ + This class tracks the status of an individual worker's contribution to a + higher level assignment. It is the smallest 'unit' of work to complete + the assignment, and this class is only responsible for checking + the status of that work itself being done. + + It should be extended for usage with a specific crowd provider + """ + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MockDatastore" = db.get_datastore_for_provider(PROVIDER_TYPE) + + def launch(self, task_url: str) -> None: + """Mock launches do nothing right now beyond updating state""" + self.db.update_unit(self.db_id, status=AssignmentState.LAUNCHED) + + # TODO(OWN) get this link to the frontend + port = task_url.split(":")[1].split("/")[0] + print(task_url) + print( + f"Mock task launched: localhost:{port} for preview, " + f"localhost:{port}/?worker_id=x&assignment_id={self.db_id}" + ) + logger.info( + f"Mock task launched: localhost:{port} for preview, " + f"localhost:{port}/?worker_id=x&assignment_id={self.db_id} for assignment {self.assignment_id}" + ) + + return None + + def expire(self) -> float: + """Expiration is immediate on Mocks""" + self.db.update_unit(self.db_id, status=AssignmentState.EXPIRED) + self.datastore.set_unit_expired(self.db_id, True) + return 0.0 + + def is_expired(self) -> bool: + """Determine if this unit is expired as according to the vendor.""" + return self.datastore.get_unit_expired(self.db_id) + + @staticmethod + def new( + db: "MephistoDB", assignment: "Assignment", index: int, pay_amount: float + ) -> "Unit": + """Create a Unit for the given assignment""" + return MockUnit._register_unit(db, assignment, index, pay_amount, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mock/mock_worker.py b/mephisto/abstractions/providers/mock/mock_worker.py new file mode 100644 index 000000000..efbd08657 --- /dev/null +++ b/mephisto/abstractions/providers/mock/mock_worker.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.worker import Worker +from mephisto.abstractions.providers.mock.provider_type import PROVIDER_TYPE +from typing import List, Optional, Tuple, Dict, Mapping, Type, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Unit, Agent + from mephisto.data_model.requester import Requester + from mephisto.abstractions.providers.mock.mock_datastore import MockDatastore + + +class MockWorker(Worker): + """ + This class represents an individual - namely a person. It maintains components of ongoing identity for a user. + """ + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MockDatastore" = db.get_datastore_for_provider(PROVIDER_TYPE) + + def bonus_worker( + self, amount: float, reason: str, unit: Optional["Unit"] = None + ) -> Tuple[bool, str]: + """Bonus this worker for work any reason. Return success of bonus""" + return True, "" + + def block_worker( + self, + reason: str, + unit: Optional["Unit"] = None, + requester: Optional["Requester"] = None, + ) -> Tuple[bool, str]: + """Block this worker for a specified reason. Return success of block""" + self.datastore.set_worker_blocked(self.db_id, True) + return True, "" + + def unblock_worker(self, reason: str, requester: "Requester") -> bool: + """unblock a blocked worker for the specified reason. Return success of unblock""" + self.datastore.set_worker_blocked(self.db_id, False) + return True + + def is_blocked(self, requester: "Requester") -> bool: + """Determine if a worker is blocked""" + return self.datastore.get_worker_blocked(self.db_id) + + def is_eligible(self, task_run: "TaskRun") -> bool: + """Determine if this worker is eligible for the given task run""" + return True + + @staticmethod + def new(db: "MephistoDB", worker_id: str) -> "Worker": + return MockWorker._register_worker(db, worker_id, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mock/provider_type.py b/mephisto/abstractions/providers/mock/provider_type.py new file mode 100644 index 000000000..d044e6891 --- /dev/null +++ b/mephisto/abstractions/providers/mock/provider_type.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +# 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. + +PROVIDER_TYPE = "mock" diff --git a/mephisto/providers/mock/wrap_crowd_source.js b/mephisto/abstractions/providers/mock/wrap_crowd_source.js similarity index 100% rename from mephisto/providers/mock/wrap_crowd_source.js rename to mephisto/abstractions/providers/mock/wrap_crowd_source.js diff --git a/mephisto/abstractions/providers/mturk/__init__.py b/mephisto/abstractions/providers/mturk/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/providers/mturk/mturk_agent.py b/mephisto/abstractions/providers/mturk/mturk_agent.py new file mode 100644 index 000000000..c85617fcc --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_agent.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.agent import Agent +from mephisto.abstractions.blueprint import AgentState +from mephisto.abstractions.providers.mturk.provider_type import PROVIDER_TYPE +from mephisto.abstractions.providers.mturk.mturk_utils import ( + approve_work, + reject_work, + get_assignment, +) + +from typing import List, Optional, Tuple, Dict, Mapping, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.assignment import Unit + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.worker import Worker + from mephisto.data_model.packet import Packet + from mephisto.abstractions.providers.mturk.requester import MTurkRequester + from mephisto.abstractions.providers.mturk.unit import MTurkUnit + from mephisto.abstractions.providers.mturk.datastore import MTurkDatastore + + +class MTurkAgent(Agent): + """ + This class encompasses a worker as they are working on an individual assignment. + It maintains details for the current task at hand such as start and end time, + connection status, etc. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + unit: "MTurkUnit" = self.get_unit() + self.mturk_assignment_id = unit.get_mturk_assignment_id() + # TODO(#97) any additional init as is necessary once + # a mock DB exists + + def _get_mturk_assignment_id(self): + if self.mturk_assignment_id is None: + self.mturk_assignment_id = self.get_unit().get_mturk_assignment_id() + return self.mturk_assignment_id + + def _get_client(self) -> Any: + """ + Get an mturk client for usage with mturk_utils for this agent + """ + unit = self.get_unit() + requester: "MTurkRequester" = unit.get_requester() + return self.datastore.get_client_for_requester(requester._requester_name) + + @classmethod + def new_from_provider_data( + cls, + db: "MephistoDB", + worker: "Worker", + unit: "Unit", + provider_data: Dict[str, Any], + ) -> "Agent": + """ + Wrapper around the new method that allows registering additional + bookkeeping information from a crowd provider for this agent + """ + datastore: "MTurkDatastore" = db.get_datastore_for_provider(cls.PROVIDER_TYPE) + datastore.register_assignment_to_hit( + provider_data["hit_id"], unit.db_id, provider_data["assignment_id"] + ) + return super().new_from_provider_data(db, worker, unit, provider_data) + + # Required functions for Agent Interface + + def approve_work(self) -> None: + """Approve the work done on this specific Unit""" + client = self._get_client() + approve_work(client, self._get_mturk_assignment_id(), override_rejection=True) + self.update_status(AgentState.STATUS_APPROVED) + + def reject_work(self, reason) -> None: + """Reject the work done on this specific Unit""" + client = self._get_client() + reject_work(client, self._get_mturk_assignment_id(), reason) + self.update_status(AgentState.STATUS_REJECTED) + + def mark_done(self) -> None: + """ + MTurk agents are marked as done on the side of MTurk, so if this agent + is marked as done there's nothing else we need to do as the task has been + submitted. + """ + if self.get_status() != AgentState.STATUS_DISCONNECT: + self.db.update_agent( + agent_id=self.db_id, status=AgentState.STATUS_COMPLETED + ) + + @staticmethod + def new(db: "MephistoDB", worker: "Worker", unit: "Unit") -> "Agent": + """Create an agent for this worker to be used for work on the given Unit.""" + return MTurkAgent._register_agent(db, worker, unit, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mturk/mturk_datastore.py b/mephisto/abstractions/providers/mturk/mturk_datastore.py new file mode 100644 index 000000000..971b06918 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_datastore.py @@ -0,0 +1,289 @@ +#!/usr/bin/env python3 + +# 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 boto3 +import sqlite3 +import os +import threading + +from datetime import datetime + + +from botocore.exceptions import ClientError +from botocore.exceptions import ProfileNotFound + +from typing import Dict, Any, Optional + +MTURK_REGION_NAME = "us-east-1" + +CREATE_HITS_TABLE = """CREATE TABLE IF NOT EXISTS hits ( + hit_id TEXT PRIMARY KEY UNIQUE, + unit_id TEXT, + assignment_id TEXT, + link TEXT, + assignment_time_in_seconds INTEGER NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_RUN_MAP_TABLE = """CREATE TABLE IF NOT EXISTS run_mappings ( + hit_id TEXT, + run_id TEXT +); +""" + +CREATE_RUNS_TABLE = """CREATE TABLE IF NOT EXISTS runs ( + run_id TEXT PRIMARY KEY UNIQUE, + arn_id TEXT, + hit_type_id TEXT NOT NULL, + hit_config_path TEXT NOT NULL, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + +CREATE_QUALIFICATIONS_TABLE = """CREATE TABLE IF NOT EXISTS qualifications ( + qualification_name TEXT PRIMARY KEY UNIQUE, + requester_id TEXT, + mturk_qualification_name TEXT, + mturk_qualification_id TEXT, + creation_date DATETIME DEFAULT CURRENT_TIMESTAMP +); +""" + + +class MTurkDatastore: + """ + Handles storing multiple sessions for different requesters + across a single mephisto thread (locked to a MephistoDB). + Also creates a relevant tables for mapping between MTurk + and mephisto. + """ + + def __init__(self, datastore_root: str): + """Initialize the session storage to empty, initialize tables if needed""" + self.session_storage: Dict[str, boto3.Session] = {} + self.table_access_condition = threading.Condition() + self.conn: Dict[int, sqlite3.Connection] = {} + self.db_path = os.path.join(datastore_root, "mturk.db") + self.init_tables() + self.datastore_root = datastore_root + + def _get_connection(self) -> sqlite3.Connection: + """Returns a singular database connection to be shared amongst all + calls for a given thread. + """ + # TODO(#101) is there a problem with having just one db connection? + # Will this cause bugs with failed commits? + curr_thread = threading.get_ident() + if curr_thread not in self.conn or self.conn[curr_thread] is None: + conn = sqlite3.connect(self.db_path) + conn.row_factory = sqlite3.Row + self.conn[curr_thread] = conn + return self.conn[curr_thread] + + def init_tables(self) -> None: + """ + Run all the table creation SQL queries to ensure the expected tables exist + """ + with self.table_access_condition: + conn = self._get_connection() + conn.execute("PRAGMA foreign_keys = 1") + with conn: + c = conn.cursor() + c.execute(CREATE_HITS_TABLE) + c.execute(CREATE_RUNS_TABLE) + c.execute(CREATE_RUN_MAP_TABLE) + c.execute(CREATE_QUALIFICATIONS_TABLE) + + def new_hit(self, hit_id: str, hit_link: str, duration: int, run_id: str) -> None: + """Register a new HIT mapping in the table""" + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """INSERT INTO hits( + hit_id, + link, + assignment_time_in_seconds + ) VALUES (?, ?, ?);""", + (hit_id, hit_link, duration), + ) + c.execute( + """INSERT INTO run_mappings( + hit_id, + run_id + ) VALUES (?, ?);""", + (hit_id, run_id), + ) + + def get_unassigned_hit_ids(self, run_id: str): + """ + Return a list of all HIT ids that haven't been assigned + """ + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT + hit_id, + unit_id, + run_id + FROM + hits + INNER JOIN run_mappings + USING (hit_id) + WHERE unit_id IS NULL + AND run_id = ?; + """, + (run_id,), + ) + results = c.fetchall() + return [r["hit_id"] for r in results] + + def register_assignment_to_hit( + self, + hit_id: str, + unit_id: Optional[str] = None, + assignment_id: Optional[str] = None, + ) -> None: + """ + Register a specific assignment and hit to the given unit, + or clear the assignment after a return + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """UPDATE hits + SET assignment_id = ?, unit_id = ? + WHERE hit_id = ? + """, + (assignment_id, unit_id, hit_id), + ) + + def get_hit_mapping(self, unit_id: str) -> sqlite3.Row: + """Get the mapping between Mephisto IDs and MTurk ids""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from hits + WHERE unit_id = ? + """, + (unit_id,), + ) + results = c.fetchall() + return results[0] + + def register_run( + self, run_id: str, arn_id: str, hit_type_id: str, hit_config_path: str + ) -> None: + """Register a new task run in the mturk table""" + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """INSERT INTO runs( + run_id, + arn_id, + hit_type_id, + hit_config_path + ) VALUES (?, ?, ?, ?);""", + (run_id, arn_id, hit_type_id, hit_config_path), + ) + + def get_run(self, run_id: str) -> sqlite3.Row: + """Get the details for a run by task_run_id""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from runs + WHERE run_id = ? + """, + (run_id,), + ) + results = c.fetchall() + return results[0] + + def create_qualification_mapping( + self, + qualification_name: str, + requester_id: str, + mturk_qualification_name: str, + mturk_qualification_id: str, + ) -> None: + """ + Create a mapping between mephisto qualification name and mturk + qualification details in the local datastore + """ + with self.table_access_condition, self._get_connection() as conn: + c = conn.cursor() + c.execute( + """INSERT INTO qualifications( + qualification_name, + requester_id, + mturk_qualification_name, + mturk_qualification_id + ) VALUES (?, ?, ?, ?);""", + ( + qualification_name, + requester_id, + mturk_qualification_name, + mturk_qualification_id, + ), + ) + return None + + def get_qualification_mapping( + self, qualification_name: str + ) -> Optional[sqlite3.Row]: + """Get the mapping between Mephisto qualifications and MTurk qualifications""" + with self.table_access_condition: + conn = self._get_connection() + c = conn.cursor() + c.execute( + """ + SELECT * from qualifications + WHERE qualification_name = ? + """, + (qualification_name,), + ) + results = c.fetchall() + if len(results) == 0: + return None + return results[0] + + def get_session_for_requester(self, requester_name: str) -> boto3.Session: + """ + Either create a new session for the given requester or return + the existing one if it has already been created + """ + if requester_name not in self.session_storage: + session = boto3.Session( + profile_name=requester_name, region_name=MTURK_REGION_NAME + ) + self.session_storage[requester_name] = session + + return self.session_storage[requester_name] + + def get_client_for_requester(self, requester_name: str) -> Any: + """ + Return the client for the given requester, which should allow + direct calls to the mturk surface + """ + return self.get_session_for_requester(requester_name).client("mturk") + + def get_sandbox_client_for_requester(self, requester_name: str) -> Any: + """ + Return the client for the given requester, which should allow + direct calls to the mturk surface + """ + return self.get_session_for_requester(requester_name).client( + service_name="mturk", + region_name="us-east-1", + endpoint_url="https://mturk-requester-sandbox.us-east-1.amazonaws.com", + ) diff --git a/mephisto/abstractions/providers/mturk/mturk_provider.py b/mephisto/abstractions/providers/mturk/mturk_provider.py new file mode 100644 index 000000000..4979192c7 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_provider.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 + +# 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 os +from mephisto.data_model.task_config import TaskConfig +from mephisto.abstractions.providers.mturk.provider_type import PROVIDER_TYPE +from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore +from mephisto.abstractions.crowd_provider import CrowdProvider, ProviderArgs +from mephisto.data_model.requester import RequesterArgs +from mephisto.abstractions.providers.mturk.mturk_agent import MTurkAgent +from mephisto.abstractions.providers.mturk.mturk_requester import MTurkRequester +from mephisto.abstractions.providers.mturk.mturk_unit import MTurkUnit +from mephisto.abstractions.providers.mturk.mturk_worker import MTurkWorker +from mephisto.abstractions.providers.mturk.mturk_utils import ( + create_hit_type, + create_hit_config, + setup_sns_topic, + delete_sns_topic, + delete_qualification, +) +from mephisto.operations.registry import register_mephisto_abstraction +from dataclasses import dataclass, field + +from typing import ClassVar, Dict, Any, Optional, Type, List, cast, TYPE_CHECKING + +from mephisto.data_model.requester import Requester + +if TYPE_CHECKING: + from mephisto.abstractions.blueprint import SharedTaskState + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Unit + from mephisto.data_model.worker import Worker + from mephisto.data_model.agent import Agent + from omegaconf import DictConfig + + +@dataclass +class MTurkProviderArgs(ProviderArgs): + """Provider args for an MTurk provider""" + + _provider_type: str = PROVIDER_TYPE + + +@register_mephisto_abstraction() +class MTurkProvider(CrowdProvider): + """ + Implementation of a crowdprovider that interfaces with MTurk + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + UnitClass: ClassVar[Type["Unit"]] = MTurkUnit + + RequesterClass: ClassVar[Type["Requester"]] = MTurkRequester + + WorkerClass: ClassVar[Type["Worker"]] = MTurkWorker + + AgentClass: ClassVar[Type["Agent"]] = MTurkAgent + + ArgsClass = MTurkProviderArgs + + SUPPORTED_TASK_TYPES: ClassVar[List[str]] = [ + # TODO + ] + + def initialize_provider_datastore(self, storage_path: str) -> Any: + """ + MTurk itself is the source of truth for most data required to run + tasks on MTurk. The datastore holds sessions to connect with + MTurk as well as mappings between MTurk ids and Mephisto ids + """ + return MTurkDatastore(datastore_root=storage_path) + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_client_for_requester(requester_name) + + def setup_resources_for_task_run( + self, + task_run: "TaskRun", + args: "DictConfig", + shared_state: "SharedTaskState", + server_url: str, + ) -> None: + """ + Set up SNS queue to recieve agent events from MTurk, and produce the + HIT type for this task run. + """ + requester = cast("MTurkRequester", task_run.get_requester()) + session = self.datastore.get_session_for_requester(requester._requester_name) + task_config = task_run.get_task_config() + + # Set up SNS queue + # TODO(OWN) implement arn? + task_run_id = task_run.db_id + # task_name = task_run.get_task().task_name + # arn_id = setup_sns_topic(session, task_name, server_url, task_run_id) + arn_id = "TEST" + + # Set up HIT config + config_dir = os.path.join(self.datastore.datastore_root, task_run_id) + task_config = TaskConfig(task_run) + + # Find or create relevant qualifications + qualifications = [] + for qualification in shared_state.qualifications: + applicable_providers = qualification["applicable_providers"] + if ( + applicable_providers is None + or self.PROVIDER_TYPE in applicable_providers + ): + qualifications.append(qualification) + for qualification in qualifications: + qualification_name = qualification["qualification_name"] + if requester.PROVIDER_TYPE == "mturk_sandbox": + qualification_name += "_sandbox" + if self.datastore.get_qualification_mapping(qualification_name) is None: + qualification[ + "QualificationTypeId" + ] = requester._create_new_mturk_qualification(qualification_name) + + if hasattr(shared_state, "mturk_specific_qualifications"): + qualifications += shared_state.mturk_specific_qualifications + + # Set up HIT type + client = self._get_client(requester._requester_name) + hit_type_id = create_hit_type(client, task_config, qualifications) + self.datastore.register_run(task_run_id, arn_id, hit_type_id, config_dir) + + def cleanup_resources_from_task_run( + self, task_run: "TaskRun", server_url: str + ) -> None: + """Shut down the SNS queue for this task.""" + requester = cast("MTurkRequester", task_run.get_requester()) + session = self.datastore.get_session_for_requester(requester._requester_name) + run_row = self.datastore.get_run(task_run.db_id) + delete_sns_topic(session, run_row["arn_id"]) + + @classmethod + def get_wrapper_js_path(cls): + """ + Return the path to the `wrap_crowd_source.js` file for this + provider to be deployed to the server + """ + return os.path.join(os.path.dirname(__file__), "wrap_crowd_source.js") + + def cleanup_qualification(self, qualification_name: str) -> None: + """Remove the qualification from the sandbox server, if it exists""" + mapping = self.datastore.get_qualification_mapping(qualification_name) + if mapping is None: + return None + + requester_id = mapping["requester_id"] + requester = Requester(self.db, requester_id) + assert isinstance(requester, MTurkRequester), "Must be an mturk requester" + client = requester._get_client(requester._requester_name) + delete_qualification(client, mapping["mturk_qualification_id"]) diff --git a/mephisto/abstractions/providers/mturk/mturk_requester.py b/mephisto/abstractions/providers/mturk/mturk_requester.py new file mode 100644 index 000000000..26b3e70ec --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_requester.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 + +# 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. + +from uuid import uuid4 +import time +import random + +from dataclasses import dataclass, field +from omegaconf import MISSING, DictConfig +from mephisto.data_model.requester import Requester, RequesterArgs +from mephisto.abstractions.providers.mturk.mturk_utils import ( + setup_aws_credentials, + get_requester_balance, + check_aws_credentials, + find_or_create_qualification, +) +from mephisto.abstractions.providers.mturk.provider_type import PROVIDER_TYPE + +from typing import List, Optional, Mapping, Dict, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.task_run import TaskRun + from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore + from argparse import _ArgumentGroup as ArgumentGroup + + +MAX_QUALIFICATION_ATTEMPTS = 300 + + +@dataclass +class MTurkRequesterArgs(RequesterArgs): + _group: str = field( + default="MTurkRequester", + metadata={ + "help": ( + "AWS is required to create a new Requester. " + "Please create an IAM user with programmatic access and " + "AmazonMechanicalTurkFullAccess policy at " + 'https://console.aws.amazon.com/iam/ (On the "Set permissions" ' + 'page, choose "Attach existing policies directly" and then select ' + '"AmazonMechanicalTurkFullAccess" policy). After creating ' + "the IAM user, you should get an Access Key ID " + "and Secret Access Key. " + ) + }, + ) + access_key_id: str = field( + default=MISSING, metadata={"required": True, "help": "IAM Access Key ID"} + ) + secret_access_key: str = field( + default=MISSING, metadata={"required": True, "help": "IAM Secret Access Key"} + ) + + +class MTurkRequester(Requester): + """ + Wrapper for requester behavior as provided by MTurk. Makes + all requests directly to MTurk through boto3. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + ArgsClass = MTurkRequesterArgs + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + # Use _requester_name to preserve sandbox behavior which + # utilizes a different requester_name + self._requester_name = self.requester_name + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_client_for_requester(requester_name) + + # Required functions for a Requester implementation + + def register(self, args: Optional[DictConfig] = None) -> None: + """ + Register this requester with the crowd provider by providing any required credentials + or such. If no args are provided, assume the registration is already made and try + to assert it as such. + """ + for req_field in ["access_key_id", "secret_access_key"]: + if args is not None and req_field not in args: + raise Exception( + f'Missing IAM "{req_field}" in requester registration args' + ) + setup_aws_credentials(self._requester_name, args) + + def is_registered(self) -> bool: + """Return whether or not this requester has registered yet""" + return check_aws_credentials(self._requester_name) + + def get_available_budget(self) -> float: + """Get the available budget from MTurk""" + client = self._get_client(self._requester_name) + return get_requester_balance(client) + + def _create_new_mturk_qualification(self, qualification_name: str) -> str: + """ + Create a new qualification on MTurk owned by the requester provided + """ + client = self._get_client(self._requester_name) + qualification_desc = f"Equivalent qualification for {qualification_name}." + use_qualification_name = qualification_name + qualification_id = find_or_create_qualification( + client, qualification_name, qualification_desc, must_be_owned=True + ) + if qualification_id is None: + # Try to append time to make the qualification unique + use_qualification_name = f"{qualification_name}_{time.time()}" + qualification_id = find_or_create_qualification( + client, use_qualification_name, qualification_desc, must_be_owned=True + ) + attempts = 0 + while qualification_id is None: + # Append something somewhat random + use_qualification_name = f"{qualification_name}_{str(uuid4())}" + qualification_id = find_or_create_qualification( + client, + use_qualification_name, + qualification_desc, + must_be_owned=True, + ) + attempts += 1 + if attempts > MAX_QUALIFICATION_ATTEMPTS: + raise Exception( + "Something has gone extremely wrong with creating qualification " + f"{qualification_name} for requester {self.requester_name}" + ) + # Store the new qualification in the datastore + self.datastore.create_qualification_mapping( + qualification_name, self.db_id, use_qualification_name, qualification_id + ) + return qualification_id + + @staticmethod + def new(db: "MephistoDB", requester_name: str) -> "Requester": + return MTurkRequester._register_requester(db, requester_name, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mturk/mturk_unit.py b/mephisto/abstractions/providers/mturk/mturk_unit.py new file mode 100644 index 000000000..631984d3d --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_unit.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 + +# 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. + +from datetime import datetime + +from mephisto.data_model.assignment import Unit +from mephisto.data_model.constants.assignment_state import AssignmentState +from mephisto.abstractions.blueprint import AgentState +from mephisto.abstractions.providers.mturk.mturk_utils import ( + expire_hit, + get_hit, + create_hit_with_hit_type, +) +from mephisto.abstractions.providers.mturk.provider_type import PROVIDER_TYPE +from typing import List, Optional, Tuple, Mapping, Dict, Any, Type, cast, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.assignment import Assignment + from mephisto.abstractions.providers.mturk.mturk_requester import MTurkRequester + from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + + +class MTurkUnit(Unit): + """ + This class tracks the status of an individual worker's contribution to a + higher level assignment. It is the smallest 'unit' of work to complete + the assignment, and this class is only responsible for checking + the status of that work itself being done. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + self.hit_id: Optional[str] = None + self._sync_hit_mapping() + self.__requester: Optional["MTurkRequester"] = None + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_client_for_requester(requester_name) + + def _sync_hit_mapping(self) -> None: + """Sync with the datastore to see if any mappings have updated""" + try: + mapping = dict(self.datastore.get_hit_mapping(self.db_id)) + self.hit_id = mapping["hit_id"] + self.mturk_assignment_id = mapping.get("assignment_id") + self.assignment_time_in_seconds = mapping.get("assignment_time_in_seconds") + except IndexError: + # HIT does not appear to exist + self.hit_id = None + self.mturk_assignment_id = None + self.assignment_time_in_seconds = -1 + + def get_mturk_assignment_id(self) -> Optional[str]: + """ + Return the MTurk assignment id associated with this unit + """ + if self.mturk_assignment_id is None: + self._sync_hit_mapping() + return self.mturk_assignment_id + + def get_mturk_hit_id(self) -> Optional[str]: + """ + Return the MTurk hit id associated with this unit + """ + if self.hit_id is None: + self._sync_hit_mapping() + return self.hit_id + + def get_requester(self) -> "MTurkRequester": + """Wrapper around regular Requester as this will be MTurkRequesters""" + if self.__requester is None: + self.__requester = cast("MTurkRequester", super().get_requester()) + return self.__requester + + def clear_assigned_agent(self) -> None: + """ + Additionally to clearing the agent, we also need to dissociate the + hit_id from this unit in the MTurkDatastore + """ + super().clear_assigned_agent() + mturk_hit_id = self.get_mturk_hit_id() + if mturk_hit_id is not None: + self.datastore.register_assignment_to_hit(mturk_hit_id) + self._sync_hit_mapping() + + # Required Unit functions + + def get_status(self) -> str: + """Get status for this unit directly from MTurk, fall back on local info""" + if self.db_status in [ + AssignmentState.CREATED, + AssignmentState.ACCEPTED, + AssignmentState.EXPIRED, + AssignmentState.SOFT_REJECTED, + ]: + # These statuses don't change with a get_status call + return self.db_status + + if self.db_status in [AssignmentState.COMPLETED, AssignmentState.REJECTED]: + # These statuses only change on agent dependent changes + agent = self.get_assigned_agent() + found_status = self.db_status + if agent is not None: + agent_status = agent.get_status() + if agent_status == AgentState.STATUS_APPROVED: + found_status = AssignmentState.ACCEPTED + elif agent_status == AgentState.STATUS_REJECTED: + found_status = AssignmentState.REJECTED + elif agent_status == AgentState.STATUS_SOFT_REJECTED: + found_status = AssignmentState.SOFT_REJECTED + else: + logger.warning("Agent is None") + if found_status != self.db_status: + self.set_db_status(found_status) + return self.db_status + + # Remaining statuses are tracking a live HIT + + mturk_hit_id = self.get_mturk_hit_id() + if mturk_hit_id is None: + # Can't determine anything if there is no HIT on this assignment + return self.db_status + + requester = self.get_requester() + client = self._get_client(requester._requester_name) + hit = get_hit(client, mturk_hit_id) + hit_data = hit["HIT"] + + local_status = self.db_status + external_status = self.db_status + + if hit_data["HITStatus"] == "Assignable": + external_status = AssignmentState.LAUNCHED + elif hit_data["HITStatus"] == "Unassignable": + external_status = AssignmentState.ASSIGNED + elif hit_data["HITStatus"] in ["Reviewable", "Reviewing"]: + external_status = AssignmentState.COMPLETED + if hit_data["NumberOfAssignmentsAvailable"] != 0: + external_status = AssignmentState.EXPIRED + elif hit_data["HITStatus"] == "Disposed": + # The HIT was deleted, must rely on what we have + external_status = local_status + else: + raise Exception(f"Unexpected HIT status {hit_data['HITStatus']}") + + if external_status != local_status: + if ( + local_status == AssignmentState.ASSIGNED + and external_status == AssignmentState.LAUNCHED + ): + # Treat this as a return event, this hit is now doable by someone else + agent = self.get_assigned_agent() + if agent is not None: + # mark the agent as having returned the HIT, to + # free any running tasks and have Blueprint decide on cleanup. + agent.update_status(AgentState.STATUS_RETURNED) + self.set_db_status(external_status) + + return self.db_status + + def launch(self, task_url: str) -> None: + """Create this HIT on MTurk (making it availalbe) and register the ids in the local db""" + task_run = self.get_assignment().get_task_run() + duration = task_run.get_task_config().assignment_duration_in_seconds + run_id = task_run.db_id + hit_type_id = self.datastore.get_run(run_id)["hit_type_id"] + requester = self.get_requester() + client = self._get_client(requester._requester_name) + frame_height = 650 + hit_link, hit_id, response = create_hit_with_hit_type( + client, frame_height, task_url, hit_type_id + ) + # TODO(OWN) get this link to the frontend + print(hit_link) + + # We create a hit for this unit, but note that this unit may not + # necessarily match with the same HIT that was launched for it. + self.datastore.new_hit(hit_id, hit_link, duration, run_id) + self.set_db_status(AssignmentState.LAUNCHED) + return None + + def expire(self) -> float: + """ + Send a request to expire the HIT, and if it's not assigned return, + otherwise just return the maximum assignment duration + """ + delay = 0 + if self.get_status() == AssignmentState.ASSIGNED: + # The assignment is currently being worked on, + # so we will set the wait time to be the + # amount of time we granted for working on this assignment + if self.assignment_time_in_seconds is not None: + delay = self.assignment_time_in_seconds + mturk_hit_id = self.get_mturk_hit_id() + requester = self.get_requester() + client = self._get_client(requester._requester_name) + if mturk_hit_id is not None: + expire_hit(client, mturk_hit_id) + return delay + else: + unassigned_hit_ids = self.datastore.get_unassigned_hit_ids(self.task_run_id) + + if len(unassigned_hit_ids) == 0: + logger.warning( + f"Number of unassigned hit IDs more than 1; Potential RACE CONDITION" + ) + return delay + hit_id = unassigned_hit_ids[0] + expire_hit(client, hit_id) + self.datastore.register_assignment_to_hit(hit_id, self.db_id) + self.set_db_status(AssignmentState.EXPIRED) + return delay + + def is_expired(self) -> bool: + """ + Determine if this unit is expired as according to the vendor. + + In this case, we keep track of the expiration locally by refreshing + the hit's status and seeing if we've expired. + """ + return self.get_status() == AssignmentState.EXPIRED + + @staticmethod + def new( + db: "MephistoDB", assignment: "Assignment", index: int, pay_amount: float + ) -> "Unit": + """Create a Unit for the given assignment""" + return MTurkUnit._register_unit( + db, assignment, index, pay_amount, PROVIDER_TYPE + ) diff --git a/mephisto/abstractions/providers/mturk/mturk_utils.py b/mephisto/abstractions/providers/mturk/mturk_utils.py new file mode 100644 index 000000000..8576af911 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_utils.py @@ -0,0 +1,704 @@ +#!/usr/bin/env python3 + +# 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 boto3 +import os +import json +import re +from typing import Dict, Optional, Tuple, List, Any, TYPE_CHECKING +from datetime import datetime + +from botocore import client +from botocore.exceptions import ClientError +from botocore.exceptions import ProfileNotFound +from botocore.config import Config +from omegaconf import DictConfig + +from mephisto.operations.logger_core import get_logger +from mephisto.operations.config_handler import get_config_arg + +logger = get_logger(name=__name__, verbose=True, level="info") + +if TYPE_CHECKING: + from mephisto.data_model.task_config import TaskConfig + +MTURK_TASK_FEE = 0.2 +MTURK_BONUS_FEE = 0.2 +SANDBOX_ENDPOINT = "https://mturk-requester-sandbox.us-east-1.amazonaws.com" + +MTurkClient = Any + +MTURK_LOCALE_REQUIREMENT = "00000000000000000071" + +botoconfig = Config(retries=dict(max_attempts=10)) + + +def client_is_sandbox(client: MTurkClient) -> bool: + """ + Determine if the given client is communicating with + the live server or a sandbox + """ + return client.meta.endpoint_url == SANDBOX_ENDPOINT + + +def check_aws_credentials(profile_name: str) -> bool: + try: + # Check existing credentials + boto3.Session(profile_name=profile_name) + return True + except ProfileNotFound: + return False + + +def setup_aws_credentials( + profile_name: str, register_args: Optional[DictConfig] = None +) -> bool: + try: + # Check existing credentials + boto3.Session(profile_name=profile_name) + return True + except ProfileNotFound: + # Setup new credentials + if register_args is not None: + aws_access_key_id = register_args.access_key_id + aws_secret_access_key = register_args.secret_access_key + else: + print( + f"AWS credentials for {profile_name} not found. Please create " + "an IAM user with " + "programmatic access and AdministratorAccess policy at " + 'https://console.aws.amazon.com/iam/ (On the "Set permissions" ' + 'page, choose "Attach existing policies directly" and then select ' + '"AdministratorAccess" policy). After creating the IAM user, ' + "please enter the user's Access Key ID and Secret Access " + "Key below:" + ) + aws_access_key_id = input("Access Key ID: ") + aws_secret_access_key = input("Secret Access Key: ") + if not os.path.exists(os.path.expanduser("~/.aws/")): + os.makedirs(os.path.expanduser("~/.aws/")) + aws_credentials_file_path = "~/.aws/credentials" + aws_credentials_file_string = None + expanded_aws_file_path = os.path.expanduser(aws_credentials_file_path) + if os.path.exists(expanded_aws_file_path): + with open(expanded_aws_file_path, "r") as aws_credentials_file: + aws_credentials_file_string = aws_credentials_file.read() + with open(expanded_aws_file_path, "a+") as aws_credentials_file: + # Clean up file + if aws_credentials_file_string: + if aws_credentials_file_string.endswith("\n\n"): + pass + elif aws_credentials_file_string.endswith("\n"): + aws_credentials_file.write("\n") + else: + aws_credentials_file.write("\n\n") + # Write login details + aws_credentials_file.write("[{}]\n".format(profile_name)) + aws_credentials_file.write( + "aws_access_key_id={}\n".format(aws_access_key_id) + ) + aws_credentials_file.write( + "aws_secret_access_key={}\n".format(aws_secret_access_key) + ) + print( + "AWS credentials successfully saved in {} file.\n".format( + aws_credentials_file_path + ) + ) + return True + + +def calculate_mturk_task_fee(task_amount: float) -> float: + """ + MTurk Pricing: https://requester.mturk.com/pricing + 20% fee on the reward and bonus amount (if any) you pay Workers. + """ + return MTURK_TASK_FEE * task_amount + + +def calculate_mturk_bonus_fee(bonus_amount: float) -> float: + """ + MTurk Pricing: https://requester.mturk.com/pricing + 20% fee on the reward and bonus amount (if any) you pay Workers. + """ + return MTURK_TASK_FEE * bonus_amount + + +def get_requester_balance(client: MTurkClient) -> float: + """Get the balance for the requester associated with this client""" + return float(client.get_account_balance()["AvailableBalance"]) + + +def check_mturk_balance(client: MTurkClient, balance_needed: float): + """Checks to see if there is at least balance_needed amount in the + requester account, returns True if the balance is greater than + balance_needed + """ + # Test that you can connect to the API by checking your account balance + # In Sandbox this always returns $10,000 + try: + user_balance = float(client.get_account_balance()["AvailableBalance"]) + except ClientError as e: + if e.response["Error"]["Code"] == "RequestError": + print( + "ERROR: To use the MTurk API, you will need an Amazon Web " + "Services (AWS) Account. Your AWS account must be linked to " + "your Amazon Mechanical Turk Account. Visit " + "https://requestersandbox.mturk.com/developer to get started. " + "(Note: if you have recently linked your account, please wait " + "for a couple minutes before trying again.)\n" + ) + quit() + else: + raise + + if user_balance < balance_needed: + print( + "You might not have enough money in your MTurk account. Please go " + "to https://requester.mturk.com/account and increase your balance " + "to at least ${}, and then try again.".format(balance_needed) + ) + return False + else: + return True + + +def create_hit_config( + opt: Dict[str, Any], task_description: str, unique_worker: bool, is_sandbox: bool +) -> None: + """Writes a HIT config to file""" + mturk_submit_url = "https://workersandbox.mturk.com/mturk/externalSubmit" + if not is_sandbox: + mturk_submit_url = "https://www.mturk.com/mturk/externalSubmit" + hit_config = { + "task_description": task_description, + "is_sandbox": is_sandbox, + "mturk_submit_url": mturk_submit_url, + "unique_worker": unique_worker, + "frame_height": opt.get("frame_height", 650), + "allow_reviews": opt.get("allow_reviews", False), + "block_mobile": opt.get("block_mobile", True), + # Populate the chat pane title from chat_title, defaulting to the + # hit_title if the task provides no chat_title + "chat_title": opt.get("chat_title", opt.get("hit_title", "Live Chat")), + "template_type": opt.get("frontend_template_type", "default"), + } + hit_config_file_path = os.path.join(opt["tmp_dir"], "hit_config.json") + if os.path.exists(hit_config_file_path): + os.remove(hit_config_file_path) + with open(hit_config_file_path, "w") as hit_config_file: + hit_config_file.write(json.dumps(hit_config)) + + +def delete_qualification(client: MTurkClient, qualification_id: str) -> None: + """Deletes a qualification by id""" + client.delete_qualification_type(QualificationTypeId=qualification_id) + + +def find_qualification( + client: MTurkClient, qualification_name: str, must_be_owned: bool = True +) -> Tuple[bool, Optional[str]]: + """Query amazon to find the existing qualification name, return the Id, + otherwise return none. + If must_be_owned is true, it only returns qualifications owned by the user. + Will return False if it finds another's qualification + + The return format is (meets_owner_constraint, qual_id) + """ + # Search for the qualification owned by the current user + response = client.list_qualification_types( + Query=qualification_name, MustBeRequestable=True, MustBeOwnedByCaller=True + ) + for qualification in response["QualificationTypes"]: + if qualification["Name"] == qualification_name: + return (True, qualification["QualificationTypeId"]) + + # Qualification was not found to exist, check to see if someone else has it + response = client.list_qualification_types( + Query=qualification_name, MustBeRequestable=True, MustBeOwnedByCaller=False + ) + + for qualification in response["QualificationTypes"]: + if qualification["Name"] == qualification_name: + if must_be_owned: + return (False, qualification["QualificationTypeId"]) + return (True, qualification["QualificationTypeId"]) + return (True, None) + + +def find_or_create_qualification( + client: MTurkClient, + qualification_name: str, + description: str, + must_be_owned: bool = True, +) -> Optional[str]: + """Query amazon to find the existing qualification name, return the Id. If + it exists and must_be_owned is true but we don't own it, this returns none. + If it doesn't exist, the qualification is created + """ + qual_usable, qual_id = find_qualification( + client, qualification_name, must_be_owned=must_be_owned + ) + + if qual_usable is False: + return None + + if qual_id is not None: + return qual_id + + # Create the qualification, as it doesn't exist yet + response = client.create_qualification_type( + Name=qualification_name, + Description=description, + QualificationTypeStatus="Active", + ) + return response["QualificationType"]["QualificationTypeId"] + + +def give_worker_qualification( + client: MTurkClient, + worker_id: str, + qualification_id: str, + value: Optional[int] = None, +) -> None: + """Give a qualification to the given worker""" + if value is not None: + client.associate_qualification_with_worker( + QualificationTypeId=qualification_id, + WorkerId=worker_id, + IntegerValue=value, + SendNotification=False, + ) + else: + client.associate_qualification_with_worker( + QualificationTypeId=qualification_id, + WorkerId=worker_id, + IntegerValue=1, + SendNotification=False, + ) + + +def remove_worker_qualification( + client: MTurkClient, worker_id: str, qualification_id: str, reason: str = "" +) -> None: + """Give a qualification to the given worker""" + client.disassociate_qualification_from_worker( + QualificationTypeId=qualification_id, WorkerId=worker_id, Reason=reason + ) + + +def convert_mephisto_qualifications( + client: MTurkClient, qualifications: List[Dict[str, Any]] +): + """Convert qualifications from mephisto's format to MTurk's""" + converted_qualifications = [] + for qualification in qualifications: + converted = {} + mturk_keys = [ + "QualificationTypeId", + "Comparator", + "IntegerValue", + "IntegerValues", + "LocaleValues", + "ActionsGuarded", + ] + for key in mturk_keys: + converted[key] = qualification.get(key) + + if converted["QualificationTypeId"] is None: + qualification_name = qualification["qualification_name"] + if client_is_sandbox(client): + qualification_name += "_sandbox" + qual_id = find_or_create_qualification( + client, + qualification_name, + "Qualification required for Mephisto-launched tasks", + False, + ) + if qual_id is None: + # TODO log more loudly that this qualification is being skipped? + print( + f"Qualification name {qualification_name} can not be found or created on MTurk" + ) + converted["QualificationTypeId"] = qual_id + + if converted["Comparator"] is None: + converted["Comparator"] = qualification["comparator"] + + # if no Mturk Values are set, pull from the qualification's value + if ( + converted["IntegerValue"] is None + and converted["IntegerValues"] is None + and converted["LocaleValues"] is None + ): + value = qualification["value"] + if isinstance(value, list): + converted["IntegerValues"] = value + elif isinstance(value, int): + converted["IntegerValue"] = value + + # IntegerValue is deprecated, and needs conversion to IntegerValues + if converted["IntegerValue"] is not None: + converted["IntegerValues"] = [converted["IntegerValue"]] + del converted["IntegerValue"] + + if converted["IntegerValues"] is None: + del converted["IntegerValues"] + + if converted["LocaleValues"] is None: + del converted["LocaleValues"] + + if converted["ActionsGuarded"] is None: + converted["ActionsGuarded"] = "DiscoverPreviewAndAccept" + + converted_qualifications.append(converted) + return converted_qualifications + + +def create_hit_type( + client: MTurkClient, + task_config: "TaskConfig", + qualifications: List[Dict[str, Any]], + auto_approve_delay: Optional[int] = 7 * 24 * 3600, # default 1 week +) -> str: + """Create a HIT type to be used to generate HITs of the requested params""" + hit_title = task_config.task_title + hit_description = task_config.task_description + hit_keywords = ",".join(task_config.task_tags) + hit_reward = task_config.task_reward + assignment_duration_in_seconds = task_config.assignment_duration_in_seconds + existing_qualifications = convert_mephisto_qualifications(client, qualifications) + + # If the user hasn't specified a location qualification, we assume to + # restrict the HIT to some english-speaking countries. + locale_requirements: List[Any] = [] + has_locale_qual = False + if existing_qualifications is not None: + for q in existing_qualifications: + if q["QualificationTypeId"] == MTURK_LOCALE_REQUIREMENT: + has_locale_qual = True + locale_requirements += existing_qualifications + + if not has_locale_qual and not client_is_sandbox(client): + allowed_locales = get_config_arg("mturk", "allowed_locales") + if allowed_locales is None: + allowed_locales = [ + {"Country": "US"}, + {"Country": "CA"}, + {"Country": "GB"}, + {"Country": "AU"}, + {"Country": "NZ"}, + ] + locale_requirements.append( + { + "QualificationTypeId": MTURK_LOCALE_REQUIREMENT, + "Comparator": "In", + "LocaleValues": allowed_locales, + "ActionsGuarded": "DiscoverPreviewAndAccept", + } + ) + + # Create the HIT type + response = client.create_hit_type( + AutoApprovalDelayInSeconds=auto_approve_delay, + AssignmentDurationInSeconds=assignment_duration_in_seconds, + Reward=str(hit_reward), + Title=hit_title, + Keywords=hit_keywords, + Description=hit_description, + QualificationRequirements=locale_requirements, + ) + hit_type_id = response["HITTypeId"] + return hit_type_id + + +def create_hit_with_hit_type( + client: MTurkClient, + frame_height: int, + page_url: str, + hit_type_id: str, + num_assignments: int = 1, +) -> Tuple[str, str, Dict[str, Any]]: + """Creates the actual HIT given the type and page to direct clients to""" + page_url = page_url.replace("&", "&") + amazon_ext_url = ( + "http://mechanicalturk.amazonaws.com/" + "AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd" + ) + question_data_struture = ( + '' + "{}" # noqa: E131 + "{}" + "" + "".format(amazon_ext_url, page_url, 650) + ) + + is_sandbox = client_is_sandbox(client) + + # Create the HIT + response = client.create_hit_with_hit_type( + HITTypeId=hit_type_id, + MaxAssignments=num_assignments, + LifetimeInSeconds=60 * 60 * 24 * 31, + Question=question_data_struture, + ) + + # The response included several fields that will be helpful later + hit_type_id = response["HIT"]["HITTypeId"] + hit_id = response["HIT"]["HITId"] + + # Construct the hit URL + url_target = "workersandbox" + if not is_sandbox: + url_target = "www" + hit_link = "https://{}.mturk.com/mturk/preview?groupId={}".format( + url_target, hit_type_id + ) + return hit_link, hit_id, response + + +def expire_hit(client: MTurkClient, hit_id: str): + # Update expiration to a time in the past, the HIT expires instantly + past_time = datetime(2015, 1, 1) + client.update_expiration_for_hit(HITId=hit_id, ExpireAt=past_time) + + +def setup_sns_topic( + session: boto3.Session, task_name: str, server_url: str, task_run_id: str +) -> str: + """Create an sns topic and return the arn identifier""" + # Create the topic and subscribe to it so that our server receives notifs + client = session.client("sns", region_name="us-east-1", config=botoconfig) + pattern = re.compile("[^a-zA-Z0-9_-]+") + filtered_task_name = pattern.sub("", task_name) + response = client.create_topic(Name=filtered_task_name) + arn = response["TopicArn"] + topic_sub_url = "{}/sns_posts?task_run_id={}".format(server_url, task_run_id) + client.subscribe(TopicArn=arn, Protocol="https", Endpoint=topic_sub_url) + response = client.get_topic_attributes(TopicArn=arn) + policy_json = """{{ + "Version": "2008-10-17", + "Id": "{}/MTurkOnlyPolicy", + "Statement": [ + {{ + "Sid": "MTurkOnlyPolicy", + "Effect": "Allow", + "Principal": {{ + "Service": "mturk-requester.amazonaws.com" + }}, + "Action": "SNS:Publish", + "Resource": "{}" + }} + ]}}""".format( + arn, arn + ) + client.set_topic_attributes( + TopicArn=arn, AttributeName="Policy", AttributeValue=policy_json + ) + return arn + + +def subscribe_to_hits(client: MTurkClient, hit_type_id: str, sns_arn: str) -> None: + """Subscribe an sns channel to the specific hit type""" + # Get the mturk client and create notifications for our hits + client.update_notification_settings( + HITTypeId=hit_type_id, + Notification={ + "Destination": sns_arn, + "Transport": "SNS", + "Version": "2006-05-05", + "EventTypes": [ + "AssignmentAbandoned", + "AssignmentReturned", + "AssignmentSubmitted", + ], + }, + Active=True, + ) + + +def send_test_notif(client: MTurkClient, topic_arn: str, event_type: str) -> None: + """ + Send a test notification of the given event type to the sns + queue associated with the given arn + """ + client.send_test_event_notification( + Notification={ + "Destination": topic_arn, + "Transport": "SNS", + "Version": "2006-05-05", + "EventTypes": [ + "AssignmentAbandoned", + "AssignmentReturned", + "AssignmentSubmitted", + ], + }, + TestEventType=event_type, + ) + + +def delete_sns_topic(session: boto3.Session, topic_arn: str) -> None: + """Remove the sns queue of the given identifier""" + client = session.client("sns", region_name="us-east-1", config=botoconfig) + client.delete_topic(TopicArn=topic_arn) + + +def get_hit(client: MTurkClient, hit_id: str) -> Dict[str, Any]: + """Get hit from mturk by hit_id""" + return client.get_hit(HITId=hit_id) + + +def get_assignment(client: MTurkClient, assignment_id: str) -> Dict[str, Any]: + """Gets assignment from mturk by assignment_id. Only works if the + assignment is in a completed state + """ + return client.get_assignment(AssignmentId=assignment_id) + + +def get_assignments_for_hit(client: MTurkClient, hit_id: str) -> List[Dict[str, Any]]: + """Get completed assignments for a hit""" + assignments_info = client.list_assignments_for_hit(HITId=hit_id) + return assignments_info.get("Assignments", []) + + +def approve_work( + client: MTurkClient, assignment_id: str, override_rejection: bool = False +) -> None: + """approve work for a given assignment through the mturk client""" + try: + client.approve_assignment( + AssignmentId=assignment_id, OverrideRejection=override_rejection + ) + except Exception as e: + # TODO(#93) Break down this error to the many reasons why approve may fail, + # only silently pass on approving an already approved assignment + logger.exception( + f"Approving MTurk assignment failed, likely because it has auto-approved. Details: {e}", + exc_info=True, + ) + + +def reject_work(client: MTurkClient, assignment_id: str, reason: str) -> None: + """reject work for a given assignment through the mturk client""" + try: + client.reject_assignment(AssignmentId=assignment_id, RequesterFeedback=reason) + except Exception as e: + # TODO(#93) Break down this error to the many reasons why approve may fail, + # only silently pass on approving an already approved assignment + logger.exception( + f"Rejecting MTurk assignment failed, likely because it has auto-approved. Details:{e}", + exc_info=True, + ) + + +def approve_assignments_for_hit( + client: MTurkClient, hit_id: str, override_rejection: bool = False +): + """Approve work for assignments associated with a given hit, through + mturk client + """ + assignments = get_assignments_for_hit(client, hit_id) + for assignment in assignments: + assignment_id = assignment["AssignmentId"] + client.approve_assignment( + AssignmentId=assignment_id, OverrideRejection=override_rejection + ) + + +def block_worker(client: MTurkClient, worker_id: str, reason: str) -> None: + """Block a worker by id using the mturk client, passes reason along""" + res = client.create_worker_block(WorkerId=worker_id, Reason=reason) + + +def unblock_worker(client: MTurkClient, worker_id: str, reason: str) -> None: + """Remove a block on the given worker""" + client.delete_worker_block(WorkerId=worker_id, Reason=reason) + + +def is_worker_blocked(client: MTurkClient, worker_id: str) -> bool: + """Determine if the given worker is blocked by this client""" + blocks = client.list_worker_blocks(MaxResults=100)["WorkerBlocks"] + blocked_ids = [x["WorkerId"] for x in blocks] + return worker_id in blocked_ids + + +def pay_bonus( + client: MTurkClient, + worker_id: str, + bonus_amount: float, + assignment_id: str, + reason: str, + unique_request_token: str, +) -> bool: + """Handles paying bonus to a Turker, fails for insufficient funds. + Returns True on success and False on failure + """ + total_cost = bonus_amount + calculate_mturk_bonus_fee(bonus_amount) + if not check_mturk_balance(client, balance_needed=total_cost): + print("Cannot pay bonus. Reason: Insufficient " "funds in your MTurk account.") + return False + + client.send_bonus( + WorkerId=worker_id, + BonusAmount=str(bonus_amount), + AssignmentId=assignment_id, + Reason=reason, + UniqueRequestToken=unique_request_token, + ) + + return True + + +def email_worker( + client: MTurkClient, worker_id: str, subject: str, message_text: str +) -> Tuple[bool, str]: + """Send an email to a worker through the mturk client""" + response = client.notify_workers( + Subject=subject, MessageText=message_text, WorkerIds=[worker_id] + ) + if len(response["NotifyWorkersFailureStatuses"]) > 0: + failure_message = response["NotifyWorkersFailureStatuses"][0] + return (False, failure_message["NotifyWorkersFailureMessage"]) + else: + return (True, "") + + +def get_outstanding_hits(client: MTurkClient) -> Dict[str, List[Dict[str, Any]]]: + """Return the HITs sorted by HITTypeId that are still on the MTurk Server""" + new_hits = client.list_hits(MaxResults=100) + all_hits = new_hits["HITs"] + while len(new_hits["HITs"]) > 0: + new_hits = client.list_hits(MaxResults=100, NextToken=new_hits["NextToken"]) + all_hits += new_hits["HITs"] + + hit_by_type: Dict[str, List[Dict[str, Any]]] = {} + for h in all_hits: + hit_type = h["HITTypeId"] + if hit_type not in hit_by_type: + hit_by_type[hit_type] = [] + hit_by_type[hit_type].append(h) + + return hit_by_type + + +def expire_and_dispose_hits( + client: MTurkClient, hits: List[Dict[str, Any]] +) -> List[Dict[str, Any]]: + """ + Loops over attempting to expire and dispose any hits in the hits list that can be disposed + + Returns any HITs that could not be disposed of + """ + non_disposed_hits = [] + for h in hits: + try: + client.delete_hit(HITId=h["HITId"]) + except: + client.update_expiration_for_hit( + HITId=h["HITId"], ExpireAt=datetime(2015, 1, 1) + ) + non_disposed_hits.append(h) + return non_disposed_hits diff --git a/mephisto/abstractions/providers/mturk/mturk_worker.py b/mephisto/abstractions/providers/mturk/mturk_worker.py new file mode 100644 index 000000000..243577fd6 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/mturk_worker.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.data_model.worker import Worker +from mephisto.data_model.requester import Requester +from mephisto.abstractions.providers.mturk.provider_type import PROVIDER_TYPE +from mephisto.abstractions.providers.mturk.mturk_utils import ( + pay_bonus, + block_worker, + unblock_worker, + is_worker_blocked, + give_worker_qualification, + remove_worker_qualification, +) +from mephisto.abstractions.providers.mturk.mturk_requester import MTurkRequester + +from uuid import uuid4 + +from typing import List, Optional, Tuple, Dict, Mapping, Any, cast, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.task_run import TaskRun + from mephisto.data_model.assignment import Unit + from mephisto.abstractions.providers.mturk.mturk_unit import MTurkUnit + from mephisto.abstractions.providers.mturk.mturk_requester import MTurkRequester + +from mephisto.operations.logger_core import get_logger + +logger = get_logger(name=__name__, verbose=True, level="info") + + +class MTurkWorker(Worker): + """ + This class represents an individual - namely a person. It maintains components of ongoing identity for a user. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + self._worker_name = self.worker_name # sandbox workers use a different name + + @classmethod + def get_from_mturk_worker_id( + cls, db: "MephistoDB", mturk_worker_id: str + ) -> Optional["MTurkWorker"]: + """Get the MTurkWorker from the given worker_id""" + if cls.PROVIDER_TYPE != PROVIDER_TYPE: + mturk_worker_id += "_sandbox" + workers = db.find_workers( + worker_name=mturk_worker_id, provider_type=cls.PROVIDER_TYPE + ) + if len(workers) == 0: + # TODO warn? + return None + return workers[0] + + def get_mturk_worker_id(self): + return self._worker_name + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_client_for_requester(requester_name) + + def grant_crowd_qualification( + self, qualification_name: str, value: int = 1 + ) -> None: + """ + Grant a qualification by the given name to this worker. Check the local + MTurk db to find the matching MTurk qualification to grant, and pass + that. If no qualification exists, try to create one. + + In creating a new qualification, Mephisto resolves the ambiguity over which + requester to associate that qualification with by using the FIRST requester + of the given account type (either `mturk` or `mturk_sandbox`) + """ + mturk_qual_details = self.datastore.get_qualification_mapping( + qualification_name + ) + if mturk_qual_details is not None: + requester = Requester(self.db, mturk_qual_details["requester_id"]) + qualification_id = mturk_qual_details["mturk_qualification_id"] + else: + target_type = ( + "mturk_sandbox" if qualification_name.endswith("sandbox") else "mturk" + ) + requester = self.db.find_requesters(provider_type=target_type)[0] + assert isinstance( + requester, MTurkRequester + ), "find_requesters must return mturk requester for given provider types" + qualification_id = requester._create_new_mturk_qualification( + qualification_name + ) + assert isinstance( + requester, MTurkRequester + ), "Must be an MTurk requester for MTurk quals" + client = self._get_client(requester._requester_name) + give_worker_qualification( + client, self.get_mturk_worker_id(), qualification_id, value + ) + return None + + def revoke_crowd_qualification(self, qualification_name: str) -> None: + """ + Revoke the qualification by the given name from this worker. Check the local + MTurk db to find the matching MTurk qualification to revoke, pass if + no such qualification exists. + """ + mturk_qual_details = self.datastore.get_qualification_mapping( + qualification_name + ) + if mturk_qual_details is None: + logger.error( + f"No locally stored MTurk qualification to revoke for name {qualification_name}" + ) + return None + + requester = Requester(self.db, mturk_qual_details["requester_id"]) + assert isinstance( + requester, MTurkRequester + ), "Must be an MTurk requester from MTurk quals" + client = self._get_client(requester._requester_name) + qualification_id = mturk_qual_details["mturk_qualification_id"] + remove_worker_qualification( + client, self.get_mturk_worker_id(), qualification_id + ) + return None + + def bonus_worker( + self, amount: float, reason: str, unit: Optional["Unit"] = None + ) -> Tuple[bool, str]: + """Bonus this worker for work any reason. Return tuple of success and failure message""" + if unit is None: + # TODO(WISH) implement + return False, "bonusing via compensation tasks not yet available" + + unit = cast("MTurkUnit", unit) + requester = unit.get_assignment().get_task_run().get_requester() + client = self._get_client(requester._requester_name) + mturk_assignment_id = unit.get_mturk_assignment_id() + assert mturk_assignment_id is not None, "Cannot bonus for a unit with no agent" + pay_bonus( + client, self._worker_name, amount, mturk_assignment_id, reason, str(uuid4()) + ) + return True, "" + + def block_worker( + self, + reason: str, + unit: Optional["Unit"] = None, + requester: Optional["Requester"] = None, + ) -> Tuple[bool, str]: + """Block this worker for a specified reason. Return success of block""" + if unit is None and requester is None: + # TODO(WISH) soft block from all requesters? Maybe have the master + # requester soft block? + return ( + False, + "Blocking without a unit or requester not yet supported for MTurkWorkers", + ) + elif unit is not None and requester is None: + requester = unit.get_assignment().get_task_run().get_requester() + requester = cast("MTurkRequester", requester) + client = self._get_client(requester._requester_name) + block_worker(client, self._worker_name, reason) + return True, "" + + def unblock_worker(self, reason: str, requester: "Requester") -> bool: + """unblock a blocked worker for the specified reason. Return success of unblock""" + requester = cast("MTurkRequester", requester) + client = self._get_client(requester._requester_name) + unblock_worker(client, self._worker_name, reason) + return True + + def is_blocked(self, requester: "Requester") -> bool: + """Determine if a worker is blocked""" + requester = cast("MTurkRequester", requester) + client = self._get_client(requester._requester_name) + return is_worker_blocked(client, self._worker_name) + + def is_eligible(self, task_run: "TaskRun") -> bool: + """ + Qualifications are handled primarily by MTurk, so if a worker is able to get + through to be able to access the task, they should be eligible + """ + return True + + @staticmethod + def new(db: "MephistoDB", worker_id: str) -> "Worker": + return MTurkWorker._register_worker(db, worker_id, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mturk/provider_type.py b/mephisto/abstractions/providers/mturk/provider_type.py new file mode 100644 index 000000000..240b3ffa5 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/provider_type.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +# 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. + +PROVIDER_TYPE = "mturk" diff --git a/mephisto/abstractions/providers/mturk/utils/__init__.py b/mephisto/abstractions/providers/mturk/utils/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/providers/mturk/utils/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/providers/mturk/utils/script_utils.py b/mephisto/abstractions/providers/mturk/utils/script_utils.py similarity index 94% rename from mephisto/providers/mturk/utils/script_utils.py rename to mephisto/abstractions/providers/mturk/utils/script_utils.py index 81733399d..63e24d6ce 100644 --- a/mephisto/providers/mturk/utils/script_utils.py +++ b/mephisto/abstractions/providers/mturk/utils/script_utils.py @@ -6,12 +6,12 @@ from typing import List, Optional, TYPE_CHECKING, Dict -from mephisto.providers.mturk.mturk_utils import give_worker_qualification +from mephisto.abstractions.providers.mturk.mturk_utils import give_worker_qualification from mephisto.data_model.requester import Requester from mephisto.data_model.assignment import Unit if TYPE_CHECKING: - from mephisto.data_model.database import MephistoDB + from mephisto.abstractions.database import MephistoDB def direct_soft_block_mturk_workers( diff --git a/mephisto/providers/mturk/wrap_crowd_source.js b/mephisto/abstractions/providers/mturk/wrap_crowd_source.js similarity index 100% rename from mephisto/providers/mturk/wrap_crowd_source.js rename to mephisto/abstractions/providers/mturk/wrap_crowd_source.js diff --git a/mephisto/abstractions/providers/mturk_sandbox/__init__.py b/mephisto/abstractions/providers/mturk_sandbox/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# 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. diff --git a/mephisto/abstractions/providers/mturk_sandbox/provider_type.py b/mephisto/abstractions/providers/mturk_sandbox/provider_type.py new file mode 100644 index 000000000..2c944bfe9 --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/provider_type.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +# 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. + +PROVIDER_TYPE = "mturk_sandbox" diff --git a/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_agent.py b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_agent.py new file mode 100644 index 000000000..8bf47096d --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_agent.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.providers.mturk_sandbox.provider_type import PROVIDER_TYPE +from mephisto.abstractions.providers.mturk.mturk_agent import MTurkAgent + +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.providers.mturk.requester import MTurkRequester + from mephisto.data_model.assignment import Unit + from mephisto.data_model.agent import Agent + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.worker import Worker + + +class SandboxMTurkAgent(MTurkAgent): + """ + Wrapper for a regular MTurk agent that will only communicate with sandbox + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def _get_client(self) -> Any: + """ + Get an mturk client for usage with mturk_utils for this agent + """ + unit = self.get_unit() + requester: "MTurkRequester" = unit.get_requester() + return self.datastore.get_sandbox_client_for_requester( + requester._requester_name + ) + + @staticmethod + def new(db: "MephistoDB", worker: "Worker", unit: "Unit") -> "Agent": + """Create an agent for this worker to be used for work on the given Unit.""" + return SandboxMTurkAgent._register_agent(db, worker, unit, PROVIDER_TYPE) diff --git a/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_provider.py b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_provider.py new file mode 100644 index 000000000..b9c007d77 --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_provider.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.providers.mturk_sandbox.provider_type import PROVIDER_TYPE +from mephisto.abstractions.providers.mturk.mturk_provider import ( + MTurkProvider, + MTurkProviderArgs, +) +from mephisto.abstractions.providers.mturk_sandbox.sandbox_mturk_agent import ( + SandboxMTurkAgent, +) +from mephisto.abstractions.providers.mturk_sandbox.sandbox_mturk_requester import ( + SandboxMTurkRequester, +) +from mephisto.abstractions.providers.mturk_sandbox.sandbox_mturk_unit import ( + SandboxMTurkUnit, +) +from mephisto.abstractions.providers.mturk_sandbox.sandbox_mturk_worker import ( + SandboxMTurkWorker, +) +from mephisto.operations.registry import register_mephisto_abstraction + +import os +from dataclasses import dataclass + +from typing import Any, ClassVar, Type, List, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.assignment import Unit + from mephisto.data_model.worker import Worker + from mephisto.data_model.requester import Requester + from mephisto.data_model.agent import Agent + + +@dataclass +class SandboxMTurkProviderArgs(MTurkProviderArgs): + """Provider args for a sandbox MTurk provider""" + + _provider_type: str = PROVIDER_TYPE + + +@register_mephisto_abstraction() +class SandboxMTurkProvider(MTurkProvider): + """ + Mock implementation of a CrowdProvider that stores everything + in a local state in the class for use in tests. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + UnitClass: ClassVar[Type["Unit"]] = SandboxMTurkUnit + + RequesterClass: ClassVar[Type["Requester"]] = SandboxMTurkRequester + + WorkerClass: ClassVar[Type["Worker"]] = SandboxMTurkWorker + + AgentClass: ClassVar[Type["Agent"]] = SandboxMTurkAgent + + ArgsClass = SandboxMTurkProviderArgs + + SUPPORTED_TASK_TYPES: ClassVar[List[str]] = [ + # TODO + ] + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_sandbox_client_for_requester(requester_name) + + @classmethod + def get_wrapper_js_path(cls): + """ + Return the path to the `wrap_crowd_source.js` file for this + provider to be deployed to the server + """ + return os.path.join(os.path.dirname(__file__), "wrap_crowd_source.js") + + def cleanup_qualification(self, qualification_name: str) -> None: + """Remove the qualification from the sandbox server""" + return super().cleanup_qualification(f"{qualification_name}_sandbox") diff --git a/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_requester.py b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_requester.py new file mode 100644 index 000000000..14e53899b --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_requester.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.providers.mturk.mturk_requester import MTurkRequester +from mephisto.abstractions.providers.mturk_sandbox.provider_type import PROVIDER_TYPE + +from typing import Any, Optional, Mapping, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.requester import Requester + from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore + + +class SandboxMTurkRequester(MTurkRequester): + """Wrapper around regular requester that handles removing the appended "sandbox" name""" + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + # Use _requester_name to preserve sandbox behavior which + # utilizes a different requester_name + assert self.requester_name.endswith( + "_sandbox" + ), f"{self.requester_name} is not a sandbox requester" + self._requester_name = self.requester_name[:-8] + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_sandbox_client_for_requester(requester_name) + + def is_sandbox(self) -> bool: + """ + Determine if this is a requester on sandbox + """ + return True + + # Required functions for a Requester implementation + + @staticmethod + def new(db: "MephistoDB", requester_name: str) -> "Requester": + if not requester_name.endswith("_sandbox"): + requester_name += "_sandbox" + return SandboxMTurkRequester._register_requester( + db, requester_name, PROVIDER_TYPE + ) diff --git a/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_unit.py b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_unit.py new file mode 100644 index 000000000..2b21f5433 --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_unit.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# 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. + +from datetime import datetime + +from mephisto.abstractions.providers.mturk.mturk_unit import MTurkUnit +from mephisto.abstractions.providers.mturk_sandbox.provider_type import PROVIDER_TYPE +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.data_model.assignment import Unit + from mephisto.abstractions.database import MephistoDB + from mephisto.data_model.assignment import Assignment + + +class SandboxMTurkUnit(MTurkUnit): + """ + This class tracks the status of an individual worker's contribution to a + higher level assignment. It is the smallest 'unit' of work to complete + the assignment, and this class is only responsible for checking + the status of that work itself being done. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_sandbox_client_for_requester(requester_name) + + @staticmethod + def new( + db: "MephistoDB", assignment: "Assignment", index: int, pay_amount: float + ) -> "Unit": + """Create a Unit for the given assignment""" + return SandboxMTurkUnit._register_unit( + db, assignment, index, pay_amount, PROVIDER_TYPE + ) diff --git a/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_worker.py b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_worker.py new file mode 100644 index 000000000..9ee4f87bb --- /dev/null +++ b/mephisto/abstractions/providers/mturk_sandbox/sandbox_mturk_worker.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +# 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. + +from mephisto.abstractions.providers.mturk.mturk_worker import MTurkWorker +from mephisto.abstractions.providers.mturk_sandbox.provider_type import PROVIDER_TYPE + +from typing import Any, Mapping, Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from mephisto.abstractions.providers.mturk.mturk_datastore import MTurkDatastore + from mephisto.data_model.worker import Worker + from mephisto.abstractions.database import MephistoDB + + +class SandboxMTurkWorker(MTurkWorker): + """ + This class represents an individual - namely a person. It maintains components of ongoing identity for a user. + """ + + # Ensure inherited methods use this level's provider type + PROVIDER_TYPE = PROVIDER_TYPE + + def __init__( + self, db: "MephistoDB", db_id: str, row: Optional[Mapping[str, Any]] = None + ): + super().__init__(db, db_id, row=row) + self.datastore: "MTurkDatastore" = self.db.get_datastore_for_provider( + self.PROVIDER_TYPE + ) + # sandbox workers use a different name + self._worker_name = self.worker_name[:-8] + + def grant_crowd_qualification( + self, qualification_name: str, value: int = 1 + ) -> None: + """ + Grant a qualification by the given name to this worker. Check the local + MTurk db to find the matching MTurk qualification to grant, and pass + that. If no qualification exists, try to create one. + """ + return super().grant_crowd_qualification(qualification_name + "_sandbox", value) + + def revoke_crowd_qualification(self, qualification_name: str) -> None: + """ + Revoke the qualification by the given name from this worker. Check the local + MTurk db to find the matching MTurk qualification to revoke, pass if + no such qualification exists. + """ + return super().revoke_crowd_qualification(qualification_name + "_sandbox") + + def _get_client(self, requester_name: str) -> Any: + """ + Get an mturk client for usage with mturk_utils + """ + return self.datastore.get_sandbox_client_for_requester(requester_name) + + @staticmethod + def new(db: "MephistoDB", worker_id: str) -> "Worker": + return MTurkWorker._register_worker(db, worker_id + "_sandbox", PROVIDER_TYPE) diff --git a/mephisto/providers/mturk_sandbox/wrap_crowd_source.js b/mephisto/abstractions/providers/mturk_sandbox/wrap_crowd_source.js similarity index 100% rename from mephisto/providers/mturk_sandbox/wrap_crowd_source.js rename to mephisto/abstractions/providers/mturk_sandbox/wrap_crowd_source.js diff --git a/mephisto/client/api.py b/mephisto/client/api.py index 371c111ca..1be0fcf54 100644 --- a/mephisto/client/api.py +++ b/mephisto/client/api.py @@ -6,12 +6,12 @@ from flask import Blueprint, jsonify, request from flask import current_app as app -from mephisto.data_model.database import EntryAlreadyExistsException -from mephisto.data_model.assignment_state import AssignmentState -from mephisto.data_model.task import TaskRun +from mephisto.abstractions.database import EntryAlreadyExistsException +from mephisto.data_model.constants.assignment_state import AssignmentState +from mephisto.data_model.task_run import TaskRun from mephisto.data_model.assignment import Assignment, Unit from mephisto.core.argparse_parser import get_extra_argument_dicts, parse_arg_dict -from mephisto.core.registry import ( +from mephisto.operations.registry import ( get_blueprint_from_type, get_crowd_provider_from_type, get_architect_from_type, diff --git a/mephisto/client/cli.py b/mephisto/client/cli.py index b2cdf11ba..c486c6020 100644 --- a/mephisto/client/cli.py +++ b/mephisto/client/cli.py @@ -48,8 +48,8 @@ def review(review_app_dir, port, output, output_method, csv_headers, json, debug @cli.command("check") def check(): """Checks that mephisto is setup correctly""" - from mephisto.core.local_database import LocalMephistoDB - from mephisto.core.utils import get_mock_requester + from mephisto.abstractions.databases.local_database import LocalMephistoDB + from mephisto.operations.utils import get_mock_requester try: db = LocalMephistoDB() @@ -64,7 +64,7 @@ def check(): @cli.command("requesters") def list_requesters(): """Lists all registered requesters""" - from mephisto.core.local_database import LocalMephistoDB + from mephisto.abstractions.databases.local_database import LocalMephistoDB from tabulate import tabulate db = LocalMephistoDB() @@ -81,8 +81,8 @@ def register_provider(args): click.echo("Usage: mephisto register arg1=value arg2=value") return - from mephisto.core.local_database import LocalMephistoDB - from mephisto.core.registry import get_crowd_provider_from_type + from mephisto.abstractions.databases.local_database import LocalMephistoDB + from mephisto.operations.registry import get_crowd_provider_from_type from mephisto.core.argparse_parser import parse_arg_dict, get_extra_argument_dicts provider_type, requester_args = args[0], args[1:] @@ -130,7 +130,7 @@ def get_help_arguments(args): ) return - from mephisto.core.registry import ( + from mephisto.operations.registry import ( get_blueprint_from_type, get_crowd_provider_from_type, get_architect_from_type, diff --git a/mephisto/client/server.py b/mephisto/client/full/server.py similarity index 86% rename from mephisto/client/server.py rename to mephisto/client/full/server.py index 42211a8e0..d44564df3 100644 --- a/mephisto/client/server.py +++ b/mephisto/client/full/server.py @@ -7,14 +7,14 @@ from flask import Flask, send_file, jsonify from mephisto.client.config import Config from mephisto.client.api import api -from mephisto.core.operator import Operator -from mephisto.core.local_database import LocalMephistoDB +from mephisto.operations.operator import Operator +from mephisto.abstractions.databases.local_database import LocalMephistoDB import os import atexit import signal -app = Flask(__name__, static_url_path="/static", static_folder="../webapp/build/static") +app = Flask(__name__, static_url_path="/static", static_folder="webapp/build/static") app.config.from_object(Config) app.register_blueprint(api, url_prefix="/api/v1") @@ -31,7 +31,7 @@ @app.route("/", defaults={"path": "index.html"}) @app.route("/") def index(path): - return send_file(os.path.join("..", "webapp", "build", "index.html")) + return send_file(os.path.join("webapp", "build", "index.html")) @app.after_request diff --git a/mephisto/webapp/.gitattributes b/mephisto/client/full/webapp/.gitattributes similarity index 100% rename from mephisto/webapp/.gitattributes rename to mephisto/client/full/webapp/.gitattributes diff --git a/mephisto/webapp/.gitignore b/mephisto/client/full/webapp/.gitignore similarity index 100% rename from mephisto/webapp/.gitignore rename to mephisto/client/full/webapp/.gitignore diff --git a/mephisto/webapp/README.md b/mephisto/client/full/webapp/README.md similarity index 100% rename from mephisto/webapp/README.md rename to mephisto/client/full/webapp/README.md diff --git a/mephisto/webapp/build/asset-manifest.json b/mephisto/client/full/webapp/build/asset-manifest.json similarity index 100% rename from mephisto/webapp/build/asset-manifest.json rename to mephisto/client/full/webapp/build/asset-manifest.json diff --git a/mephisto/webapp/build/index.html b/mephisto/client/full/webapp/build/index.html similarity index 100% rename from mephisto/webapp/build/index.html rename to mephisto/client/full/webapp/build/index.html diff --git a/mephisto/webapp/build/precache-manifest.6a3f8be9c9b4eda91b48c53412c4ac04.js b/mephisto/client/full/webapp/build/precache-manifest.6a3f8be9c9b4eda91b48c53412c4ac04.js similarity index 100% rename from mephisto/webapp/build/precache-manifest.6a3f8be9c9b4eda91b48c53412c4ac04.js rename to mephisto/client/full/webapp/build/precache-manifest.6a3f8be9c9b4eda91b48c53412c4ac04.js diff --git a/mephisto/client/full/webapp/build/precache-manifest.9f9697fc33c2a769605084eb8123c827.js b/mephisto/client/full/webapp/build/precache-manifest.9f9697fc33c2a769605084eb8123c827.js new file mode 100644 index 000000000..2987066ca --- /dev/null +++ b/mephisto/client/full/webapp/build/precache-manifest.9f9697fc33c2a769605084eb8123c827.js @@ -0,0 +1,34 @@ +self.__precacheManifest = (self.__precacheManifest || []).concat([ + { + "revision": "413929c22f5eb0b865838e3cf75e0cb2", + "url": "/index.html" + }, + { + "revision": "e60a7159900a72987567", + "url": "/static/css/main.f511f1d3.chunk.css" + }, + { + "revision": "54446ba46b7001c87af6", + "url": "/static/js/2.c380e4ee.chunk.js" + }, + { + "revision": "53b91fb6912e14c9689b5be87306d93a", + "url": "/static/js/2.c380e4ee.chunk.js.LICENSE" + }, + { + "revision": "e60a7159900a72987567", + "url": "/static/js/main.d1c9df08.chunk.js" + }, + { + "revision": "e0acb5af05f59d50df01", + "url": "/static/js/runtime-main.3d6e97dd.js" + }, + { + "revision": "cf23121829070fedf98e5caa6585792f", + "url": "/static/media/M.cf231218.svg" + }, + { + "revision": "44730b5bd732ae067bd4f9f8abe88757", + "url": "/static/media/sample.44730b5b.png" + } +]); \ No newline at end of file diff --git a/mephisto/webapp/build/robots.txt b/mephisto/client/full/webapp/build/robots.txt similarity index 100% rename from mephisto/webapp/build/robots.txt rename to mephisto/client/full/webapp/build/robots.txt diff --git a/mephisto/webapp/build/service-worker.js b/mephisto/client/full/webapp/build/service-worker.js similarity index 100% rename from mephisto/webapp/build/service-worker.js rename to mephisto/client/full/webapp/build/service-worker.js diff --git a/mephisto/webapp/build/static/css/2.d6c513eb.chunk.css b/mephisto/client/full/webapp/build/static/css/2.d6c513eb.chunk.css similarity index 100% rename from mephisto/webapp/build/static/css/2.d6c513eb.chunk.css rename to mephisto/client/full/webapp/build/static/css/2.d6c513eb.chunk.css diff --git a/mephisto/webapp/build/static/css/2.d6c513eb.chunk.css.map b/mephisto/client/full/webapp/build/static/css/2.d6c513eb.chunk.css.map similarity index 100% rename from mephisto/webapp/build/static/css/2.d6c513eb.chunk.css.map rename to mephisto/client/full/webapp/build/static/css/2.d6c513eb.chunk.css.map diff --git a/mephisto/webapp/build/static/css/main.ec5c0f52.chunk.css b/mephisto/client/full/webapp/build/static/css/main.ec5c0f52.chunk.css similarity index 100% rename from mephisto/webapp/build/static/css/main.ec5c0f52.chunk.css rename to mephisto/client/full/webapp/build/static/css/main.ec5c0f52.chunk.css diff --git a/mephisto/webapp/build/static/css/main.ec5c0f52.chunk.css.map b/mephisto/client/full/webapp/build/static/css/main.ec5c0f52.chunk.css.map similarity index 100% rename from mephisto/webapp/build/static/css/main.ec5c0f52.chunk.css.map rename to mephisto/client/full/webapp/build/static/css/main.ec5c0f52.chunk.css.map diff --git a/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css b/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css new file mode 100644 index 000000000..36b8c556a --- /dev/null +++ b/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css @@ -0,0 +1,2 @@ +body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.App{text-align:center;background-color:#eaf3fd;display:flex;min-height:100vh;flex-direction:column}*{box-sizing:border-box}.App-header{background-color:#fff;display:flex;font-size:30px;color:#345;height:80px;margin-bottom:30px;border-bottom:1px solid #c7ddf3}.App-header,.App-header a{flex-direction:row;align-items:center;justify-content:center}.App-header a{text-decoration:none;color:inherit;display:inline-flex}.App-header a:hover{color:#5f9ea0}.App-header a:hover .logo{position:relative;-webkit-animation:emphasizeLogo .3s cubic-bezier(.5,0,0,1);animation:emphasizeLogo .3s cubic-bezier(.5,0,0,1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.logo{margin-right:12px}@-webkit-keyframes emphasizeLogo{0%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}to{-webkit-transform:scale(1.2) rotate(-15deg);transform:scale(1.2) rotate(-15deg)}}@keyframes emphasizeLogo{0%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}to{-webkit-transform:scale(1.2) rotate(-15deg);transform:scale(1.2) rotate(-15deg)}}p{line-height:1.4em;margin:0}.card.create-task,.card.export-data{font-size:14px}.card.create-task p,.card.export-data p,.card p{margin-bottom:20px}.App-link{display:block;margin-top:5px;font-size:14px;font-weight:700}.page-body{flex:1 1;flex-direction:column;align-items:center;justify-content:center;overflow:auto}a{color:#1a809c}.card-container{display:flex;flex-direction:row;width:100%;align-items:flex-start}.card-outer-container{display:inline-flex}.card{background-color:#fff;box-shadow:0 15px 25px #cee1f5;padding:20px;border-radius:20px;font-size:16px;text-align:left;margin:15px;min-width:200px;max-width:300px;color:#345}.card h3{font-weight:700;margin:0 0 20px;color:#8b9db1;font-size:18px}.card h3 em{font-style:normal;color:#345}span.badge{border-radius:20px;background-color:#345;width:20px;color:#fff;display:inline-flex;text-align:center;font-size:10px;height:20px;align-items:center;justify-content:center;vertical-align:text-bottom;margin-right:7px}ul{padding-left:20px}ul li{margin-bottom:5px}.live-task{padding:10px 20px;margin:0 -20px 10px;border-top:1px solid #d6ecd7;border-bottom:1px solid #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f0f9f7),to(rgba(240,249,247,0)));background-image:linear-gradient(180deg,#f0f9f7,rgba(240,249,247,0))}.live-task.interactive{cursor:pointer}.live-task.interactive:hover{background-color:#e0f6ff;border-bottom:1px solid #3ec9ff;background-image:none;border-top:1px solid #3ec9ff;-webkit-transition:border-color .3s,background .3s;transition:border-color .3s,background .3s}.live-task.interactive:hover .title{color:#0dadea;-webkit-transition:color .3s;transition:color .3s}.live-task .title{font-weight:700;color:#4fa254}.hyperparameters{color:#888;font-size:12px;word-break:break-word;font-style:italic;margin-bottom:4px}.hyperparameter{margin-right:5px;white-space:nowrap;display:inline-block}.hyperparameter .value{font-weight:700;color:#666}.hyperparameter .key,.hyperparameter .value{white-space:nowrap}.details{font-size:13px;margin-top:10px}.btn{padding:7px;cursor:pointer;font-size:14px;background-color:#334355;border:1px solid #080808;color:#fff;font-weight:700;margin-top:9px;width:100%;text-decoration:none}.bar{background-color:#b8d7ff;height:14px;margin-bottom:2px}.metrics{display:flex;flex-direction:row;justify-content:center}.metric{margin:0;text-align:center;padding:10px;font-size:16px;color:#333;flex:1 1}.metrics.highlight-first .metric:first-child{font-weight:700}.metric label{display:block;font-size:12px}.metrics.anticipate-double label{margin-top:10px}p.warning,p a{font-weight:700}p.warning{background-color:#ffffd1;padding:5px;border:1px solid #e2d108;margin:5px 0}code{white-space:nowrap}.card{-webkit-animation:fadeIn .3s cubic-bezier(.5,0,0,1);animation:fadeIn .3s cubic-bezier(.5,0,0,1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;opacity:0}.card:first-child{-webkit-animation-delay:0s;animation-delay:0s}.card:nth-child(2){-webkit-animation-delay:.1s;animation-delay:.1s}.card:nth-child(3){-webkit-animation-delay:.2s;animation-delay:.2s}.card:nth-child(4){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes fadeIn{0%{opacity:0;-webkit-transform:scale(.9) translateY(80px);transform:scale(.9) translateY(80px)}60%{-webkit-transform:translateY(-2px);transform:translateY(-2px)}to{opacity:1;-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fadeIn{0%{opacity:0;-webkit-transform:scale(.9) translateY(80px);transform:scale(.9) translateY(80px)}60%{-webkit-transform:translateY(-2px);transform:translateY(-2px)}to{opacity:1;-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}.sandbox{font-size:10px;text-transform:uppercase;background-color:#f3d9b7;color:#694903;padding:2px;margin-left:3px;vertical-align:initial;float:right}a.unstyled{text-decoration:inherit;color:inherit}.btn.rounded{width:auto;border-radius:20px;border:none;padding:10px 20px}.user_info{padding:10px 20px;margin:0 -20px 10px}.user_info .title{color:#6e91b3;font-size:16px;font-weight:700}.task-list{display:flex;flex-direction:column;border-right:1px solid #cee1f5;margin:-20px 0 -20px -20px;padding:20px 0;align-content:flex-start}.task-list-item{display:inline-block;padding:15px 30px;max-width:400px;min-width:200px;text-align:left}.task-list-item.selected,.task-list-item.selected:hover{color:#fff;background-color:#345}.task-list-item:hover{background-color:#ecf0f3;cursor:pointer}.name{font-weight:700}.tags span{margin-right:7px;display:inline-block;font-size:13px}.search{margin:10px 20px;padding:10px;border-radius:10px;border:none;background-color:#eff3f7;font-size:inherit;font-weight:700;color:inherit}.search::-webkit-input-placeholder{color:#a4b5c7;font-weight:400}.search::-moz-placeholder{color:#a4b5c7;font-weight:400}.search::-ms-input-placeholder{color:#a4b5c7;font-weight:400}.search::placeholder{color:#a4b5c7;font-weight:400}.search:focus{outline:none;box-shadow:inset 0 0 2px 1px #c8d8f5;background-color:#f7f7f7}.text-container,textarea{margin:0;padding:10px;border-radius:10px;border:none;background-color:#eff3f7;font-size:inherit;font-weight:700;color:inherit;font-family:monospace;width:100%}textarea:focus{outline:none;box-shadow:inset 0 0 2px 1px #c8d8f5}.task-description{padding:0 30px;flex:1 1}.task-description h1{margin:10px 0 5px}.card .task-description p{color:#68879e;font-size:21px}.task-description h3{margin-bottom:10px}.task-description h3 code{background-color:#f2f2f2;font-size:16px;padding:0 2px}.controls{margin-top:40px}.btn.inverse{background-color:#f5f5f5;color:#324456}.btn.inverse:hover{background-color:#efefef;color:#324456}.ace_editor .ace_marker-layer .ace_bracket,.ace_hidden-cursors .ace_cursor{display:none}.controls{margin-bottom:40px;background-color:#fbfbfb;border:1px solid #f5f5f5;padding:20px;border-radius:20px;box-shadow:0 3px 3px 0 rgba(0,0,0,.1)}.hero{font-size:45px;font-weight:700;color:#033c3e;line-height:1.2em;padding:80px 0;-webkit-animation:fadeUp 2s cubic-bezier(0,1,0,1);animation:fadeUp 2s cubic-bezier(0,1,0,1)}@-webkit-keyframes fadeUp{0%{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeUp{0%{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}} +/*# sourceMappingURL=main.f511f1d3.chunk.css.map */ \ No newline at end of file diff --git a/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css.map b/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css.map new file mode 100644 index 000000000..084c4ea32 --- /dev/null +++ b/mephisto/client/full/webapp/build/static/css/main.f511f1d3.chunk.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["index.css","App.css","review.css","taskgallery.css","splash.css"],"names":[],"mappings":"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AAU,CACV,wCAAsC,CAAtC,gCACF,CACF,CAEA,SACE,cAAe,CACf,wBAAyB,CACzB,wBAAyB,CACzB,aAAsB,CACtB,WAAY,CACZ,eAAgB,CAChB,sBAAwB,CACxB,WACF,CAEA,WACE,uBAAwB,CACxB,aACF,CAEA,aACE,UAAW,CACX,kBAAmB,CACnB,WAAY,CACZ,iBACF,CC3VA,WACE,iBAA4B,CAC5B,mBACF,CAEA,kBACE,aAAc,CACd,cAAe,CACf,eACF,CCTA,WACE,YAAa,CACb,qBAAsB,CACtB,8BAA+B,CAC/B,0BAA6B,CAC7B,cAAe,CACf,wBAEF,CAEA,gBACE,oBAAqB,CACrB,iBAAkB,CAClB,eAAgB,CAChB,eAAgB,CAChB,eACF,CAEA,wDAEE,UAAY,CACZ,qBACF,CAEA,sBACE,wBAAyB,CACzB,cACF,CAEA,MACE,eACF,CAEA,WACE,gBAAiB,CACjB,oBAAqB,CACrB,cACF,CAEA,QACE,gBAAiB,CACjB,YAAa,CACb,kBAAmB,CACnB,WAAY,CACZ,wBAAyB,CACzB,iBAAkB,CAClB,eAAiB,CACjB,aACF,CAEA,mCACE,aAAc,CACd,eACF,CAHA,0BACE,aAAc,CACd,eACF,CAHA,+BACE,aAAc,CACd,eACF,CAHA,qBACE,aAAc,CACd,eACF,CAEA,cACE,YAAa,CACb,oCAAyC,CACzC,wBACF,CAEA,yBAEE,QAAW,CACX,YAAa,CACb,kBAAmB,CACnB,WAAY,CACZ,wBAAyB,CACzB,iBAAkB,CAClB,eAAiB,CACjB,aAAc,CACd,qBAAsB,CACtB,UACF,CAEA,eACE,YAAa,CACb,oCACF,CAEA,kBACE,cAAe,CACf,QACF,CAEA,qBACE,iBACF,CAEA,0BACE,aAAc,CACd,cACF,CAEA,qBACE,kBACF,CAEA,0BACE,wBAAyB,CACzB,cAAe,CACf,aACF,CAEA,UACE,eACF,CAEA,aACE,wBAAyB,CACzB,aACF,CAEA,mBACE,wBAAyB,CACzB,aACF,CAMA,2EACE,YACF,CAEA,UACE,kBAAmB,CACnB,wBAAyB,CAEzB,wBAAyB,CAEzB,YAAoB,CACpB,kBAAmB,CACnB,qCAGF,CCzIA,MACE,cAAe,CACf,eAAiB,CACjB,aAAc,CACd,iBAAkB,CAClB,cAAe,CACf,iDAA6C,CAA7C,yCACF,CAaA,0BACE,GACE,SAAU,CACV,mCAA4B,CAA5B,2BACF,CACA,GACE,SAAU,CACV,+BAA0B,CAA1B,uBACF,CACF,CATA,kBACE,GACE,SAAU,CACV,mCAA4B,CAA5B,2BACF,CACA,GACE,SAAU,CACV,+BAA0B,CAA1B,uBACF,CACF","file":"main.f511f1d3.chunk.css","sourcesContent":["body {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n",".App {\n text-align: center;\n background-color: #eaf3fd;\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n}\n\n* {\n box-sizing: border-box;\n}\n\n.App-header {\n background-color: white;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n font-size: 30px;\n color: #334455;\n height: 80px;\n margin-bottom: 30px;\n border-bottom: 1px solid #c7ddf3;\n}\n\n.App-header a {\n text-decoration: none;\n color: inherit;\n display: inline-flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\n.App-header a:hover {\n color: cadetblue;\n}\n\n.App-header a:hover .logo {\n position: relative;\n animation: emphasizeLogo 0.3s cubic-bezier(0.5, 0, 0, 1);\n animation-fill-mode: forwards;\n}\n\n/* .App-header a:active {\n position: relative;\n top: 1px;\n} */\n\n.logo {\n margin-right: 12px;\n}\n\n@keyframes emphasizeLogo {\n from {\n transform: scale(1, 1) rotate(0);\n }\n to {\n transform: scale(1.2, 1.2) rotate(-15deg);\n }\n}\n\np {\n line-height: 1.4em;\n margin: 0;\n}\n\n.card.create-task,\n.card.export-data {\n font-size: 14px;\n}\n\n.card.create-task p,\n.card.export-data p {\n margin-bottom: 20px;\n}\n\n.card p {\n margin-bottom: 20px;\n}\n\n.App-link {\n display: block;\n margin-top: 5px;\n font-size: 14px;\n font-weight: bold;\n}\n\n.page-body {\n /* display: flex; */\n flex: 1;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n overflow: auto;\n}\n\na {\n color: #1a809c;\n}\n\n.card-container {\n display: flex;\n flex-direction: row;\n width: 100%;\n align-items: flex-start;\n}\n\n.card-outer-container {\n display: inline-flex;\n}\n\n.card {\n background-color: white;\n box-shadow: 0px 15px 25px #cee1f5;\n padding: 20px;\n border-radius: 20px;\n font-size: 16px;\n text-align: left;\n margin: 15px;\n /* margin-right: 30px; */\n min-width: 200px;\n max-width: 300px;\n color: #334455;\n}\n\n.card h3 {\n font-weight: bold;\n margin: 0 0 20px;\n color: #8b9db1;\n font-size: 18px;\n}\n\n.card h3 em {\n font-style: normal;\n color: #334455;\n}\n\nspan.badge {\n border-radius: 20px;\n background-color: #334455;\n width: 20px;\n color: white;\n display: inline-flex;\n text-align: center;\n font-size: 10px;\n height: 20px;\n align-items: center;\n justify-content: center;\n vertical-align: text-bottom;\n margin-right: 7px;\n}\n\nul {\n padding-left: 20px;\n}\nul li {\n margin-bottom: 5px;\n}\n\n.live-task {\n /* margin-bottom: 10px;\n border-left: 5px solid #4fa254;\n padding: 0px 5px 1px 10px;\n cursor: pointer; */\n padding: 10px 20px 10px 20px;\n margin: 0 -20px 10px;\n border-top: 1px solid #d6ecd7;\n border-bottom: 1px solid rgba(255, 255, 255, 1);\n background-image: linear-gradient(\n to bottom,\n rgba(240, 249, 247, 1),\n rgba(240, 249, 247, 0)\n );\n}\n\n.live-task.interactive {\n cursor: pointer;\n}\n\n.live-task.interactive:hover {\n background-color: #e0f6ff;\n border-bottom: 1px solid #3ec9ff;\n background-image: none;\n border-top: 1px solid #3ec9ff;\n transition: border-color 0.3s, background 0.3s;\n}\n\n.live-task.interactive:hover .title {\n color: #0dadea;\n transition: color 0.3s;\n}\n\n.live-task .title {\n font-weight: bold;\n color: #4fa254;\n /* background-color: rgb(230, 255, 230); */\n /* padding: 3px 0px; */\n}\n\n.hyperparameters {\n color: #888;\n font-size: 12px;\n word-break: break-word;\n font-style: italic;\n margin-bottom: 4px;\n}\n.hyperparameter {\n margin-right: 5px;\n white-space: nowrap;\n display: inline-block;\n}\n.hyperparameter .value {\n font-weight: bold;\n color: #666;\n}\n.hyperparameter .value,\n.hyperparameter .key {\n white-space: nowrap;\n}\n\n.details {\n font-size: 13px;\n margin-top: 10px;\n}\n\n.btn {\n padding: 7px;\n cursor: pointer;\n font-size: 14px;\n background-color: #334355;\n border: 1px solid #080808;\n color: white;\n font-weight: bold;\n\n margin-top: 9px;\n /* display: block; */\n width: 100%;\n text-decoration: none;\n}\n\n.bar {\n background-color: #b8d7ff;\n height: 14px;\n margin-bottom: 2px;\n}\n\n.metrics {\n display: flex;\n flex-direction: row;\n justify-content: center;\n}\n\n.metric {\n margin: 0px 0px 0px;\n text-align: center;\n /* background-color: white; */\n /* border: 1px solid #ddd; */\n padding: 10px;\n font-size: 16px;\n color: #333;\n flex: 1;\n}\n\n.metrics.highlight-first .metric:first-child {\n font-weight: bold;\n}\n\n.metric label {\n display: block;\n font-size: 12px;\n}\n\n.metrics.anticipate-double label {\n margin-top: 10px;\n}\n\np a {\n font-weight: bold;\n}\n\np.warning {\n background-color: #ffffd1;\n padding: 5px;\n border: 1px solid #e2d108;\n margin: 5px 0;\n font-weight: bold;\n}\n\ncode {\n white-space: nowrap;\n}\n\n.card {\n animation: fadeIn 0.3s cubic-bezier(0.5, 0, 0, 1);\n animation-fill-mode: forwards;\n opacity: 0;\n}\n\n.card:nth-child(1) {\n animation-delay: 0s;\n}\n.card:nth-child(2) {\n animation-delay: 0.1s;\n}\n.card:nth-child(3) {\n animation-delay: 0.2s;\n}\n.card:nth-child(4) {\n animation-delay: 0.3s;\n}\n\n@keyframes fadeIn {\n 0% {\n opacity: 0;\n transform: scale(0.9, 0.9) translateY(80px);\n }\n 60% {\n transform: translateY(-2px);\n }\n 100% {\n opacity: 1;\n transform: scale(1, 1) translateY(0px);\n }\n}\n\n.sandbox {\n font-size: 10px;\n text-transform: uppercase;\n background-color: #f3d9b7;\n color: rgb(105, 73, 3);\n padding: 2px;\n margin-left: 3px;\n vertical-align: baseline;\n float: right;\n}\n\na.unstyled {\n text-decoration: inherit;\n color: inherit;\n}\n\n.btn.rounded {\n width: auto;\n border-radius: 20px;\n border: none;\n padding: 10px 20px;\n}\n",".user_info {\n padding: 10px 20px 10px 20px;\n margin: 0 -20px 10px;\n}\n\n.user_info .title {\n color: #6e91b3;\n font-size: 16px;\n font-weight: bold;\n}\n",".task-list {\n display: flex;\n flex-direction: column;\n border-right: 1px solid #cee1f5;\n margin: -20px 0px -20px -20px;\n padding: 20px 0;\n align-content: flex-start;\n /* padding: \"20px 30px\"; */\n}\n\n.task-list-item {\n display: inline-block;\n padding: 15px 30px;\n max-width: 400px;\n min-width: 200px;\n text-align: left;\n}\n\n.task-list-item.selected,\n.task-list-item.selected:hover {\n color: white;\n background-color: #334455;\n}\n\n.task-list-item:hover {\n background-color: #ecf0f3;\n cursor: pointer;\n}\n\n.name {\n font-weight: bold;\n}\n\n.tags span {\n margin-right: 7px;\n display: inline-block;\n font-size: 13px;\n}\n\n.search {\n margin: 10px 20px;\n padding: 10px;\n border-radius: 10px;\n border: none;\n background-color: #eff3f7;\n font-size: inherit;\n font-weight: bold;\n color: inherit;\n}\n\n.search::placeholder {\n color: #a4b5c7;\n font-weight: normal;\n}\n\n.search:focus {\n outline: none;\n box-shadow: 0px 0px 2px 1px #c8d8f5 inset;\n background-color: #f7f7f7;\n}\n\ntextarea,\n.text-container {\n margin: 0px;\n padding: 10px;\n border-radius: 10px;\n border: none;\n background-color: #eff3f7;\n font-size: inherit;\n font-weight: bold;\n color: inherit;\n font-family: monospace;\n width: 100%;\n}\n\ntextarea:focus {\n outline: none;\n box-shadow: 0px 0px 2px 1px #c8d8f5 inset;\n}\n\n.task-description {\n padding: 0 30px;\n flex: 1;\n}\n\n.task-description h1 {\n margin: 10px 0 5px 0;\n}\n\n.card .task-description p {\n color: #68879e;\n font-size: 21px;\n}\n\n.task-description h3 {\n margin-bottom: 10px;\n}\n\n.task-description h3 code {\n background-color: #f2f2f2;\n font-size: 16px;\n padding: 0 2px;\n}\n\n.controls {\n margin-top: 40px;\n}\n\n.btn.inverse {\n background-color: #f5f5f5;\n color: #324456;\n}\n\n.btn.inverse:hover {\n background-color: #efefef;\n color: #324456;\n}\n\n.ace_editor .ace_marker-layer .ace_bracket {\n display: none;\n}\n\n.ace_hidden-cursors .ace_cursor {\n display: none;\n}\n\n.controls {\n margin-bottom: 40px;\n background-color: #fbfbfb;\n padding: 20px;\n border: 1px solid #f5f5f5;\n padding-top: 20px;\n padding-bottom: 20px;\n border-radius: 20px;\n box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.1);\n\n /* border-bottom: 1px solid #eee; */\n}\n",".hero {\n font-size: 45px;\n font-weight: bold;\n color: #033c3e;\n line-height: 1.2em;\n padding: 80px 0;\n animation: fadeUp 2s cubic-bezier(0, 1, 0, 1);\n}\n/* \n.hero a {\n text-decoration: inherit;\n color: inherit;\n}\n\n.hero a:hover {\n text-decoration: inherit;\n color: inherit;\n opacity: 0.9;\n} */\n\n@keyframes fadeUp {\n from {\n opacity: 0;\n transform: translateY(100px);\n }\n to {\n opacity: 1;\n transform: translateY(0px);\n }\n}\n"]} \ No newline at end of file diff --git a/mephisto/webapp/build/static/js/2.34d4026e.chunk.js b/mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js similarity index 100% rename from mephisto/webapp/build/static/js/2.34d4026e.chunk.js rename to mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js diff --git a/mephisto/webapp/build/static/js/2.34d4026e.chunk.js.LICENSE b/mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js.LICENSE similarity index 100% rename from mephisto/webapp/build/static/js/2.34d4026e.chunk.js.LICENSE rename to mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js.LICENSE diff --git a/mephisto/webapp/build/static/js/2.34d4026e.chunk.js.map b/mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js.map similarity index 100% rename from mephisto/webapp/build/static/js/2.34d4026e.chunk.js.map rename to mephisto/client/full/webapp/build/static/js/2.34d4026e.chunk.js.map diff --git a/mephisto/webapp/build/static/js/main.6e109e52.chunk.js b/mephisto/client/full/webapp/build/static/js/main.6e109e52.chunk.js similarity index 100% rename from mephisto/webapp/build/static/js/main.6e109e52.chunk.js rename to mephisto/client/full/webapp/build/static/js/main.6e109e52.chunk.js diff --git a/mephisto/webapp/build/static/js/main.6e109e52.chunk.js.map b/mephisto/client/full/webapp/build/static/js/main.6e109e52.chunk.js.map similarity index 100% rename from mephisto/webapp/build/static/js/main.6e109e52.chunk.js.map rename to mephisto/client/full/webapp/build/static/js/main.6e109e52.chunk.js.map diff --git a/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js b/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js new file mode 100644 index 000000000..15b26f022 --- /dev/null +++ b/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js @@ -0,0 +1,2 @@ +(this.webpackJsonpturk=this.webpackJsonpturk||[]).push([[0],{27:function(e,a,t){e.exports=t.p+"static/media/sample.44730b5b.png"},32:function(e,a,t){e.exports=t(54)},37:function(e,a,t){},38:function(e,a,t){},43:function(e,a,t){},44:function(e,a,t){},53:function(e,a,t){},54:function(e,a,t){"use strict";t.r(a);var n=t(0),l=t.n(n),r=t(21),c=t.n(r),s=(t(37),t(22)),i=t(23),m=t(30),o=t(24),d=t(31),u=(t(38),t(3)),p=t(8),E=t(5),v=function(){return l.a.createElement("div",{className:"page-body"},l.a.createElement("div",{className:"card-outer-container"},l.a.createElement("div",{className:"card-container"},l.a.createElement("div",{className:"card create-task"},l.a.createElement("h3",null,l.a.createElement("span",{className:"badge"},"1"),l.a.createElement("em",null,"Create")," a task"),l.a.createElement("div",null,l.a.createElement("p",null,"You will need an MTurk Requester Account and an AWS account (separate accounts).",l.a.createElement("a",{className:"App-link",href:"https://parl.ai/docs/tutorial_mturk.html#running-a-task",target:"_blank",rel:"noopener noreferrer"},"Setting up AWS \xbb")),l.a.createElement("p",null,"We have a growing collection of tasks already available. You can re-use one of them, clone & modify one of them to create a similar yet different task, or create a completely new custom task altogether. Custom tasks can range from simple static pages, to multi-agent dialogue, to dynamic & interactive React applications!",l.a.createElement(u.b,{className:"App-link",to:"/task-gallery"},"View gallery of existing tasks \xbb"),l.a.createElement("a",{className:"App-link",href:"https://parl.ai/docs/tutorial_task.html#creating-a-new-task-the-more-complete-way",target:"_blank",rel:"noopener noreferrer"},"Create a custom task \xbb")))),l.a.createElement("div",{className:"card"},l.a.createElement("h3",null,l.a.createElement("span",{className:"badge"},"2"),l.a.createElement("em",null,"Launch")," tasks"),l.a.createElement("p",null,"You currently have ",l.a.createElement("strong",null,"3 tasks")," running live."),[1,2,3].map((function(e){return l.a.createElement("div",{className:"live-task interactive"},l.a.createElement("div",{className:"title"},e>1?"semantic annotation":"LIGHT pilot (v2)",1===e&&l.a.createElement("span",{className:"sandbox"},"Sandbox")),l.a.createElement("div",{className:"hyperparameters"},[null].map((function(){return Object.entries({dataset:"twitter",model:"v3.123",enableSafety:!0,saveDataFile:"localDB"}).map((function(e){var a=Object(E.a)(e,2),t=a[0],n=a[1];return l.a.createElement("span",{className:"hyperparameter"},l.a.createElement("span",{className:"key"},t),"=",l.a.createElement("span",{className:"value"},n.toString()))}))}))[0]),l.a.createElement("div",{className:"details"},"Started 8 hours ago. 25 completed HITs. 3 disconnects."))})),l.a.createElement("button",{className:"btn"},"Launch a new task")),l.a.createElement("div",{className:"card"},l.a.createElement("h3",null,l.a.createElement("span",{className:"badge"},"3"),l.a.createElement("em",null,"Review")," data"),l.a.createElement("p",null,"You have"," ",l.a.createElement(u.b,{to:"/review",alt:"link"},"300 HITs")," ","left to review."),l.a.createElement(u.b,{className:"unstyled",to:"/review"},l.a.createElement("div",{className:"live-task interactive"},l.a.createElement("div",{className:"title"},"LIGHT dialogue"),l.a.createElement("div",{className:"hyperparameters"},[null].map((function(){return Object.entries({dataset:"twitter",model:"v3.123",enableSafety:!0,saveDataFile:"localDB"}).map((function(e){var a=Object(E.a)(e,2),t=a[0],n=a[1];return l.a.createElement("span",{className:"hyperparameter"},l.a.createElement("span",{className:"key"},t),"=",l.a.createElement("span",{className:"value"},n.toString()))}))}))[0]),l.a.createElement("div",{className:"details"},l.a.createElement("div",{className:"metrics highlight-first"},l.a.createElement("div",{className:"metric"},"70",l.a.createElement("label",null,"Unreviewed")),l.a.createElement("div",{className:"metric"},"300",l.a.createElement("label",null,"Approved")),l.a.createElement("div",{className:"metric"},"23",l.a.createElement("label",null,"Rejected"))),l.a.createElement("p",{className:"warning"},"Warning: 10 HITs are nearing their 2 week deadline and risk being auto-approved.")))),l.a.createElement("div",{className:"live-task interactive"},l.a.createElement("div",{className:"title"},"LIGHT dialogue (pilot v1)"),l.a.createElement("div",{className:"hyperparameters"},[null].map((function(){return Object.entries({dataset:"twitter",model:"v3.123",enableSafety:!0,saveDataFile:"localDB"}).map((function(e){var a=Object(E.a)(e,2),t=a[0],n=a[1];return l.a.createElement("span",{className:"hyperparameter"},l.a.createElement("span",{className:"key"},t),"=",l.a.createElement("span",{className:"value"},n.toString()))}))}))[0]),l.a.createElement("div",{className:"details"},l.a.createElement("div",{className:"metrics highlight-first"},l.a.createElement("div",{className:"metric"},"230",l.a.createElement("label",null,"Unreviewed")),l.a.createElement("div",{className:"metric"},"300",l.a.createElement("label",null,"Approved")),l.a.createElement("div",{className:"metric"},"23",l.a.createElement("label",null,"Rejected"))))),l.a.createElement("div",{style:{marginTop:20}},l.a.createElement("a",{className:"App-link",href:"#",target:"_blank",rel:"noopener noreferrer"},"View all completed tasks \xbb"))),l.a.createElement("div",{className:"card export-data"},l.a.createElement("h3",null,l.a.createElement("span",{className:"badge"},"4"),l.a.createElement("em",null,"Export")," data"),l.a.createElement("p",null,"Output data for tasks is stored in:"," ",l.a.createElement("code",null,"/data//")),l.a.createElement("p",null,"Best practices:",l.a.createElement("ul",null,l.a.createElement("li",null,"Use a Jupyter notebook to post-process your data to encode reproducibility steps.")))))))},h=(t(43),t(27)),g=t.n(h),f=function(){return l.a.createElement("div",{style:{display:"flex",flexDirection:"row",maxWidth:1440,width:"100%",margin:"0 auto",alignItems:"flex-start"}},l.a.createElement("div",{className:"card"},l.a.createElement("h3",null,l.a.createElement("span",{className:"badge"},"3"),l.a.createElement("em",null,"Review")," data"),l.a.createElement("p",null,"You have"," ",l.a.createElement(u.b,{to:"/review",alt:"link"},"300 total HITs")," ","left to review across 5 tasks."),l.a.createElement("div",{style:{background:"#ee1054",margin:"0px -20px",padding:"5px 20px",color:"white",fontWeight:"bold"}},"Currently Reviewing Task:"),l.a.createElement("div",{className:"live-task"},l.a.createElement("div",{className:"title"},"LIGHT dialogue"),l.a.createElement("div",{className:"hyperparameters"},[null].map((function(){return Object.entries({dataset:"twitter",model:"v3.123",enableSafety:!0,saveDataFile:"localDB"}).map((function(e){var a=Object(E.a)(e,2),t=a[0],n=a[1];return l.a.createElement("span",{className:"hyperparameter"},l.a.createElement("span",{className:"key"},t),"=",l.a.createElement("span",{className:"value"},n.toString()))}))}))[0]),l.a.createElement("div",{className:"details"},l.a.createElement("div",{className:"metrics highlight-first"},l.a.createElement("div",{className:"metric"},"70",l.a.createElement("label",null,"Unreviewed")),l.a.createElement("div",{className:"metric"},"300",l.a.createElement("label",null,"Approved")),l.a.createElement("div",{className:"metric"},"23",l.a.createElement("label",null,"Rejected"))))),l.a.createElement("div",{style:{background:"#ee1054",margin:"0px -20px",padding:"5px 20px",color:"white",fontWeight:"bold"}},"Currently Reviewing User:"),l.a.createElement("div",{className:"user_info"},l.a.createElement("div",{className:"title"},"User #182"),l.a.createElement("div",{className:"hyperparameters"},[null].map((function(){return Object.entries({"All-Time Approved":"96%","All-Time Evaluated":"83",timezone:"EST",browser:"Chrome"}).map((function(e){var a=Object(E.a)(e,2),t=a[0],n=a[1];return l.a.createElement("span",{className:"hyperparameter"},l.a.createElement("span",{className:"key"},t),"=",l.a.createElement("span",{className:"value"},n.toString()))}))}))[0]),l.a.createElement("div",{className:"details"},l.a.createElement("div",{className:"metrics highlight-first"},l.a.createElement("div",{className:"metric"},"3/3",l.a.createElement("label",null,"Golden tasks")),l.a.createElement("div",{className:"metric"},"31",l.a.createElement("label",null,"Submitted")),l.a.createElement("div",{className:"metric"},"0",l.a.createElement("label",null,"Disconnects"))),l.a.createElement("div",{className:"metrics highlight-first anticipate-double",style:{marginTop:15}},l.a.createElement("div",{className:"metric"},"\u2014 / 0"," ",l.a.createElement("label",null,"Current Task: %\xa0Approved\xa0/\xa0#\xa0Evaluated"))))),l.a.createElement("div",{style:{backgroundColor:"#ffffcf",padding:"5px 10px 10px",border:"1px solid #f5f5e0"}},l.a.createElement("button",{className:"btn",style:{background:"green"}},"Approve"),l.a.createElement("button",{className:"btn"},"Approve all by this user"),l.a.createElement("button",{className:"btn",style:{background:"crimson"}},"Reject"))),l.a.createElement("div",{className:"card",style:{flex:"1",backgroundColor:"white",width:"100%",maxWidth:"none",margin:"15px 20px 0 10px",minHeight:300}},l.a.createElement("div",{className:"review-control-panel"},"\xa0"),l.a.createElement("div",{className:"task-frame",style:{backgroundColor:"white",color:"black"}},l.a.createElement("img",{src:g.a,width:"100%"}))))},b=(t(44),t(28)),N=t.n(b),y=(t(12),t(29)),k=t.n(y),w=(t(51),[{name:"QA Data Collection",desc:"Collect questions and answers from Turkers, given a random Wikipedia paragraph from SQuAD",tags:["qa","wikipedia","SQuAD"]},{name:"Model Evaluator",desc:"Ask Turkers to evaluate the information retrieval baseline model on the Reddit movie dialog dataset",tags:["reddit","evaluate"]},{name:"Multi-Agent Dialog",desc:"Round-robin chat between a local human agent and two Turkers",tags:["round-robin","dialog"]},{name:"Deal or No Deal",desc:"Negotiation chat between two agents over how to fairly divide a fixed set of items when each agent values the items differently",tags:["negotiation"]},{name:"Qualification Flow Example",desc:"Filter out workers from working on more instances of your task if they fail to complete a test instance properly",tags:["example"]},{name:"Semantic Alignment",desc:"Allow Turkers to pick matching words between a pair of sentences based on some criteria",tags:["sentences","matching"],initialData:'{\n "text1": "Brad and Angelina tied the knot on Friday",\n "text2": "Angelina got married to Brad on Friday"\n}'}]),x=function(){var e=l.a.useState(null),a=Object(E.a)(e,2),t=a[0],n=a[1],r=l.a.useState(""),c=Object(E.a)(r,2),s=c[0],i=c[1];return l.a.createElement("div",{style:{display:"flex",flexDirection:"row",maxWidth:1440,width:"100%",margin:"0 auto",alignItems:"stretch",padding:"0 20px",boxSizing:"border-box"}},l.a.createElement("div",{className:"card",style:{maxWidth:"none",width:"100%",minHeight:"300px",display:"flex"}},l.a.createElement("div",{className:"task-list"},l.a.createElement("input",{className:"search",placeholder:"search...",value:s,onChange:function(e){return i(e.target.value)}}),w.map((function(e,a){return(""===s||e.name.match(new RegExp(s,"i"))||e.tags.join(" ").match(new RegExp(s,"i")))&&l.a.createElement("div",{className:N()("task-list-item",{selected:a===t}),onClick:function(){return n(a)}},l.a.createElement("div",{className:"name"},e.name),l.a.createElement("div",{className:"tags"},e.tags.map((function(e){return l.a.createElement("span",null,"#",e)}))))})))," ",null!==t&&l.a.createElement("div",{className:"task-description",key:t},l.a.createElement("h1",null,w[t].name),l.a.createElement("p",null,w[t].desc),l.a.createElement("div",{className:"controls"},l.a.createElement("h3",null,"Pass ",l.a.createElement("code",null,"task_data"),":"),l.a.createElement(S,{id:t,initial:w[t].initialData||""}),l.a.createElement("button",{className:"btn inverse rounded"},"Submit")),l.a.createElement("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:10}},l.a.createElement("h3",null,"Live Example:"),l.a.createElement("div",null,"Viewing As:"," ",l.a.createElement("select",{style:{font:"inherit"}},l.a.createElement("option",null,"Worker"),l.a.createElement("option",null,"Teacher"),l.a.createElement("option",null,"Reviewer")))),l.a.createElement("iframe",{src:"https://codesandbox.io/embed/x3oy3myvyp?fontsize=14&hidenavigation=1&view=preview",title:"Paired Phrases Picker v0.1",style:{width:"100%",height:"500px",border:0,borderRadius:"4px",overflow:"hidden"},sandbox:"allow-modals allow-forms allow-popups allow-scripts allow-same-origin"}))))};function S(e){var a=e.initial,t=e.id,n=l.a.useState("test"),r=Object(E.a)(n,2);r[0],r[1];return l.a.createElement("div",{className:"text-container"},l.a.createElement(k.a,{highlightActiveLine:!1,value:a,style:{backgroundColor:"transparent",padding:"10px",width:"100%",fontSize:14,boxSizing:"border-box"},mode:"javascript",placeholder:"Type JSON payload here...",tabSize:2,maxLines:1/0,theme:"tuesday",height:"100px",showGutter:!1,showPrintMargin:!1,name:t,editorProps:{$blockScrolling:1/0}}))}t(53);function j(){return(j=Object.assign||function(e){for(var a=1;a=0||(l[t]=e[t]);return l}(e,a);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(l[t]=e[t])}return l}var A=l.a.createElement("title",null,"M"),T=l.a.createElement("desc",null,"Created with Sketch."),R=l.a.createElement("g",{id:"Page-1",stroke:"none",strokeWidth:1,fill:"none",fillRule:"evenodd",fontFamily:"Phosphate-Inline, Phosphate",fontSize:48,fontWeight:"normal",letterSpacing:-.8135598},l.a.createElement("g",{id:"Landing-Page",transform:"translate(-73.000000, -49.000000)",fill:"#2768FF"},l.a.createElement("text",{id:"M"},l.a.createElement("tspan",{x:72.4507799,y:82},"M")))),D=function(e){var a=e.svgRef,t=e.title,n=O(e,["svgRef","title"]);return l.a.createElement("svg",j({className:"logo",width:"35px",height:"33px",viewBox:"0 0 35 33",ref:a},n),void 0===t?A:t?l.a.createElement("title",null,t):null,T,R)},C=l.a.forwardRef((function(e,a){return l.a.createElement(D,j({svgRef:a},e))})),W=(t.p,function(e){function a(){return Object(s.a)(this,a),Object(m.a)(this,Object(o.a)(a).apply(this,arguments))}return Object(d.a)(a,e),Object(i.a)(a,[{key:"render",value:function(){return l.a.createElement("div",{className:"App"},l.a.createElement(u.a,null,l.a.createElement("header",{className:"App-header"},l.a.createElement(p.c,null,l.a.createElement(p.a,{exact:!0,path:"/",render:function(){return l.a.createElement(u.b,{to:"/dashboard"},l.a.createElement(C,null),"mephisto")}}),l.a.createElement(p.a,{render:function(){return l.a.createElement(u.b,{to:"/dashboard"},l.a.createElement(C,null),"mephisto")}}))),l.a.createElement(p.a,{exact:!0,path:"/",render:function(){return l.a.createElement(v,null)}}),l.a.createElement(p.a,{exact:!0,path:"/dashboard",render:function(){return l.a.createElement(v,null)}}),l.a.createElement(p.a,{exact:!0,path:"/task-gallery",render:function(){return l.a.createElement(x,null)}}),l.a.createElement(p.a,{exact:!0,path:"/review",render:function(){return l.a.createElement(f,null)}})))}}]),a}(n.Component));c.a.render(l.a.createElement(W,null),document.getElementById("root"))}},[[32,1,2]]]); +//# sourceMappingURL=main.d1c9df08.chunk.js.map \ No newline at end of file diff --git a/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js.map b/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js.map new file mode 100644 index 000000000..284e6f63e --- /dev/null +++ b/mephisto/client/full/webapp/build/static/js/main.d1c9df08.chunk.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["sample.png","Dashboard.js","Review.js","TaskGallery.js","M.svg","App.js","index.js"],"names":["module","exports","className","href","target","rel","to","map","i","Object","entries","dataset","model","enableSafety","saveDataFile","key","value","toString","alt","style","marginTop","display","flexDirection","maxWidth","width","margin","alignItems","background","padding","color","fontWeight","timezone","browser","backgroundColor","border","flex","minHeight","src","samplePic","data_model","name","desc","tags","initialData","React","useState","selectedIndex","setSelectedIndex","searchTerm","setSearchTerm","boxSizing","placeholder","onChange","e","task","idx","match","RegExp","join","cx","selected","onClick","tag","JSONEditor","id","initial","justifyContent","marginBottom","font","title","height","borderRadius","overflow","sandbox","highlightActiveLine","fontSize","mode","tabSize","maxLines","Infinity","theme","showGutter","showPrintMargin","editorProps","$blockScrolling","_extends","assign","arguments","length","source","prototype","hasOwnProperty","call","apply","this","_objectWithoutProperties","excluded","sourceKeys","keys","indexOf","_objectWithoutPropertiesLoose","getOwnPropertySymbols","sourceSymbolKeys","propertyIsEnumerable","createElement","stroke","strokeWidth","fill","fillRule","fontFamily","letterSpacing","transform","x","y","_ref","svgRef","props","viewBox","ref","undefined","ForwardRef","forwardRef","App","exact","path","render","Dashboard","TaskGallery","Review","Component","ReactDOM","document","getElementById"],"mappings":"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","file":"static/js/main.d1c9df08.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/sample.44730b5b.png\";","import React from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport default () => (\n
\n
\n
\n
\n

\n 1\n Create a task\n

\n {/*

\nEdit src/App.js and save to reload.\n

*/}\n
\n

\n You will need an MTurk Requester Account and an AWS account\n (separate accounts).\n \n Setting up AWS »\n \n

\n

\n We have a growing collection of tasks already available. You can\n re-use one of them, clone & modify one of them to create a\n similar yet different task, or create a completely new custom task\n altogether. Custom tasks can range from simple static pages, to\n multi-agent dialogue, to dynamic & interactive React\n applications!\n \n View gallery of existing tasks »\n \n \n Create a custom task »\n \n

\n
\n
\n
\n

\n 2\n Launch tasks\n

\n

\n You currently have 3 tasks running live.\n

\n {[1, 2, 3].map(i => (\n
\n
\n {i > 1 ? \"semantic annotation\" : \"LIGHT pilot (v2)\"}\n {i === 1 && Sandbox}\n
\n
\n {\n [null].map(() => {\n return Object.entries({\n dataset: \"twitter\",\n model: \"v3.123\",\n enableSafety: true,\n saveDataFile: \"localDB\"\n }).map(([key, value]) => (\n \n {key}=\n {value.toString()}\n \n ));\n })[0]\n }\n
\n
\n Started 8 hours ago. 25 completed HITs. 3 disconnects.\n
\n
\n ))}\n \n
\n
\n

\n 3\n Review data\n

\n {/*

\nEdit src/App.js and save to reload.\n

*/}\n {/* {[{amount: 12, daysPending: 1}]} */}\n

\n You have{\" \"}\n \n 300 HITs\n {\" \"}\n left to review.\n

\n {/*

\n \n 10 tasks\n {\" \"}\n will be auto-reviewed by tomorrow.\n

*/}\n\n \n
\n
LIGHT dialogue
\n
\n {\n [null].map(() => {\n return Object.entries({\n dataset: \"twitter\",\n model: \"v3.123\",\n enableSafety: true,\n saveDataFile: \"localDB\"\n }).map(([key, value]) => (\n \n {key}=\n {value.toString()}\n \n ));\n })[0]\n }\n
\n
\n
\n
\n 70\n
\n
\n 300\n
\n
\n 23\n
\n
\n {/* Reviewed: 300 | Unreviewed: 80 */}\n

\n Warning: 10 HITs are nearing their 2 week deadline and risk\n being auto-approved.\n

\n
\n
\n \n
\n
LIGHT dialogue (pilot v1)
\n
\n {\n [null].map(() => {\n return Object.entries({\n dataset: \"twitter\",\n model: \"v3.123\",\n enableSafety: true,\n saveDataFile: \"localDB\"\n }).map(([key, value]) => (\n \n {key}=\n {value.toString()}\n \n ));\n })[0]\n }\n
\n
\n
\n
\n 230\n
\n
\n 300\n
\n
\n 23\n
\n
\n
\n
\n
\n \n View all completed tasks »\n \n
\n {/*
\n  \n
\n
\n  \n
*/}\n
\n
\n

\n 4\n Export data\n

\n

\n Output data for tasks is stored in:{\" \"}\n /data/<task-name>/<run-id>\n

\n

\n Best practices:\n

    \n
  • \n Use a Jupyter notebook to post-process your data to encode\n reproducibility steps.\n
  • \n
\n

\n
\n
\n
\n
\n);\n","import React from \"react\";\nimport { Link } from \"react-router-dom\";\nimport \"./review.css\";\nimport samplePic from \"./sample.png\"\n\nexport default () => (\n \n
\n

\n 3\n Review data\n

\n

\n You have{\" \"}\n \n 300 total HITs\n {\" \"}\n left to review across 5 tasks.\n

\n \n Currently Reviewing Task:\n
\n
\n
LIGHT dialogue
\n
\n {\n [null].map(() => {\n return Object.entries({\n dataset: \"twitter\",\n model: \"v3.123\",\n enableSafety: true,\n saveDataFile: \"localDB\"\n }).map(([key, value]) => (\n \n {key}=\n {value.toString()}\n \n ));\n })[0]\n }\n
\n
\n
\n
\n 70\n
\n
\n 300\n
\n
\n 23\n
\n
\n\n {/*

\n Warning: 10 HITs are nearing their 2 week deadline and risk being\n auto-approved.\n

*/}\n
\n
\n \n Currently Reviewing User:\n
\n\n
\n
User #182
\n
\n {\n [null].map(() => {\n return Object.entries({\n \"All-Time Approved\": \"96%\",\n \"All-Time Evaluated\": \"83\",\n timezone: \"EST\",\n browser: \"Chrome\"\n }).map(([key, value]) => (\n \n {key}=\n {value.toString()}\n \n ));\n })[0]\n }\n
\n
\n
\n
\n 3/3\n
\n
\n 31\n
\n
\n 0\n
\n
\n \n
\n — / 0{\" \"}\n \n
\n {/*
\n 96% / 3,000{\" \"}\n \n
*/}\n
\n
\n \n \n \n \n \n \n \n \n
 
\n \n \n \n \n \n);\n","import React from \"react\";\nimport \"./taskgallery.css\";\nimport cx from \"classnames\";\n\nimport brace from \"brace\";\nimport AceEditor from \"react-ace\";\nimport \"brace/mode/javascript\";\n\nconst data_model = [\n {\n name: \"QA Data Collection\",\n desc:\n \"Collect questions and answers from Turkers, given a random Wikipedia paragraph from SQuAD\",\n tags: [\"qa\", \"wikipedia\", \"SQuAD\"]\n },\n {\n name: \"Model Evaluator\",\n desc:\n \"Ask Turkers to evaluate the information retrieval baseline model on the Reddit movie dialog dataset\",\n tags: [\"reddit\", \"evaluate\"]\n },\n {\n name: \"Multi-Agent Dialog\",\n desc: \"Round-robin chat between a local human agent and two Turkers\",\n tags: [\"round-robin\", \"dialog\"]\n },\n {\n name: \"Deal or No Deal\",\n desc:\n \"Negotiation chat between two agents over how to fairly divide a fixed set of items when each agent values the items differently\",\n tags: [\"negotiation\"]\n },\n {\n name: \"Qualification Flow Example\",\n desc:\n \"Filter out workers from working on more instances of your task if they fail to complete a test instance properly\",\n tags: [\"example\"]\n },\n {\n name: \"Semantic Alignment\",\n desc:\n \"Allow Turkers to pick matching words between a pair of sentences based on some criteria\",\n tags: [\"sentences\", \"matching\"],\n initialData: `{\n \"text1\": \"Brad and Angelina tied the knot on Friday\",\n \"text2\": \"Angelina got married to Brad on Friday\"\n}`\n }\n];\n\nexport default () => {\n const [selectedIndex, setSelectedIndex] = React.useState(null);\n const [searchTerm, setSearchTerm] = React.useState(\"\");\n\n return (\n \n \n
\n setSearchTerm(e.target.value)}\n />\n {data_model.map(\n (task, idx) =>\n (searchTerm === \"\" ||\n task.name.match(new RegExp(searchTerm, \"i\")) ||\n task.tags.join(\" \").match(new RegExp(searchTerm, \"i\"))) && (\n setSelectedIndex(idx)}\n >\n
{task.name}
\n
\n {task.tags.map(tag => (\n #{tag}\n ))}\n
\n
\n )\n )}\n {\" \"}\n {selectedIndex !== null && (\n
\n

{data_model[selectedIndex].name}

\n

{data_model[selectedIndex].desc}

\n
\n

\n Pass task_data:\n

\n {/*