diff --git a/.codacy.yml b/.codacy.yml index 7e85c730..5363e2b1 100644 --- a/.codacy.yml +++ b/.codacy.yml @@ -1,5 +1,5 @@ exclude_paths: - - '**/3rdparty/**' - - '**/engine/js/cvat-core.min.js' - - '**/engine/js/unzip_imgs.js' - - CHANGELOG.md + - '**/3rdparty/**' + - '**/engine/js/cvat-core.min.js' + - '**/engine/js/unzip_imgs.js' + - CHANGELOG.md diff --git a/.coveragerc b/.coveragerc index f174f846..6e95757c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -3,13 +3,10 @@ branch = true # relative_files = true # does not work? source = - datumaro/datumaro/ cvat/apps/ utils/cli/ omit = - datumaro/datumaro/__main__.py - datumaro/datumaro/version.py cvat/settings/* */tests/* */test_* diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..54f42aa5 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,10 @@ +.*/ +3rdparty/ +node_modules/ +dist/ +data/ +datumaro/ +keys/ +logs/ +static/ +templates/ diff --git a/.eslintrc.js b/.eslintrc.js index a8731c42..b171226f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,53 +1,23 @@ -/* - * Copyright (C) 2018 Intel Corporation - * - * SPDX-License-Identifier: MIT - */ +// Copyright (C) 2018-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT - module.exports = { - "env": { - "node": false, - "browser": true, - "es6": true, - "jquery": true, - "qunit": true, +module.exports = { + env: { + node: true, + browser: true, + es6: true, }, - "parserOptions": { - "sourceType": "script", + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018, }, - "plugins": [ - "security", - "no-unsanitized", - "no-unsafe-innerhtml", - ], - "extends": [ - "eslint:recommended", - "plugin:security/recommended", - "plugin:no-unsanitized/DOM", - "airbnb-base", - ], - "rules": { - "no-await-in-loop": [0], - "global-require": [0], - "no-new": [0], - "class-methods-use-this": [0], - "no-restricted-properties": [0, { - "object": "Math", - "property": "pow", - }], - "no-param-reassign": [0], - "no-underscore-dangle": ["error", { "allowAfterThis": true }], - "no-restricted-syntax": [0, {"selector": "ForOfStatement"}], - "no-continue": [0], - "no-unsafe-innerhtml/no-unsafe-innerhtml": 1, - // This rule actual for user input data on the node.js environment mainly. - "security/detect-object-injection": 0, - "indent": ["warn", 4], - // recently added to airbnb - "max-classes-per-file": [0], - // it was opposite before and our code has been written according to previous rule - "arrow-parens": [0], - // object spread is a modern ECMA standard. Let's do not use it without babel - "prefer-object-spread": [0], + plugins: ['eslint-plugin-header'], + extends: ['eslint:recommended', 'prettier'], + rules: { + 'header/header': [2, 'line', [{ + pattern: ' {1}Copyright \\(C\\) (?:20\\d{2}-)?2020 Intel Corporation', + template: ' Copyright (C) 2020 Intel Corporation' + }, '', ' SPDX-License-Identifier: MIT']], }, }; diff --git a/.gitignore b/.gitignore index cbe91f69..e985f4ef 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ yarn-debug.log* yarn-error.log* .DS_Store + +#Ignore Cypress tests temp files +/tests/cypress/fixtures +/tests/cypress/screenshots diff --git a/.nycrc b/.nycrc new file mode 100644 index 00000000..7438d774 --- /dev/null +++ b/.nycrc @@ -0,0 +1,17 @@ +{ + "all": true, + "compact": false, + "extension": [ + ".js", + ".jsx", + ".ts", + ".tsx" + ], + "exclude": [ + "**/3rdparty/*", + "**/tests/*" + ], + "parser-plugins": [ + "typescript" + ] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..54f42aa5 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,10 @@ +.*/ +3rdparty/ +node_modules/ +dist/ +data/ +datumaro/ +keys/ +logs/ +static/ +templates/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..2bd8f204 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,27 @@ +{ + "arrowParens": "always", + "bracketSpacing": true, + "embeddedLanguageFormatting": "auto", + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "jsxBracketSameLine": false, + "jsxSingleQuote": true, + "printWidth": 120, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": true, + "singleQuote": true, + "tabWidth": 4, + "trailingComma": "all", + "useTabs": false, + "vueIndentScriptAndStyle": false, + "overrides": [ + { + "files": ["*.json", "*.yml", "*.yaml", "*.md"], + "options": { + "tabWidth": 2 + } + } + ] +} diff --git a/.remarkrc.js b/.remarkrc.js index 1daf8b83..e57d403a 100644 --- a/.remarkrc.js +++ b/.remarkrc.js @@ -1,16 +1,16 @@ -exports.settings = {bullet: '*', paddedTable: false} +exports.settings = { bullet: '*', paddedTable: false }; exports.plugins = [ - 'remark-preset-lint-recommended', - 'remark-preset-lint-consistent', - ['remark-preset-lint-markdown-style-guide', 'mixed'], - ['remark-lint-no-dead-urls', { skipOffline: true }], - ['remark-lint-maximum-line-length', 120], - ['remark-lint-maximum-heading-length', 120], - ['remark-lint-strong-marker', "*"], - ['remark-lint-emphasis-marker', "_"], - ['remark-lint-unordered-list-marker-style', "-"], - ['remark-lint-ordered-list-marker-style', "."], - ['remark-lint-no-file-name-irregular-characters', false], - ['remark-lint-list-item-spacing', false], -] + 'remark-preset-lint-recommended', + 'remark-preset-lint-consistent', + ['remark-preset-lint-markdown-style-guide', 'mixed'], + ['remark-lint-no-dead-urls', { skipOffline: true }], + ['remark-lint-maximum-line-length', 120], + ['remark-lint-maximum-heading-length', 120], + ['remark-lint-strong-marker', '*'], + ['remark-lint-emphasis-marker', '_'], + ['remark-lint-unordered-list-marker-style', '-'], + ['remark-lint-ordered-list-marker-style', '.'], + ['remark-lint-no-file-name-irregular-characters', false], + ['remark-lint-list-item-spacing', false], +]; diff --git a/.stylelintrc.json b/.stylelintrc.json index 4a37e44d..44333abf 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,20 +1,22 @@ { - "extends": "stylelint-config-standard", - "rules": { - "indentation": 4, - "value-keyword-case": null, - "selector-combinator-space-after": null, - "no-descending-specificity": null, - "at-rule-no-unknown": [true, { - "ignoreAtRules": ["extend"] - }], - "selector-type-no-unknown": [true, { - "ignoreTypes": ["first-child"] - }] - }, - "ignoreFiles": [ - "**/*.js", - "**/*.ts", - "**/*.py" + "extends": "stylelint-config-standard", + "rules": { + "indentation": 4, + "value-keyword-case": null, + "selector-combinator-space-after": null, + "no-descending-specificity": null, + "at-rule-no-unknown": [ + true, + { + "ignoreAtRules": ["extend"] + } + ], + "selector-type-no-unknown": [ + true, + { + "ignoreTypes": ["first-child"] + } ] + }, + "ignoreFiles": ["**/*.js", "**/*.ts", "**/*.py"] } diff --git a/.travis.yml b/.travis.yml index 68533c0d..cc72db8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ -sudo: required - -language: python - -python: - - "3.5" +language: generic +dist: focal cache: npm: true @@ -11,9 +7,11 @@ cache: - ~/.cache addons: + firefox: 'latest' + chrome: stable apt: packages: - - libgconf-2-4 + - libgconf-2-4 services: - docker @@ -25,25 +23,34 @@ env: DJANGO_SU_EMAIL="admin@localhost.company" DJANGO_SU_PASSWORD="12qwaszx" NODE_VERSION="12" + API_ABOUT_PAGE="localhost:8080/api/v1/server/about" before_install: - nvm install ${NODE_VERSION} before_script: - - docker-compose -f docker-compose.yml -f docker-compose.ci.yml build - chmod a+rwx ${HOST_COVERAGE_DATA_DIR} script: - # FIXME: Git package and application name conflict in PATH and try to leave only one python test execution - - docker-compose -f docker-compose.yml -f docker-compose.ci.yml run cvat_ci /bin/bash -c 'coverage run -a manage.py test cvat/apps && coverage run -a manage.py test --pattern="_test*.py" cvat/apps/dataset_manager/tests cvat/apps/engine/tests utils/cli && coverage run -a manage.py test datumaro/ && mv .coverage ${CONTAINER_COVERAGE_DATA_DIR}' - - docker-compose -f docker-compose.yml -f docker-compose.ci.yml run cvat_ci /bin/bash -c 'cd cvat-data && npm install && cd ../cvat-core && npm install && npm run test && coveralls-lcov -v -n ./reports/coverage/lcov.info > ${CONTAINER_COVERAGE_DATA_DIR}/coverage.json' - # Up all containers + - if [[ $TRAVIS_EVENT_TYPE == "cron" && $TRAVIS_BRANCH == "develop" ]]; + then + docker-compose -f docker-compose.yml -f ./tests/docker-compose.email.yml up -d --build; + bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done'; + docker exec -it cvat bash -ic "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell"; + cd ./tests && npm install && npm run cypress:run:firefox; exit $?; + fi; + - docker-compose -f docker-compose.yml -f docker-compose.ci.yml build + - docker-compose -f docker-compose.yml -f docker-compose.ci.yml run cvat_ci /bin/bash -c 'coverage run -a manage.py test cvat/apps utils/cli && mv .coverage ${CONTAINER_COVERAGE_DATA_DIR}' + - docker-compose -f docker-compose.yml -f docker-compose.ci.yml run cvat_ci /bin/bash -c 'cd cvat-data && npm install && cd ../cvat-core && npm install && npm run test && mv ./reports/coverage/lcov.info ${CONTAINER_COVERAGE_DATA_DIR} && chmod a+rwx ${CONTAINER_COVERAGE_DATA_DIR}/lcov.info' - docker-compose up -d - # Create superuser - docker exec -it cvat bash -ic "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" - # Install Cypress and run tests - - cd ./tests && npm install - - $(npm bin)/cypress run --headless --browser chrome && cd .. + # End-to-end testing + - npm install && npm run coverage + - docker-compose up -d --build + - cd ./tests && npm install && npx cypress run --headless --browser chrome + - mv ./.nyc_output ../ && cd .. + - npx nyc report --reporter=text-lcov >> ${HOST_COVERAGE_DATA_DIR}/lcov.info + - docker-compose -f docker-compose.yml -f docker-compose.ci.yml run cvat_ci /bin/bash -c 'cd ${CONTAINER_COVERAGE_DATA_DIR} && coveralls-lcov -v -n lcov.info > ${CONTAINER_COVERAGE_DATA_DIR}/coverage.json' after_success: # https://coveralls-python.readthedocs.io/en/latest/usage/multilang.html diff --git a/.vscode/launch.json b/.vscode/launch.json index 48bc4583..d6e8e878 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,6 +21,21 @@ }, "smartStep": true, }, + { + "type": "node", + "request": "launch", + "name": "ui.js: test", + "cwd": "${workspaceRoot}/tests", + "runtimeExecutable": "${workspaceRoot}/tests/node_modules/.bin/cypress", + "args": [ + "run", + "--headless", + "--browser", + "chrome" + ], + "outputCapture": "std", + "console": "internalConsole" + }, { "name": "server: django", "type": "python", diff --git a/.vscode/python.env b/.vscode/python.env deleted file mode 100644 index a624ab13..00000000 --- a/.vscode/python.env +++ /dev/null @@ -1 +0,0 @@ -PYTHONPATH="datumaro/:$PYTHONPATH" \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 3b796a0b..7efcd4e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,37 +1,26 @@ { "python.pythonPath": ".env/bin/python", "eslint.enable": true, - "eslint.validate": [ + "eslint.probe": [ "javascript", "typescript", - "typescriptreact", + "typescriptreact" ], + "eslint.onIgnoredFiles": "warn", "eslint.workingDirectories": [ { - "directory": "./cvat-core", - "changeProcessCWD": true + "directory": "${cwd}", }, { - "directory": "./cvat-canvas", - "changeProcessCWD": true + "pattern": "cvat-*" }, { - "directory": "./cvat-ui", - "changeProcessCWD": true - }, - { - "directory": ".", - "changeProcessCWD": true + "directory": "tests", + "!cwd": true } ], "python.linting.pylintEnabled": true, - "python.envFile": "${workspaceFolder}/.vscode/python.env", "python.testing.unittestEnabled": true, - "python.testing.unittestArgs": [ - "-v", - "-s", - "./datumaro", - ], "licenser.license": "Custom", "licenser.customHeader": "Copyright (C) @YEAR@ Intel Corporation\n\nSPDX-License-Identifier: MIT", "files.trimTrailingWhitespace": true diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1d1dd3..6b7d6452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,127 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.0] - 2020-01-08 + +### Fixed + +- Memory consumption for the task creation process () +- Frame preloading () +- Project cannot be removed from the project page () + +## [1.2.0-beta] - 2020-12-15 + +### Added + +- GPU support and improved documentation for auto annotation () +- Manual review pipeline: issues/comments/workspace () +- Basic projects implementation () +- Documentation on how to mount cloud starage(AWS S3 bucket, Azure container, Google Drive) as FUSE () +- Ability to work with share files without copying inside () +- Tooltips in label selectors () +- Page redirect after login using `next` query parameter () +- [ImageNet](http://www.image-net.org) format support () +- [CamVid](http://mi.eng.cam.ac.uk/research/projects/VideoRec/CamVid/) format support () + +### Changed + +- PATCH requests from cvat-core submit only changed fields () +- deploy.sh in serverless folder is seperated into deploy_cpu.sh and deploy_gpu.sh () +- Bumped nuclio version to 1.5.8 +- Migrated to Antd 4.9 () + +### Fixed + +- Fixed FastRCNN inference bug for images with 4 channels i.e. png () +- Django templates for email and user guide () +- Saving relative paths in dummy chunks instead of absolute () +- Objects with a specific label cannot be displayed if at least one tag with the label exist () +- Wrong attribute can be removed in labels editor () +- UI fails with the error "Cannot read property 'label' of undefined" () +- Exception: "Value must be a user instance" () +- Reset zoom option doesn't work in tag annotation mode () +- Canvas is busy error () +- Projects view layout fix () +- Fixed the tasks view (infinite loading) when it is impossible to get a preview of the task () +- Empty frames navigation () +- TypeError: Cannot read property 'toString' of undefined () +- Extra shapes are drawn after Esc, or G pressed while drawing a region in grouping () +- Reset state (reviews, issues) after logout or changing a job () +- TypeError: Cannot read property 'id' of undefined when updating a task () + +## [1.2.0-alpha] - 2020-11-09 + +### Added + +- Ability to login into CVAT-UI with token from api/v1/auth/login () +- Added layout grids toggling ('ctrl + alt + Enter') +- Added password reset functionality () +- Ability to work with data on the fly (https://github.com/opencv/cvat/pull/2007) +- Annotation in process outline color wheel () +- On the fly annotation using DL detectors () +- Displaying automatic annotation progress on a task view () +- Automatic tracking of bounding boxes using serverless functions () +- [Datumaro] CLI command for dataset equality comparison () +- [Datumaro] Merging of datasets with different labels () +- Add FBRS interactive segmentation serverless function () +- Ability to change default behaviour of previous/next buttons of a player. + It supports regular navigation, searching a frame according to annotations + filters and searching the nearest frame without any annotations () +- MacOS users notes in CONTRIBUTING.md +- Ability to prepare meta information manually () +- Ability to upload prepared meta information along with a video when creating a task () +- Optional chaining plugin for cvat-canvas and cvat-ui () +- MOTS png mask format support () +- Ability to correct upload video with a rotation record in the metadata () +- User search field for assignee fields () +- Support of mxf videos () + +### Changed + +- UI models (like DEXTR) were redesigned to be more interactive () +- Used Ubuntu:20.04 as a base image for CVAT Dockerfile () +- Right colors of label tags in label mapping when a user runs automatic detection () +- Nuclio became an optional component of CVAT () +- A key to remove a point from a polyshape [Ctrl => Alt] () +- Updated `docker-compose` file version from `2.3` to `3.3`() +- Added auto inference of url schema from host in CLI, if provided () +- Track frames in skips between annotation is presented in MOT and MOTS formats are marked `outside` () +- UI packages installation with `npm ci` instead of `npm install` () + +### Removed + +- Removed Z-Order flag from task creation process + +### Fixed + +- Fixed multiple errors which arises when polygon is of length 5 or less () +- Fixed task creation from PDF () +- Fixed CVAT format import for frame stepped tasks () +- Fixed the reading problem with large PDFs () +- Fixed unnecessary pyhash dependency () +- Fixed Data is not getting cleared, even after deleting the Task from Django Admin App() +- Fixed blinking message: "Some tasks have not been showed because they do not have any data" () +- Fixed case when a task with 0 jobs is shown as "Completed" in UI () +- Fixed use case when UI throws exception: Cannot read property 'objectType' of undefined #2053 () +- Fixed use case when logs could be saved twice or more times #2202 () +- Fixed issues from #2112 () +- Git application name (renamed to dataset_repo) () +- A problem in exporting of tracks, where tracks could be truncated () +- Fixed CVAT startup process if the user has `umask 077` in .bashrc file () +- Exception: Cannot read property "each" of undefined after drawing a single point () +- Cannot read property 'label' of undefined (Fixed?) () +- Excluded track frames marked `outside` in `CVAT for Images` export () +- 'List of tasks' Kibana visualization () +- An error on exporting not `jpg` or `png` images in TF Detection API format () + ## [1.1.0] - 2020-08-31 + ### Added + - Siammask tracker as DL serverless function () - [Datumaro] Added model info and source info commands () - [Datumaro] Dataset statistics () @@ -16,18 +132,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Notification message when users use wrong browser () ### Changed + - Shape coordinates are rounded to 2 digits in dumped annotations () - COCO format does not produce polygon points for bbox annotations () ### Fixed + - Issue loading openvino models for semi-automatic and automatic annotation () - Basic functions of CVAT works without activated nuclio dashboard - Fixed a case in which exported masks could have wrong color order () - Fixed error with creating task with labels with the same name () - Django RQ dashboard view () +- Object's details menu settings () ## [1.1.0-beta] - 2020-08-03 + ### Added + - DL models as serverless functions () - Source type support for tags, shapes and tracks () - Source type support for CVAT Dumper/Loader () @@ -38,16 +159,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ability to change user password () ### Changed + - Smaller object details () - `COCO` format does not convert bboxes to polygons on export () - It is impossible to submit a DL model in OpenVINO format using UI. Now you can deploy new models on the server using serverless functions () - Files and folders under share path are now alphabetically sorted ### Removed + - Removed OpenVINO and CUDA components because they are not necessary anymore () - Removed the old UI code () ### Fixed + - Some objects aren't shown on canvas sometimes. For example after propagation on of objects is invisible () - CVAT doesn't offer to restore state after an error () - Cannot read property 'shapeType' of undefined because of zOrder related issues () @@ -68,7 +192,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Increase rate of throttling policy for unauthenticated users () ## [1.1.0-alpha] - 2020-06-30 + ### Added + - Throttling policy for unauthenticated users () - Added default label color table for mask export () - Added environment variables for Redis and Postgres hosts for Kubernetes deployment support () @@ -96,6 +222,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Datumaro] Added image copying when exporting datasets, if possible () ### Changed + - Removed information about e-mail from the basic user information () - Update https install manual. Makes it easier and more robust. Includes automatic renewing of lets encrypt certificates. - Settings page move to the modal. () @@ -107,6 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Datumaro] Annotation-less files are not generated anymore in COCO format, unless tasks explicitly requested () ### Fixed + - Problem with exported frame stepped image task () - Fixed dataset filter item representation for imageless dataset items () - Fixed interpreter crash when trying to import `tensorflow` with no AVX instructions available () @@ -127,10 +255,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Error when interpolating polygons () ### Security + - SQL injection in Django `CVE-2020-9402` () ## [1.0.0] - 2020-05-29 + ### Added + - cvat-ui: cookie policy drawer for login page () - `datumaro_project` export format () - Ability to configure user agreements for the user registration form () @@ -139,6 +270,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ability to configure access to the analytics page based on roles () ### Changed + - Downloaded file name in annotations export became more informative () - Added auto trimming for trailing whitespaces style enforcement () - REST API: updated `GET /task//annotations`: parameters are `format`, `filename` (now optional), `action` (optional) () @@ -152,10 +284,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Images without annotations now also included in dataset/annotations export () ### Removed + - `annotation` application is replaced with `dataset_manager` () - `_DATUMARO_INIT_LOGLEVEL` env. variable is removed in favor of regular `--loglevel` cli parameter () ### Fixed + - Categories for empty projects with no sources are taken from own dataset () - Added directory removal on error during `extract` command () - Added debug error message on incorrect XPath () @@ -173,7 +307,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed COCO keypoints skeleton parsing and saving () - `tf.placeholder() is not compatible with eager execution` exception for auto_segmentation () - Canvas cannot be moved with move functionality on left mouse key () -- Deep extreme cut request is sent when draw any shape with Make AI polygon option enabled () +- Deep extreme cut request is sent when draw any shape with Make AI polygon option enabled () - Fixed an error when exporting a task with cuboids to any format except CVAT () - Synchronization with remote git repo () - A problem with mask to polygons conversion when polygons are too small () @@ -181,19 +315,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed an issue with `z_order` having no effect on segmentations () ### Security + - Permission group whitelist check for analytics view () ## [1.0.0-beta.2] - 2020-04-30 + ### Added + - Re-Identification algorithm to merging bounding boxes automatically to the new UI () -- Methods ``import`` and ``export`` to import/export raw annotations for Job and Task in ``cvat-core`` () -- Versioning of client packages (``cvat-core``, ``cvat-canvas``, ``cvat-ui``). Initial versions are set to 1.0.0 () +- Methods `import` and `export` to import/export raw annotations for Job and Task in `cvat-core` () +- Versioning of client packages (`cvat-core`, `cvat-canvas`, `cvat-ui`). Initial versions are set to 1.0.0 () - Cuboids feature was migrated from old UI to new one. () ### Removed + - Annotation convertation utils, currently supported natively via Datumaro framework (https://github.com/opencv/cvat/pull/1477) ### Fixed + - Auto annotation, TF annotation and Auto segmentation apps (https://github.com/opencv/cvat/pull/1409) - Import works with truncated images now: "OSError:broken data stream" on corrupt images (https://github.com/opencv/cvat/pull/1430) - Hide functionality (H) doesn't work () @@ -210,8 +349,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Open task button doesn't work (https://github.com/opencv/cvat/pull/1474) ## [1.0.0-beta.1] - 2020-04-15 + ### Added -- Special behaviour for attribute value ``__undefined__`` (invisibility, no shortcuts to be set in AAM) + +- Special behaviour for attribute value `__undefined__` (invisibility, no shortcuts to be set in AAM) - Dialog window with some helpful information about using filters - Ability to display a bitmap in the new UI - Button to reset colors settings (brightness, saturation, contrast) in the new UI @@ -223,13 +364,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Deep extreme cut (semi-automatic segmentation) to the new UI (https://github.com/opencv/cvat/pull/1398) ### Changed + - Increase preview size of a task till 256, 256 on the server - Public ssh-keys are displayed in a dedicated window instead of console when create a task with a repository - React UI is the primary UI ### Fixed + - Cleaned up memory in Auto Annotation to enable long running tasks on videos -- New shape is added when press ``esc`` when drawing instead of cancellation +- New shape is added when press `esc` when drawing instead of cancellation - Dextr segmentation doesn't work. - `FileNotFoundError` during dump after moving format files - CVAT doesn't append outside shapes when merge polyshapes in old UI @@ -254,23 +397,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Uploading annotations for tasks with multiple jobs (https://github.com/opencv/cvat/pull/1396) ## [1.0.0-alpha] - 2020-03-31 + ### Added + - Data streaming using chunks (https://github.com/opencv/cvat/pull/1007) - New UI: showing file names in UI (https://github.com/opencv/cvat/pull/1311) - New UI: delete a point from context menu (https://github.com/opencv/cvat/pull/1292) ### Fixed + - Git app cannot clone a repository (https://github.com/opencv/cvat/pull/1330) - New UI: preview position in task details (https://github.com/opencv/cvat/pull/1312) - AWS deployment (https://github.com/opencv/cvat/pull/1316) ## [0.6.1] - 2020-03-21 + ### Changed + - VOC task export now does not use official label map by default, but takes one from the source task to avoid primary-class and class part name clashing ([#1275](https://github.com/opencv/cvat/issues/1275)) ### Fixed + - File names in LabelMe format export are no longer truncated ([#1259](https://github.com/opencv/cvat/issues/1259)) - `occluded` and `z_order` annotation attributes are now correctly passed to Datumaro ([#1271](https://github.com/opencv/cvat/pull/1271)) - Annotation-less tasks now can be exported as empty datasets in COCO ([#1277](https://github.com/opencv/cvat/issues/1277)) @@ -278,11 +427,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 allowed `frame_XXXXXX[.ext]` format ([#1274](https://github.com/opencv/cvat/pull/1274)) ### Security + - Bump acorn from 6.3.0 to 6.4.1 in /cvat-ui ([#1270](https://github.com/opencv/cvat/pull/1270)) ## [0.6.0] - 2020-03-15 + ### Added -- Server only support for projects. Extend REST API v1 (/api/v1/projects*) + +- Server only support for projects. Extend REST API v1 (/api/v1/projects\*) - Ability to get basic information about users without admin permissions ([#750](https://github.com/opencv/cvat/issues/750)) - Changed REST API: removed PUT and added DELETE methods for /api/v1/users/ID - Mask-RCNN Auto Annotation Script in OpenVINO format @@ -299,6 +451,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Git repositories can be specified with IPv4 address ([#827](https://github.com/opencv/cvat/pull/827)) ### Changed + - page_size parameter for all REST API methods - React & Redux & Antd based dashboard - Yolov3 interpretation script fix and changes to mapping.json @@ -306,6 +459,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for OpenVINO 2020 ### Fixed + - Exception in Git plugin [#826](https://github.com/opencv/cvat/issues/826) - Label ids in TFrecord format now start from 1 [#866](https://github.com/opencv/cvat/issues/866) - Mask problem in COCO JSON style [#718](https://github.com/opencv/cvat/issues/718) @@ -314,15 +468,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Annotations can be filtered before dumping with Datumaro [#994](https://github.com/opencv/cvat/issues/994) ## [0.5.2] - 2019-12-15 + ### Fixed + - Frozen version of scikit-image==0.15 in requirements.txt because next releases don't support Python 3.5 ## [0.5.1] - 2019-10-17 + ### Added + - Integration with Zenodo.org (DOI) ## [0.5.0] - 2019-09-12 + ### Added + - A converter to YOLO format - Installation guide - Linear interpolation for a single point @@ -341,13 +501,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added command line tool for performing common task operations (/utils/cli/) ### Changed + - Outside and keyframe buttons in the side panel for all interpolation shapes (they were only for boxes before) - Improved error messages on the client side (#511) ### Removed + - "Flip images" has been removed. UI now contains rotation features. ### Fixed + - Incorrect width of shapes borders in some cases - Annotation parser for tracks with a start frame less than the first segment frame - Interpolation on the server near outside frames @@ -365,43 +528,56 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Creating a video task with 0 overlap ### Security + - Upgraded Django, djangorestframework, and other packages ## [0.4.2] - 2019-06-03 + ### Fixed + - Fixed interaction with the server share in the auto annotation plugin ## [0.4.1] - 2019-05-14 + ### Fixed + - JavaScript syntax incompatibility with Google Chrome versions less than 72 ## [0.4.0] - 2019-05-04 + ### Added + - OpenVINO auto annotation: it is possible to upload a custom model and annotate images automatically. - Ability to rotate images/video in the client part (Ctrl+R, Shift+Ctrl+R shortcuts) (#305) - The ReID application for automatic bounding box merging has been added (#299) - Keyboard shortcuts to switch next/previous default shape type (box, polygon etc) [Alt + <, Alt + >] (#316) - Converter for VOC now supports interpolation tracks -- REST API (/api/v1/*, /api/docs) +- REST API (/api/v1/\*, /api/docs) - Semi-automatic semantic segmentation with the [Deep Extreme Cut](http://www.vision.ee.ethz.ch/~cvlsegmentation/dextr/) work ### Changed + - Propagation setup has been moved from settings to bottom player panel - Additional events like "Debug Info" or "Fit Image" have been added for analitics - Optional using LFS for git annotation storages (#314) ### Deprecated + - "Flip images" flag in the create task dialog will be removed. Rotation functionality in client part have been added instead. ### Removed + - ### Fixed + - Django 2.1.5 (security fix, https://nvd.nist.gov/vuln/detail/CVE-2019-3498) - Several scenarious which cause code 400 after undo/redo/save have been fixed (#315) ## [0.3.0] - 2018-12-29 + ### Added + - Ability to copy Object URL and Frame URL via object context menu and player context menu respectively. - Ability to change opacity for selected shape with help "Selected Fill Opacity" slider. - Ability to remove polyshapes points by double click. @@ -420,6 +596,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Buttons lock/hide for labels. They work for all objects with the same label on a current frame (#116) ### Changed + - Polyshape editing method has been improved. You can redraw part of shape instead of points cloning. - Unified shortcut (Esc) for close any mode instead of different shortcuts (Alt+N, Alt+G, Alt+M etc.). - Dump file contains information about data source (e.g. video name, archive name, ...) @@ -430,6 +607,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Drawing has become more convenience. Now it is possible to draw outside an image. Shapes will be automatically truncated after drawing process (#202) ### Fixed + - Performance bottleneck has been fixed during you create new objects (draw, copy, merge etc). - Label UI elements aren't updated after changelabel. - Attribute annotation mode can use invalid shape position after resize or move shapes. @@ -441,7 +619,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Text drawing outside of a frame in some cases (#202) ## [0.2.0] - 2018-09-28 + ### Added + - New annotation shapes: polygons, polylines, points - Undo/redo feature - Grid to estimate size of objects @@ -459,42 +639,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Full screen view ### Changed + - Documentation, screencasts, the primary screenshot - Content-type for save_job request is application/json ### Fixed + - Player navigation if the browser's window is scrolled - Filter doesn't support dash (-) - Several memory leaks - Inconsistent extensions between filenames in an annotation file and real filenames ## [0.1.2] - 2018-08-07 + ### Added + - 7z archive support when creating a task - .vscode/launch.json file for developing with VS code ### Fixed + - #14: docker-compose down command as written in the readme does not remove volumes - #15: all checkboxes in temporary attributes are checked when reopening job after saving the job - #18: extend CONTRIBUTING.md - #19: using the same attribute for label twice -> stuck ### Changed + - More strict verification for labels with attributes ## [0.1.1] - 2018-07-6 + ### Added + - Links on a screenshot, documentation, screencasts into README.md - CONTRIBUTORS.md ### Fixed + - GitHub documentation ## 0.1.0 - 2018-06-29 + ### Added + - Initial version ## Template + ``` ## [Unreleased] ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08c3cfd0..277d2bc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,78 +10,95 @@ patches and features. ## Development environment -Next steps should work on clear Ubuntu 18.04. +- Install necessary dependencies: -- Install necessary dependencies: - ```sh - sudo apt-get update && sudo apt-get --no-install-recommends install -y ffmpeg build-essential curl redis-server python3-dev python3-pip python3-venv python3-tk libldap2-dev libsasl2-dev - ``` - Also please make sure that you have installed ffmpeg with all necessary libav* libraries and pkg-config package. - ```sh - # Node and npm (you can use default versions of these packages from apt (8.*, 3.*), but we would recommend to use newer versions) - curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - - sudo apt-get install -y nodejs - - # General dependencies - sudo apt-get install -y pkg-config - - # Library components - sudo apt-get install -y \ - libavformat-dev libavcodec-dev libavdevice-dev \ - libavutil-dev libswscale-dev libswresample-dev libavfilter-dev - ``` - See [PyAV Dependencies installation guide](http://docs.mikeboers.com/pyav/develop/overview/installation.html#dependencies) - for details. - -- Install [Visual Studio Code](https://code.visualstudio.com/docs/setup/linux#_debian-and-ubuntu-based-distributions) -for development - -- Install CVAT on your local host: - ```sh - git clone https://github.com/opencv/cvat - cd cvat && mkdir logs keys - python3 -m venv .env - . .env/bin/activate - pip install -U pip wheel setuptools - pip install -r cvat/requirements/development.txt - pip install -r datumaro/requirements.txt - python manage.py migrate - python manage.py collectstatic - ``` + Ubuntu 18.04 -- Create a super user for CVAT: - ```sh - $ python manage.py createsuperuser - Username (leave blank to use 'django'): *** - Email address: *** - Password: *** - Password (again): *** - ``` + ```sh + sudo apt-get update && sudo apt-get --no-install-recommends install -y build-essential curl redis-server python3-dev python3-pip python3-venv python3-tk libldap2-dev libsasl2-dev pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev + ``` -- Install npm packages for UI and start UI debug server (run the following command from CVAT root directory): - ```sh - npm install && \ - cd cvat-core && npm install && \ - cd ../cvat-ui && npm install && npm start - ``` + ```sh + # Node and npm (you can use default versions of these packages from apt (8.*, 3.*), but we would recommend to use newer versions) + curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - + sudo apt-get install -y nodejs + ``` -- Open new terminal (Ctrl + Shift + T), run Visual Studio Code from the virtual environment - ```sh - cd .. && source .env/bin/activate && code - ``` + MacOS 10.15 + + ```sh + brew install git python pyenv redis curl openssl node + ``` + +- Install FFmpeg libraries (libav\*) version 4.0 or higher. + +- Install [Visual Studio Code](https://code.visualstudio.com/docs/setup/linux#_debian-and-ubuntu-based-distributions) + for development + +- Install CVAT on your local host: + + ```sh + git clone https://github.com/opencv/cvat + cd cvat && mkdir logs keys + python3 -m venv .env + . .env/bin/activate + pip install -U pip wheel setuptools + pip install -r cvat/requirements/development.txt + python manage.py migrate + python manage.py collectstatic + ``` + + > Note for Mac users + > + > If you have any problems with installing dependencies from + > `cvat/requirements/*.txt`, you may need to reinstall your system python + > In some cases after system update it can be configured incorrectly and cannot compile some native modules + +- Create a super user for CVAT: + + ```sh + $ python manage.py createsuperuser + Username (leave blank to use 'django'): *** + Email address: *** + Password: *** + Password (again): *** + ``` -- Install following VS Code extensions: - - [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) - - [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) - - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - - [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) - - [vscode-remark-lint](https://marketplace.visualstudio.com/items?itemName=drewbourne.vscode-remark-lint) - - [licenser](https://marketplace.visualstudio.com/items?itemName=ymotongpoo.licenser) - - [Trailing Spaces](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces) +- Install npm packages for UI and start UI debug server (run the following command from CVAT root directory): -- Reload Visual Studio Code from virtual environment + ```sh + npm ci && \ + cd cvat-core && npm ci && \ + cd ../cvat-ui && npm ci && npm start + ``` -- Select `server: debug` configuration and start it (F5) to run REST server and its workers + > Note for Mac users + > + > If you faced with error + > + > `Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (57)` + > + > Read this article [Node Sass does not yet support your current environment](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) + +- Open new terminal (Ctrl + Shift + T), run Visual Studio Code from the virtual environment + + ```sh + cd .. && source .env/bin/activate && code + ``` + +- Install following VS Code extensions: + + - [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) + - [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) + - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + - [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) + - [vscode-remark-lint](https://marketplace.visualstudio.com/items?itemName=drewbourne.vscode-remark-lint) + - [licenser](https://marketplace.visualstudio.com/items?itemName=ymotongpoo.licenser) + - [Trailing Spaces](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces) + +- Reload Visual Studio Code from virtual environment + +- Select `server: debug` configuration and start it (F5) to run REST server and its workers You have done! Now it is possible to insert breakpoints and debug server and client of the tool. @@ -89,30 +106,32 @@ You have done! Now it is possible to insert breakpoints and debug server and cli You develop CVAT under WSL (Windows subsystem for Linux) following next steps. -- Install WSL using [this guide](https://docs.microsoft.com/ru-ru/windows/wsl/install-win10). +- Install WSL using [this guide](https://docs.microsoft.com/ru-ru/windows/wsl/install-win10). -- Following this guide install Ubuntu 18.04 Linux distribution for WSL. +- Following this guide install Ubuntu 18.04 Linux distribution for WSL. -- Run Ubuntu using start menu link or execute next command - ```powershell - wsl -d Ubuntu-18.04 - ``` +- Run Ubuntu using start menu link or execute next command + + ```powershell + wsl -d Ubuntu-18.04 + ``` + +- Run all commands from this isntallation guide in WSL Ubuntu shell. -- Run all commands from this isntallation guide in WSL Ubuntu shell. ## Setup additional components in development environment ### DL models as serverless functions Install [nuclio platform](https://github.com/nuclio/nuclio): + - You have to install `nuctl` command line tool to build and deploy serverless -functions. Download [the latest release]( -https://github.com/nuclio/nuclio/blob/development/docs/reference/nuctl/nuctl.md#download). + functions. Download [the latest release](https://github.com/nuclio/nuclio/blob/development/docs/reference/nuctl/nuctl.md#download). - The simplest way to explore Nuclio is to run its graphical user interface (GUI) -of the Nuclio dashboard. All you need in order to run the dashboard is Docker. See -[nuclio documentation](https://github.com/nuclio/nuclio#quick-start-steps) -for more details. + of the Nuclio dashboard. All you need in order to run the dashboard is Docker. See + [nuclio documentation](https://github.com/nuclio/nuclio#quick-start-steps) + for more details. - Create `cvat` project inside nuclio dashboard where you will deploy new -serverless functions and deploy a couple of DL models. + serverless functions and deploy a couple of DL models. ```bash nuctl create project cvat @@ -175,7 +194,7 @@ nuctl deploy --project-name cvat \ - Display a list of running serverless functions using `nuctl` command or see them -in nuclio dashboard: + in nuclio dashboard: ```bash nuctl get function @@ -192,7 +211,7 @@ nuctl get function - Test your deployed DL model as a serverless function. The command below -should work on Linux and Mac OS. + should work on Linux and Mac OS. ```bash image=$(curl https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png --output - | base64 | tr -d '\n') @@ -233,6 +252,7 @@ Server = nuclio ] ``` + ### Run Cypress tests - Install Сypress as described in the [documentation](https://docs.cypress.io/guides/getting-started/installing-cypress.html). - Run cypress tests: @@ -252,12 +272,12 @@ little exception - we prefer 4 spaces for indentation of nested blocks and state The project uses [a successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model). Thus it has a couple of branches. Some of them are described below: -- `origin/master` to be the main branch where the source code of -HEAD always reflects a production-ready state +- `origin/master` to be the main branch where the source code of + HEAD always reflects a production-ready state -- `origin/develop` to be the main branch where the source code of -HEAD always reflects a state with the latest delivered development -changes for the next release. Some would call this the “integration branch”. +- `origin/develop` to be the main branch where the source code of + HEAD always reflects a state with the latest delivered development + changes for the next release. Some would call this the “integration branch”. ## Using the issue tracker @@ -265,13 +285,14 @@ The issue tracker is the preferred channel for [bug reports](#bugs), [features requests](#features) and [submitting pull requests](#pull-requests), but please respect the following restrictions: -- Please **do not** use the issue tracker for personal support requests (use +- Please **do not** use the issue tracker for personal support requests (use [Stack Overflow](http://stackoverflow.com)). -- Please **do not** derail or troll issues. Keep the discussion on topic and +- Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. + ## Bug reports A bug is a _demonstrable problem_ that is caused by the code in the repository. @@ -280,10 +301,10 @@ Good bug reports are extremely helpful - thank you! Guidelines for bug reports: 1. **Use the GitHub issue search** — check if the issue has already been - reported. + reported. 1. **Check if the issue has been fixed** — try to reproduce it using the - latest `develop` branch in the repository. + latest `develop` branch in the repository. 1. **Isolate the problem** — ideally create a reduced test case. @@ -310,6 +331,7 @@ Example: > merits). + ## Feature requests Feature requests are welcome. But take a moment to find out whether your idea @@ -318,6 +340,7 @@ case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. + ## Pull requests Good pull requests - patches, improvements, new features - are a fantastic @@ -362,10 +385,10 @@ project: ``` 1. Commit your changes in logical chunks. Please adhere to these [git commit - message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - or your code is unlikely be merged into the main project. Use Git's - [interactive rebase](https://docs.github.com/en/github/using-git/about-git-rebase) - feature to tidy up your commits before making them public. + message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + or your code is unlikely be merged into the main project. Use Git's + [interactive rebase](https://docs.github.com/en/github/using-git/about-git-rebase) + feature to tidy up your commits before making them public. 1. Locally merge (or rebase) the upstream development branch into your topic branch: diff --git a/Dockerfile b/Dockerfile index 07060f19..2ce2cd35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,53 @@ -FROM ubuntu:16.04 +FROM ubuntu:20.04 as build-image + +ARG http_proxy +ARG https_proxy +ARG no_proxy +ARG socks_proxy +ARG DJANGO_CONFIGURATION + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \ + apache2-dev \ + build-essential \ + curl \ + libldap2-dev \ + libsasl2-dev \ + nasm \ + git \ + pkg-config \ + python3-dev \ + python3-pip \ + python3-venv && \ + rm -rf /var/lib/apt/lists/* + +# Compile Openh264 and FFmpeg +ARG PREFIX=/opt/ffmpeg +ARG PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig + +ENV FFMPEG_VERSION=4.3.1 \ + OPENH264_VERSION=2.1.1 + +WORKDIR /tmp/openh264 +RUN curl -sL https://github.com/cisco/openh264/archive/v${OPENH264_VERSION}.tar.gz --output openh264-${OPENH264_VERSION}.tar.gz && \ + tar -zx --strip-components=1 -f openh264-${OPENH264_VERSION}.tar.gz && \ + make -j5 && make install PREFIX=${PREFIX} && make clean + +WORKDIR /tmp/ffmpeg +RUN curl -sLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \ + tar -jx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \ + ./configure --disable-nonfree --disable-gpl --enable-libopenh264 --enable-shared --disable-static --prefix="${PREFIX}" && \ + make -j5 && make install && make distclean + +# Install requirements +RUN python3 -m venv /opt/venv +ENV PATH="/opt/venv/bin:${PATH}" +RUN python3 -m pip install --no-cache-dir -U pip==20.0.1 setuptools==49.6.0 wheel==0.35.1 +COPY cvat/requirements/ /tmp/requirements/ +RUN DATUMARO_HEADLESS=1 python3 -m pip install --no-cache-dir -r /tmp/requirements/${DJANGO_CONFIGURATION}.txt + + +FROM ubuntu:20.04 ARG http_proxy ARG https_proxy @@ -21,68 +70,26 @@ ENV DJANGO_CONFIGURATION=${DJANGO_CONFIGURATION} # Install necessary apt packages RUN apt-get update && \ - apt-get --no-install-recommends install -yq \ - software-properties-common && \ - add-apt-repository ppa:mc3man/xerus-media -y && \ - add-apt-repository ppa:mc3man/gstffmpeg-keep -y && \ - apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \ apache2 \ - apache2-dev \ - apt-utils \ - build-essential \ libapache2-mod-xsendfile \ supervisor \ - ffmpeg \ - gstreamer0.10-ffmpeg \ - libavcodec-dev \ - libavdevice-dev \ - libavfilter-dev \ - libavformat-dev \ - libavutil-dev \ - libswresample-dev \ - libswscale-dev \ - libldap2-dev \ - libsasl2-dev \ - pkg-config \ - python3-dev \ - python3-pip \ + libldap-2.4-2 \ + libsasl2-2 \ + libpython3-dev \ tzdata \ + python3-distutils \ p7zip-full \ git \ - ssh \ + git-lfs \ poppler-utils \ + ssh \ curl && \ - curl https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ - apt-get --no-install-recommends install -y git-lfs && git lfs install && \ - python3 -m pip install --no-cache-dir -U pip==20.0.1 setuptools==49.6.0 wheel==0.35.1 && \ ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \ dpkg-reconfigure -f noninteractive tzdata && \ - add-apt-repository --remove ppa:mc3man/gstffmpeg-keep -y && \ - add-apt-repository --remove ppa:mc3man/xerus-media -y && \ rm -rf /var/lib/apt/lists/* && \ echo 'application/wasm wasm' >> /etc/mime.types -# Add a non-root user -ENV USER=${USER} -ENV HOME /home/${USER} -WORKDIR ${HOME} -RUN adduser --shell /bin/bash --disabled-password --gecos "" ${USER} && \ - if [ -z ${socks_proxy} ]; then \ - echo export "GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=30\"" >> ${HOME}/.bashrc; \ - else \ - echo export "GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=30 -o ProxyCommand='nc -X 5 -x ${socks_proxy} %h %p'\"" >> ${HOME}/.bashrc; \ - fi - -COPY components /tmp/components - -# Install and initialize CVAT, copy all necessary files -COPY cvat/requirements/ /tmp/requirements/ -COPY supervisord.conf mod_wsgi.conf wait-for-it.sh manage.py ${HOME}/ -RUN python3 -m pip install --no-cache-dir -r /tmp/requirements/${DJANGO_CONFIGURATION}.txt -# pycocotools package is impossible to install with its dependencies by one pip install command -RUN python3 -m pip install --no-cache-dir pycocotools==2.0.0 - ARG CLAM_AV ENV CLAM_AV=${CLAM_AV} RUN if [ "$CLAM_AV" = "yes" ]; then \ @@ -96,23 +103,52 @@ RUN if [ "$CLAM_AV" = "yes" ]; then \ rm -rf /var/lib/apt/lists/*; \ fi -COPY ssh ${HOME}/.ssh -COPY utils ${HOME}/utils -COPY cvat/ ${HOME}/cvat -COPY cvat-core/ ${HOME}/cvat-core -COPY cvat-data/ ${HOME}/cvat-data -COPY tests ${HOME}/tests -COPY datumaro/ ${HOME}/datumaro +# Add a non-root user +ENV USER=${USER} +ENV HOME /home/${USER} +RUN adduser --shell /bin/bash --disabled-password --gecos "" ${USER} && \ + if [ -z ${socks_proxy} ]; then \ + echo export "GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=30\"" >> ${HOME}/.bashrc; \ + else \ + echo export "GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o ConnectTimeout=30 -o ProxyCommand='nc -X 5 -x ${socks_proxy} %h %p'\"" >> ${HOME}/.bashrc; \ + fi -RUN python3 -m pip install --no-cache-dir -r ${HOME}/datumaro/requirements.txt +ARG INSTALL_SOURCES='no' +WORKDIR ${HOME}/sources +RUN if [ "$INSTALL_SOURCES" = "yes" ]; then \ + sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list && \ + apt-get update && \ + dpkg --get-selections | while read -r line; do \ + package=$(echo "$line" | awk '{print $1}'); \ + mkdir "$package"; \ + ( \ + cd "$package"; \ + apt-get -q --download-only source "$package"; \ + ) \ + done && \ + rm -rf /var/lib/apt/lists/*; \ + fi +COPY --from=build-image /tmp/openh264/openh264*.tar.gz /tmp/ffmpeg/ffmpeg*.tar.bz2 ${HOME}/sources/ -RUN chown -R ${USER}:${USER} . +# Copy python virtual enviroment and FFmpeg binaries from build-image +COPY --from=build-image /opt/venv /opt/venv +ENV PATH="/opt/venv/bin:${PATH}" +COPY --from=build-image /opt/ffmpeg /usr + +# Install and initialize CVAT, copy all necessary files +COPY --chown=${USER} components /tmp/components +COPY --chown=${USER} ssh ${HOME}/.ssh +COPY --chown=${USER} supervisord.conf mod_wsgi.conf wait-for-it.sh manage.py ${HOME}/ +COPY --chown=${USER} cvat/ ${HOME}/cvat +COPY --chown=${USER} utils/ ${HOME}/utils +COPY --chown=${USER} tests/ ${HOME}/tests # RUN all commands below as 'django' user USER ${USER} +WORKDIR ${HOME} RUN mkdir data share media keys logs /tmp/supervisord RUN python3 manage.py collectstatic -EXPOSE 8080 8443 +EXPOSE 8080 ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/Dockerfile.ci b/Dockerfile.ci index 422259de..bc642137 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -3,24 +3,35 @@ FROM cvat/server ENV DJANGO_CONFIGURATION=testing USER root -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \ - curl https://deb.nodesource.com/setup_12.x | bash - && \ - apt-get update && \ +RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \ + gpg-agent \ + gnupg2 \ apt-utils \ build-essential \ - google-chrome-stable \ - nodejs \ python3-dev \ ruby \ && \ + curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ + echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \ + curl https://deb.nodesource.com/setup_12.x | bash - && \ + DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \ + google-chrome-stable \ + nodejs \ + && \ rm -rf /var/lib/apt/lists/*; -RUN python3 -m pip install --no-cache-dir -r /tmp/requirements/${DJANGO_CONFIGURATION}.txt && \ +COPY cvat/requirements/ /tmp/requirements/ + +RUN DATUMARO_HEADLESS=1 python3 -m pip install --no-cache-dir -r /tmp/requirements/${DJANGO_CONFIGURATION}.txt && \ python3 -m pip install --no-cache-dir coveralls RUN gem install coveralls-lcov +COPY utils ${HOME}/utils +COPY cvat-core ${HOME}/cvat-core +COPY cvat-data ${HOME}/cvat-data +COPY tests ${HOME}/tests + COPY .coveragerc . ENTRYPOINT [] diff --git a/Dockerfile.ui b/Dockerfile.ui index 6af7763c..4f15e6ad 100644 --- a/Dockerfile.ui +++ b/Dockerfile.ui @@ -15,29 +15,29 @@ ENV TERM=xterm \ LANG='C.UTF-8' \ LC_ALL='C.UTF-8' +RUN apk add python3 g++ make + # Install dependencies COPY cvat-core/package*.json /tmp/cvat-core/ COPY cvat-canvas/package*.json /tmp/cvat-canvas/ COPY cvat-ui/package*.json /tmp/cvat-ui/ COPY cvat-data/package*.json /tmp/cvat-data/ -RUN npm config set loglevel info - # Install cvat-data dependencies WORKDIR /tmp/cvat-data/ -RUN npm install +RUN npm ci # Install cvat-core dependencies WORKDIR /tmp/cvat-core/ -RUN npm install +RUN npm ci # Install cvat-canvas dependencies WORKDIR /tmp/cvat-canvas/ -RUN npm install +RUN npm ci # Install cvat-ui dependencies WORKDIR /tmp/cvat-ui/ -RUN npm install +RUN npm ci # Build source code COPY cvat-data/ /tmp/cvat-data/ diff --git a/README.md b/README.md index 275247ac..e0921ba5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Computer Vision Annotation Tool (CVAT) -[![Build Status](https://travis-ci.org/opencv/cvat.svg?branch=develop)](https://travis-ci.org/opencv/cvat) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/840351da141e4eaeac6476fd19ec0a33)](https://app.codacy.com/app/cvat/cvat?utm_source=github.com&utm_medium=referral&utm_content=opencv/cvat&utm_campaign=Badge_Grade_Dashboard) +[![Build Status](https://travis-ci.org/openvinotoolkit/cvat.svg?branch=develop)](https://travis-ci.org/openvinotoolkit/cvat) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b9899c72f2764df0b5d26390cb872e21)](https://app.codacy.com/gh/openvinotoolkit/cvat?utm_source=github.com&utm_medium=referral&utm_content=openvinotoolkit/cvat&utm_campaign=Badge_Grade_Dashboard) [![Gitter chat](https://badges.gitter.im/opencv-cvat/gitter.png)](https://gitter.im/opencv-cvat) -[![Coverage Status](https://coveralls.io/repos/github/opencv/cvat/badge.svg?branch=)](https://coveralls.io/github/opencv/cvat?branch=develop) +[![Coverage Status](https://coveralls.io/repos/github/openvinotoolkit/cvat/badge.svg?branch=develop)](https://coveralls.io/github/openvinotoolkit/cvat?branch=develop) [![DOI](https://zenodo.org/badge/139156354.svg)](https://zenodo.org/badge/latestdoi/139156354) CVAT is free, online, interactive video and image annotation @@ -19,7 +19,7 @@ annotation team. Try it online [cvat.org](https://cvat.org). - [Installation guide](cvat/apps/documentation/installation.md) - [User's guide](cvat/apps/documentation/user_guide.md) - [Django REST API documentation](#rest-api) -- [Datumaro dataset framework](datumaro/README.md) +- [Datumaro dataset framework](https://github.com/openvinotoolkit/datumaro/blob/develop/README.md) - [Command line interface](utils/cli/) - [XML annotation format](cvat/apps/documentation/xml_format.md) - [AWS Deployment Guide](cvat/apps/documentation/AWS-Deployment-Guide.md) @@ -32,7 +32,7 @@ annotation team. Try it online [cvat.org](https://cvat.org). - [Annotation mode](https://youtu.be/vH_639N67HI) - [Interpolation of bounding boxes](https://youtu.be/Hc3oudNuDsY) - [Interpolation of polygons](https://youtu.be/K4nis9lk92s) -- [Tag_annotation_video](https://youtu.be/62bI4mF-Xfk) +- [Tag annotation video](https://youtu.be/62bI4mF-Xfk) - [Attribute mode](https://youtu.be/iIkJsOkDzVA) - [Segmentation mode](https://youtu.be/9Fe_GzMLo3E) - [Tutorial for polygons](https://youtu.be/C7-r9lZbjBw) @@ -40,36 +40,41 @@ annotation team. Try it online [cvat.org](https://cvat.org). ## Supported annotation formats -Format selection is possible after clicking on the Upload annotation -and Dump annotation buttons. [Datumaro](datumaro/README.md) dataset -framework allows additional dataset transformations -via its command line tool and Python library. - -| Annotation format | Import | Export | -| ------------------------------------------------------------------------------------------ | ------ | ------ | -| [CVAT for images](cvat/apps/documentation/xml_format.md#annotation) | X | X | -| [CVAT for a video](cvat/apps/documentation/xml_format.md#interpolation) | X | X | -| [Datumaro](datumaro/README.md) | | X | -| [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) | X | X | -| Segmentation masks from [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) | X | X | -| [YOLO](https://pjreddie.com/darknet/yolo/) | X | X | -| [MS COCO Object Detection](http://cocodataset.org/#format-data) | X | X | -| [TFrecord](https://www.tensorflow.org/tutorials/load_data/tf_records) | X | X | -| [MOT](https://motchallenge.net/) | X | X | -| [LabelMe 3.0](http://labelme.csail.mit.edu/Release3.0) | X | X | +Format selection is possible after clicking on the Upload annotation and Dump +annotation buttons. [Datumaro](https://github.com/openvinotoolkit/datumaro) +dataset framework allows additional dataset transformations via its command +line tool and Python library. + +For more information about supported formats look at the +[documentation](cvat/apps/dataset_manager/formats/README.md#formats). + +| Annotation format | Import | Export | +| ----------------------------------------------------------------------------- | ------ | ------ | +| [CVAT for images](cvat/apps/documentation/xml_format.md#annotation) | X | X | +| [CVAT for a video](cvat/apps/documentation/xml_format.md#interpolation) | X | X | +| [Datumaro](https://github.com/openvinotoolkit/datumaro) | | X | +| [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) | X | X | +| Segmentation masks from [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) | X | X | +| [YOLO](https://pjreddie.com/darknet/yolo/) | X | X | +| [MS COCO Object Detection](http://cocodataset.org/#format-data) | X | X | +| [TFrecord](https://www.tensorflow.org/tutorials/load_data/tf_records) | X | X | +| [MOT](https://motchallenge.net/) | X | X | +| [LabelMe 3.0](http://labelme.csail.mit.edu/Release3.0) | X | X | +| [ImageNet](http://www.image-net.org) | X | X | +| [CamVid](http://mi.eng.cam.ac.uk/research/projects/VideoRec/CamVid/) | X | X | ## Deep learning models for automatic labeling -| Name | Type | Framework | -| ------------------------------------------------------------------------------------------------------- | ---------- | ---------- | -| [Deep Extreme Cut](/serverless/openvino/dextr/nuclio) | interactor | OpenVINO | -| [Faster RCNN](/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio) | detector | TensorFlow | -| [Mask RCNN](/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio) | detector | OpenVINO | -| [YOLO v3](/serverless/openvino/omz/public/yolo-v3-tf/nuclio) | detector | OpenVINO | -| [Text detection v4](/serverless/openvino/omz/intel/text-detection-0004/nuclio) | detector | OpenVINO | -| [Semantic segmentation for ADAS](/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio) | detector | OpenVINO | -| [Mask RCNN](/serverless/tensorflow/matterport/mask_rcnn/nuclio) | detector | TensorFlow | -| [Object reidentification](/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio) | reid | OpenVINO | +| Name | Type | Framework | CPU | GPU | +| ------------------------------------------------------------------------------------------------------- | ---------- | ---------- | --- | --- | +| [Deep Extreme Cut](/serverless/openvino/dextr/nuclio) | interactor | OpenVINO | X | +| [Faster RCNN](/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio) | detector | TensorFlow | X | X | +| [Mask RCNN](/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio) | detector | OpenVINO | X | +| [YOLO v3](/serverless/openvino/omz/public/yolo-v3-tf/nuclio) | detector | OpenVINO | X | +| [Text detection v4](/serverless/openvino/omz/intel/text-detection-0004/nuclio) | detector | OpenVINO | X | +| [Semantic segmentation for ADAS](/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio) | detector | OpenVINO | X | +| [Mask RCNN](/serverless/tensorflow/matterport/mask_rcnn/nuclio) | detector | TensorFlow | X | +| [Object reidentification](/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio) | reid | OpenVINO | X | ## Online demo: [cvat.org](https://cvat.org) @@ -78,19 +83,21 @@ Try it online without local installation. Only own or assigned tasks are visible to users. Disabled features: + - [Analytics: management and monitoring of data annotation team](/components/analytics/README.md) Limitations: + - No more than 10 tasks per user - Uploaded data is limited to 500Mb ## REST API Automatically generated Swagger documentation for Django REST API is -available on ``/api/swagger`` -(default: ``localhost:8080/api/swagger``). +available on `/api/swagger` +(default: `localhost:8080/api/swagger`). -Swagger documentation is visiable on allowed hostes, Update environement variable in docker-compose.yml file with cvat hosted machine IP or domain name. Example - ``ALLOWED_HOSTS: 'localhost, 127.0.0.1'``) +Swagger documentation is visiable on allowed hostes, Update environement variable in docker-compose.yml file with cvat hosted machine IP or domain name. Example - `ALLOWED_HOSTS: 'localhost, 127.0.0.1'`) ## LICENSE @@ -104,16 +111,22 @@ contributors and other users. However, if you have a feature request or a bug report that can reproduced, feel free to open an issue (with steps to reproduce the bug if it's a bug -report) on [GitHub* issues](https://github.com/opencv/cvat/issues). +report) on [GitHub\* issues](https://github.com/opencv/cvat/issues). If you are not sure or just want to browse other users common questions, [Gitter chat](https://gitter.im/opencv-cvat) is the way to go. Other ways to ask questions and get our support: -* [\#cvat](https://stackoverflow.com/search?q=%23cvat) tag on StackOverflow* -* [Forum on Intel Developer Zone](https://software.intel.com/en-us/forums/computer-vision) + +- [\#cvat](https://stackoverflow.com/search?q=%23cvat) tag on StackOverflow\* +- [Forum on Intel Developer Zone](https://software.intel.com/en-us/forums/computer-vision) ## Links + - [Intel AI blog: New Computer Vision Tool Accelerates Annotation of Digital Images and Video](https://www.intel.ai/introducing-cvat) - [Intel Software: Computer Vision Annotation Tool: A Universal Approach to Data Annotation](https://software.intel.com/en-us/articles/computer-vision-annotation-tool-a-universal-approach-to-data-annotation) - [VentureBeat: Intel open-sources CVAT, a toolkit for data labeling](https://venturebeat.com/2019/03/05/intel-open-sources-cvat-a-toolkit-for-data-labeling/) + +## Projects using CVAT + +- [Onepanel](https://github.com/onepanelio/core) - Onepanel is an open source vision AI platform that fully integrates CVAT with scalable data processing and parallelized training pipelines. diff --git a/components/analytics/README.md b/components/analytics/README.md index b46a8853..3c9c9b8b 100644 --- a/components/analytics/README.md +++ b/components/analytics/README.md @@ -5,12 +5,14 @@ It is possible to proxy annotation logs from client to ELK. To do that run the following command below: ### Build docker image + ```bash # From project root directory docker-compose -f docker-compose.yml -f components/analytics/docker-compose.analytics.yml build ``` ### Run docker container + ```bash # From project root directory docker-compose -f docker-compose.yml -f components/analytics/docker-compose.analytics.yml up -d @@ -19,11 +21,12 @@ docker-compose -f docker-compose.yml -f components/analytics/docker-compose.anal At the moment it is not possible to save advanced settings. Below values should be specified manually. ## Time picker default + { - "from": "now/d", - "to": "now/d", - "display": "Today", - "section": 0 +"from": "now/d", +"to": "now/d", +"display": "Today", +"section": 0 } ## Time picker quick ranges diff --git a/components/analytics/docker-compose.analytics.yml b/components/analytics/docker-compose.analytics.yml index 5edcd505..1774eb95 100644 --- a/components/analytics/docker-compose.analytics.yml +++ b/components/analytics/docker-compose.analytics.yml @@ -1,4 +1,4 @@ -version: '2.3' +version: '3.3' services: cvat_elasticsearch: container_name: cvat_elasticsearch @@ -35,9 +35,24 @@ services: volumes: ['./components/analytics/kibana:/home/django/kibana:ro'] depends_on: ['cvat'] working_dir: '/home/django' - entrypoint: ['bash', 'wait-for-it.sh', 'elasticsearch:9200', '-t', '0', '--', - '/bin/bash', 'wait-for-it.sh', 'kibana:5601', '-t', '0', '--', - '/usr/bin/python3', 'kibana/setup.py', 'kibana/export.json'] + entrypoint: + [ + 'bash', + 'wait-for-it.sh', + 'elasticsearch:9200', + '-t', + '0', + '--', + '/bin/bash', + 'wait-for-it.sh', + 'kibana:5601', + '-t', + '0', + '--', + '/usr/bin/python3', + 'kibana/setup.py', + 'kibana/export.json', + ] environment: no_proxy: elasticsearch,kibana,${no_proxy} @@ -52,7 +67,7 @@ services: context: ./components/analytics/logstash args: ELK_VERSION: 6.4.0 - http_proxy: ${http_proxy} + http_proxy: ${http_proxy} https_proxy: ${https_proxy} depends_on: ['cvat_elasticsearch'] restart: always @@ -63,6 +78,7 @@ services: DJANGO_LOG_SERVER_PORT: 5000 DJANGO_LOG_VIEWER_HOST: kibana DJANGO_LOG_VIEWER_PORT: 5601 + CVAT_ANALYTICS: 1 no_proxy: kibana,logstash,nuclio,${no_proxy} volumes: diff --git a/components/analytics/elasticsearch/elasticsearch.yml b/components/analytics/elasticsearch/elasticsearch.yml index 50e4cf0b..2d19b17f 100644 --- a/components/analytics/elasticsearch/elasticsearch.yml +++ b/components/analytics/elasticsearch/elasticsearch.yml @@ -1,3 +1,3 @@ http.host: 0.0.0.0 script.painless.regex.enabled: true -path.repo: ["/usr/share/elasticsearch/data/backup"] +path.repo: ['/usr/share/elasticsearch/data/backup'] diff --git a/components/analytics/kibana/export.json b/components/analytics/kibana/export.json index d4896f5b..5c920e9e 100644 --- a/components/analytics/kibana/export.json +++ b/components/analytics/kibana/export.json @@ -40,19 +40,11 @@ "_type": "search", "_source": { "hits": 0, - "sort": [ - "@timestamp", - "desc" - ], + "sort": ["@timestamp", "desc"], "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"index\":\"ec510550-c238-11e8-8e1b-758ef07f6de8\",\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"event:\\\"Send exception\\\"\"},\"filter\":[]}" }, - "columns": [ - "task", - "type", - "userid", - "stack" - ], + "columns": ["task", "type", "userid", "stack"], "description": "", "title": "Table with exceptions", "version": 1 @@ -99,7 +91,7 @@ "_id": "ec510550-c238-11e8-8e1b-758ef07f6de8", "_type": "index-pattern", "_source": { - "fields": "[{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@version\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@version.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"application\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"application.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"box count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"duration\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"event\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"event.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"frame count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"object count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"points count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"polygon count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"polyline count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"task\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"task.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"timestamp\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"track count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"userid\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userid.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"working_time\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "fields": "[{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@version\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@version.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"application\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"application.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"box count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"duration\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"event\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"event.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"frame count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"object count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"points count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"polygon count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"polyline count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"task\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"task\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"timestamp\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"track count\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"userid\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userid.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"working_time\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", "title": "cvat*", "timeFieldName": "@timestamp", "fieldFormatMap": "{\"duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"milliseconds\",\"outputFormat\":\"asSeconds\"}},\"working_time\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"milliseconds\",\"outputFormat\":\"asHours\"}}}" @@ -164,7 +156,7 @@ "_type": "visualization", "_source": { "title": "List of tasks", - "visState": "{\"title\":\"List of tasks\",\"type\":\"table\",\"params\":{\"perPage\":20,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":2,\"direction\":\"desc\"},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"working_time\",\"customLabel\":\"Working time (h)\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"task.keyword\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"Task\"}},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"userid.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"_key\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"User\"}}]}", + "visState": "{\"title\":\"List of tasks\",\"type\":\"table\",\"params\":{\"perPage\":20,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":2,\"direction\":\"desc\"},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"working_time\",\"customLabel\":\"Working time (h)\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"task\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"Task\"}},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"userid.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"_key\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"User\"}}]}", "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":2,\"direction\":\"desc\"}}}}", "description": "", "version": 1, @@ -195,4 +187,4 @@ "savedObjectVersion": 2 } } -] \ No newline at end of file +] diff --git a/components/analytics/kibana/kibana.yml b/components/analytics/kibana/kibana.yml index 457aec60..4fba9171 100644 --- a/components/analytics/kibana/kibana.yml +++ b/components/analytics/kibana/kibana.yml @@ -1,5 +1,5 @@ server.host: 0.0.0.0 elasticsearch.url: http://elasticsearch:9200 -elasticsearch.requestHeadersWhitelist: [ "cookie", "authorization", "x-forwarded-user" ] -kibana.defaultAppId: "discover" +elasticsearch.requestHeadersWhitelist: ['cookie', 'authorization', 'x-forwarded-user'] +kibana.defaultAppId: 'discover' server.basePath: /analytics diff --git a/components/serverless/README.md b/components/serverless/README.md new file mode 100644 index 00000000..94edd9af --- /dev/null +++ b/components/serverless/README.md @@ -0,0 +1,8 @@ +## Serverless for Computer Vision Annotation Tool (CVAT) + +### Run docker container + +```bash +# From project root directory +docker-compose -f docker-compose.yml -f components/serverless/docker-compose.serverless.yml up -d +``` diff --git a/components/serverless/docker-compose.serverless.yml b/components/serverless/docker-compose.serverless.yml new file mode 100644 index 00000000..de94f616 --- /dev/null +++ b/components/serverless/docker-compose.serverless.yml @@ -0,0 +1,28 @@ +version: '3.3' +services: + serverless: + container_name: nuclio + image: quay.io/nuclio/dashboard:1.5.8-amd64 + restart: always + networks: + default: + aliases: + - nuclio + volumes: + - /tmp:/tmp + - /var/run/docker.sock:/var/run/docker.sock + environment: + http_proxy: + https_proxy: + no_proxy: 172.28.0.1,${no_proxy} + NUCLIO_CHECK_FUNCTION_CONTAINERS_HEALTHINESS: 'true' + ports: + - '8070:8070' + + cvat: + environment: + CVAT_SERVERLESS: 1 + no_proxy: kibana,logstash,nuclio,${no_proxy} + +volumes: + cvat_events: diff --git a/cvat-canvas/.eslintignore b/cvat-canvas/.eslintignore new file mode 100644 index 00000000..6de001d8 --- /dev/null +++ b/cvat-canvas/.eslintignore @@ -0,0 +1 @@ +webpack.config.js diff --git a/cvat-canvas/.eslintrc.js b/cvat-canvas/.eslintrc.js index 10edfa70..ab1b4278 100644 --- a/cvat-canvas/.eslintrc.js +++ b/cvat-canvas/.eslintrc.js @@ -1,39 +1,34 @@ -/* - * Copyright (C) 2019 Intel Corporation - * SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT module.exports = { - 'env': { - 'node': true, - 'browser': true, - 'es6': true, + env: { + node: true, }, - 'parserOptions': { - 'parser': '@typescript-eslint/parser', - 'ecmaVersion': 6, + parserOptions: { + parser: '@typescript-eslint/parser', + ecmaVersion: 6, }, - 'plugins': [ - '@typescript-eslint', - 'import', - ], - 'extends': [ + plugins: ['@typescript-eslint', 'import'], + extends: [ 'plugin:@typescript-eslint/recommended', 'airbnb-typescript/base', 'plugin:import/errors', 'plugin:import/warnings', 'plugin:import/typescript', ], - 'rules': { + rules: { '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/indent': ['warn', 4], 'no-plusplus': 0, 'no-restricted-syntax': [ 0, { - 'selector': 'ForOfStatement' - } + selector: 'ForOfStatement', + }, ], + 'max-len': ['error', { code: 120 }], 'no-continue': 0, 'func-names': 0, 'no-console': 0, // this rule deprecates console.log, console.warn etc. because 'it is not good in production code' @@ -41,10 +36,10 @@ module.exports = { 'import/prefer-default-export': 0, // works incorrect with interfaces 'newline-per-chained-call': 0, // makes code uglier }, - 'settings': { + settings: { 'import/resolver': { - 'node': { - 'extensions': ['.ts', '.js', '.json'], + node: { + extensions: ['.ts', '.js', '.json'], }, }, }, diff --git a/cvat-canvas/README.md b/cvat-canvas/README.md index 808aa5ac..126dc885 100644 --- a/cvat-canvas/README.md +++ b/cvat-canvas/README.md @@ -1,18 +1,21 @@ # Module CVAT-CANVAS ## Description + The CVAT module written in TypeScript language. It presents a canvas to viewing, drawing and editing of annotations. ## Versioning + If you make changes in this package, please do following: -- After not important changes (typos, backward compatible bug fixes, refactoring) do: ``npm version patch`` -- After changing API (backward compatible new features) do: ``npm version minor`` -- After changing API (changes that break backward compatibility) do: ``npm version major`` +- After not important changes (typos, backward compatible bug fixes, refactoring) do: `npm version patch` +- After changing API (backward compatible new features) do: `npm version minor` +- After changing API (changes that break backward compatibility) do: `npm version major` ## Commands -- Building of the module from sources in the ```dist``` directory: + +- Building of the module from sources in the `dist` directory: ```bash npm run build @@ -22,6 +25,7 @@ npm run build -- --mode=development # without a minification ## Using Canvas itself handles: + - Shape context menu (PKM) - Image moving (mousedrag) - Image resizing (mousewheel) @@ -51,6 +55,8 @@ Canvas itself handles: MERGE = 'merge', SPLIT = 'split', GROUP = 'group', + INTERACT = 'interact', + SELECT_ROI = 'select_roi', DRAG_CANVAS = 'drag_canvas', ZOOM_CANVAS = 'zoom_canvas', } @@ -70,6 +76,11 @@ Canvas itself handles: crosshair?: boolean; } + interface InteractionData { + shapeType: string; + minVertices?: number; + } + interface GroupData { enabled: boolean; resetGroup?: boolean; @@ -83,6 +94,12 @@ Canvas itself handles: enabled: boolean; } + interface InteractionResult { + points: number[]; + shapeType: string; + button: number; + }; + interface DrawnData { shapeType: string; points: number[]; @@ -95,14 +112,15 @@ Canvas itself handles: interface Canvas { html(): HTMLDivElement; - setZLayer(zLayer: number | null): void; - setup(frameData: any, objectStates: any[]): void; - activate(clientID: number, attributeID?: number): void; - rotate(frameAngle: number): void; + setup(frameData: any, objectStates: any[], zLayer?: number): void; + setupReviewROIs(reviewROIs: Record): void; + activate(clientID: number | null, attributeID?: number): void; + rotate(rotationAngle: number): void; focus(clientID: number, padding?: number): void; fit(): void; grid(stepX: number, stepY: number): void; + interact(interactionData: InteractionData): void; draw(drawData: DrawData): void; group(groupData: GroupData): void; split(splitData: SplitData): void; @@ -110,7 +128,8 @@ Canvas itself handles: select(objectState: any): void; fitCanvas(): void; - bitmap(enabled: boolean): void; + bitmap(enable: boolean): void; + selectROI(enable: boolean): void; dragCanvas(enable: boolean): void; zoomCanvas(enable: boolean): void; @@ -118,27 +137,33 @@ Canvas itself handles: cancel(): void; configure(configuration: Configuration): void; isAbleToChangeFrame(): boolean; + + readonly geometry: Geometry; } ``` ### API CSS -- All drawn objects (shapes, tracks) have an id ```cvat_canvas_shape_{objectState.clientID}``` -- Drawn shapes and tracks have classes ```cvat_canvas_shape```, - ```cvat_canvas_shape_activated```, - ```cvat_canvas_shape_grouping```, - ```cvat_canvas_shape_merging```, - ```cvat_canvas_shape_drawing```, - ```cvat_canvas_shape_occluded``` -- Drawn texts have the class ```cvat_canvas_text``` -- Tags have the class ```cvat_canvas_tag``` -- Canvas image has ID ```cvat_canvas_image``` -- Grid on the canvas has ID ```cvat_canvas_grid``` and ```cvat_canvas_grid_pattern``` -- Crosshair during a draw has class ```cvat_canvas_crosshair``` +- All drawn objects (shapes, tracks) have an id `cvat_canvas_shape_{objectState.clientID}` +- Drawn shapes and tracks have classes `cvat_canvas_shape`, + `cvat_canvas_shape_activated`, + `cvat_canvas_shape_grouping`, + `cvat_canvas_shape_merging`, + `cvat_canvas_shape_drawing`, + `cvat_canvas_shape_occluded` +- Drawn review ROIs have an id `cvat_canvas_issue_region_{issue.id}` +- Drawn review roi has the class `cvat_canvas_issue_region` +- Drawn texts have the class `cvat_canvas_text` +- Tags have the class `cvat_canvas_tag` +- Canvas image has ID `cvat_canvas_image` +- Grid on the canvas has ID `cvat_canvas_grid` and `cvat_canvas_grid_pattern` +- Crosshair during a draw has class `cvat_canvas_crosshair` +- To stick something to a specific position you can use an element with id `cvat_canvas_attachment_board` ### Events Standard JS events are used. + ```js - canvas.setup - canvas.activated => {state: ObjectState} @@ -146,6 +171,7 @@ Standard JS events are used. - canvas.moved => {states: ObjectState[], x: number, y: number} - canvas.find => {states: ObjectState[], x: number, y: number} - canvas.drawn => {state: DrawnData} + - canvas.interacted => {shapes: InteractionResult[]} - canvas.editstart - canvas.edited => {state: ObjectState, points: number[]} - canvas.splitted => {state: ObjectState} @@ -159,53 +185,62 @@ Standard JS events are used. - canvas.zoom - canvas.fit - canvas.dragshape => {id: number} + - canvas.roiselected => {points: number[]} - canvas.resizeshape => {id: number} - canvas.contextmenu => { mouseEvent: MouseEvent, objectState: ObjectState, pointID: number } + - canvas.error => { exception: Error } ``` ### WEB + ```js - // Create an instance of a canvas - const canvas = new window.canvas.Canvas(); - - console.log('Version ', window.canvas.CanvasVersion); - console.log('Current mode is ', window.canvas.mode()); - - // Put canvas to a html container - htmlContainer.appendChild(canvas.html()); - canvas.fitCanvas(); - - // Next you can use its API methods. For example: - canvas.rotate(270); - canvas.draw({ - enabled: true, - shapeType: 'rectangle', - crosshair: true, - rectDrawingMethod: window.Canvas.RectDrawingMethod.CLASSIC, - }); +// Create an instance of a canvas +const canvas = new window.canvas.Canvas(); + +console.log('Version ', window.canvas.CanvasVersion); +console.log('Current mode is ', window.canvas.mode()); + +// Put canvas to a html container +htmlContainer.appendChild(canvas.html()); +canvas.fitCanvas(); + +// Next you can use its API methods. For example: +canvas.rotate(270); +canvas.draw({ + enabled: true, + shapeType: 'rectangle', + crosshair: true, + rectDrawingMethod: window.Canvas.RectDrawingMethod.CLASSIC, +}); ``` + + ## API Reaction -| | IDLE | GROUP | SPLIT | DRAW | MERGE | EDIT | DRAG | RESIZE | ZOOM_CANVAS | DRAG_CANVAS | -|--------------|------|-------|-------|------|-------|------|------|--------|-------------|-------------| -| setup() | + | + | + | +/- | + | +/- | +/- | +/- | + | + | -| activate() | + | - | - | - | - | - | - | - | - | - | -| rotate() | + | + | + | + | + | + | + | + | + | + | -| focus() | + | + | + | + | + | + | + | + | + | + | -| fit() | + | + | + | + | + | + | + | + | + | + | -| grid() | + | + | + | + | + | + | + | + | + | + | -| draw() | + | - | - | - | - | - | - | - | - | - | -| split() | + | - | + | - | - | - | - | - | - | - | -| group() | + | + | - | - | - | - | - | - | - | - | -| merge() | + | - | - | - | + | - | - | - | - | - | -| fitCanvas() | + | + | + | + | + | + | + | + | + | + | -| dragCanvas() | + | - | - | - | - | - | + | - | - | + | -| zoomCanvas() | + | - | - | - | - | - | - | + | + | - | -| cancel() | - | + | + | + | + | + | + | + | + | + | -| configure() | + | + | + | + | + | + | + | + | + | + | -| bitmap() | + | + | + | + | + | + | + | + | + | + | -| setZLayer() | + | + | + | + | + | + | + | + | + | + | +| | IDLE | GROUP | SPLIT | DRAW | MERGE | EDIT | DRAG | RESIZE | ZOOM_CANVAS | DRAG_CANVAS | INTERACT | +| ----------------- | ---- | ----- | ----- | ---- | ----- | ---- | ---- | ------ | ----------- | ----------- | -------- | +| setup() | + | + | + | +/- | + | +/- | +/- | +/- | + | + | + | +| activate() | + | - | - | - | - | - | - | - | - | - | - | +| rotate() | + | + | + | + | + | + | + | + | + | + | + | +| focus() | + | + | + | + | + | + | + | + | + | + | + | +| fit() | + | + | + | + | + | + | + | + | + | + | + | +| grid() | + | + | + | + | + | + | + | + | + | + | + | +| draw() | + | - | - | + | - | - | - | - | - | - | - | +| interact() | + | - | - | - | - | - | - | - | - | - | + | +| split() | + | - | + | - | - | - | - | - | - | - | - | +| group() | + | + | - | - | - | - | - | - | - | - | - | +| merge() | + | - | - | - | + | - | - | - | - | - | - | +| fitCanvas() | + | + | + | + | + | + | + | + | + | + | + | +| dragCanvas() | + | - | - | - | - | - | + | - | - | + | - | +| zoomCanvas() | + | - | - | - | - | - | - | + | + | - | - | +| cancel() | - | + | + | + | + | + | + | + | + | + | + | +| configure() | + | + | + | + | + | + | + | + | + | + | + | +| bitmap() | + | + | + | + | + | + | + | + | + | + | + | +| setZLayer() | + | + | + | + | + | + | + | + | + | + | + | +| setupReviewROIs() | + | + | + | + | + | + | + | + | + | + | + | + + You can call setup() during editing, dragging, and resizing only to update objects, not to change a frame. You can change frame during draw only when you do not redraw an existing object diff --git a/cvat-canvas/package-lock.json b/cvat-canvas/package-lock.json index b50b6223..ff9e2c0b 100644 --- a/cvat-canvas/package-lock.json +++ b/cvat-canvas/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas", - "version": "2.0.2", + "version": "2.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -277,6 +277,28 @@ "@babel/types": "^7.0.0" } }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, "@babel/helper-split-export-declaration": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", @@ -286,6 +308,12 @@ "@babel/types": "^7.4.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", @@ -560,6 +588,25 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" } }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", @@ -616,6 +663,23 @@ "@babel/helper-plugin-utils": "^7.0.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" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-typescript": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", @@ -1086,19 +1150,12 @@ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", "dev": true }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } @@ -1182,178 +1239,177 @@ } }, "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "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.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" + "@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.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==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "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.8.5" + "@webassemblyjs/wast-printer": "1.9.0" } }, "@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==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "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.8.5", - "mamacro": "^0.0.3" + "@webassemblyjs/ast": "1.9.0" } }, "@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==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "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.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" + "@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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "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.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/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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "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.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/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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "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.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" + "@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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "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.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/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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "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.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", + "@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.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "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.8.5", - "@webassemblyjs/wast-parser": "1.8.5", + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", "@xtuc/long": "4.2.2" } }, @@ -1586,14 +1642,23 @@ } }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "assert": { @@ -1642,10 +1707,13 @@ "dev": true }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } }, "async-each": { "version": "1.0.3", @@ -1659,6 +1727,12 @@ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, + "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==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1750,9 +1824,9 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, "babel-loader": { @@ -1838,9 +1912,9 @@ } }, "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "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 }, "batch": { @@ -1880,15 +1954,15 @@ } }, "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "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==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body-parser": { @@ -2044,21 +2118,50 @@ "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "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" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "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.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "browserify-zlib": { @@ -2082,9 +2185,9 @@ } }, "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "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", @@ -2122,6 +2225,29 @@ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "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", @@ -2246,6 +2372,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", "dev": true, + "optional": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -2262,9 +2389,9 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "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": { @@ -2337,29 +2464,51 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "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" + } + }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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": "^3.0.0" + "ansi-regex": "^4.1.0" + } + }, + "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" } } } @@ -2434,12 +2583,20 @@ "dev": true }, "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { - "mime-db": ">= 1.40.0 < 2" + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + } } }, "compression": { @@ -2476,12 +2633,12 @@ } }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz", + "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop": "^4.2.1", "graceful-fs": "^4.1.2", "make-dir": "^1.0.0", "unique-string": "^1.0.0", @@ -2519,13 +2676,10 @@ "dev": true }, "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true }, "console-control-strings": { "version": "1.1.0", @@ -2667,13 +2821,21 @@ } }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "create-error-class": { @@ -2868,9 +3030,9 @@ } }, "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, "dashdash": { @@ -2882,12 +3044,6 @@ "assert-plus": "^1.0.0" } }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2910,10 +3066,18 @@ "dev": true }, "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } }, "deep-extend": { "version": "0.6.0", @@ -3021,9 +3185,9 @@ "dev": true }, "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "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", @@ -3075,6 +3239,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "dns-equal": { @@ -3118,9 +3290,9 @@ "dev": true }, "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", + "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -3235,6 +3407,14 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "emoji-regex": { @@ -3669,15 +3849,15 @@ "dev": true }, "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, "eventsource": { @@ -3941,9 +4121,9 @@ } }, "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "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": { @@ -4068,30 +4248,10 @@ } }, "follow-redirects": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", - "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", - "dev": true, - "requires": { - "debug": "^3.2.6" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "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 - } - } + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "dev": true }, "for-in": { "version": "1.0.2", @@ -4368,12 +4528,6 @@ "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, @@ -4790,12 +4944,6 @@ "globule": "^1.0.0" } }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, "get-stdin": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-0.1.0.tgz", @@ -4933,13 +5081,13 @@ } }, "globule": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", - "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", "dev": true, "requires": { "glob": "~7.1.1", - "lodash": "~4.17.12", + "lodash": "~4.17.10", "minimatch": "~3.0.2" } }, @@ -4977,9 +5125,9 @@ "dev": true }, "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, "har-schema": { @@ -4989,13 +5137,33 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + } } }, "has": { @@ -5067,13 +5235,33 @@ } }, "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "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.1", - "safe-buffer": "^5.0.1" + "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.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "hash.js": { @@ -5128,9 +5316,9 @@ } }, "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", "dev": true }, "http-deceiver": { @@ -5160,19 +5348,13 @@ } } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", + "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } @@ -5307,9 +5489,9 @@ "dev": true }, "in-publish": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", "dev": true }, "indent-string": { @@ -5350,9 +5532,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, "inquirer": { @@ -5437,9 +5619,15 @@ "dev": true }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "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==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, "is-accessor-descriptor": { @@ -5462,6 +5650,12 @@ } } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -5696,9 +5890,9 @@ } }, "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, "is-stream": { @@ -5765,9 +5959,9 @@ "dev": true }, "js-base64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", - "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", "dev": true }, "js-levenshtein": { @@ -5986,9 +6180,9 @@ "dev": true }, "loglevel": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", - "integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", + "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==", "dev": true }, "loose-envify": { @@ -6035,12 +6229,6 @@ "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==", - "dev": true - }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -6249,6 +6437,14 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "mime": { @@ -6453,9 +6649,9 @@ "dev": true }, "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", "dev": true }, "node-gyp": { @@ -6544,9 +6740,9 @@ } }, "node-sass": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", - "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", "dev": true, "requires": { "async-foreach": "^0.1.3", @@ -6563,7 +6759,7 @@ "node-gyp": "^3.8.0", "npmlog": "^4.0.0", "request": "^2.88.0", - "sass-graph": "^2.2.4", + "sass-graph": "2.2.5", "stdout-stream": "^1.4.0", "true-case-path": "^1.0.2" }, @@ -6628,23 +6824,43 @@ } }, "nodemon": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", - "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" }, "dependencies": { + "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" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -6660,6 +6876,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6780,6 +7002,75 @@ } } }, + "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-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -7039,18 +7330,18 @@ } }, "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "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.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "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": "~0.2.2", + "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } @@ -7065,14 +7356,13 @@ } }, "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.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" @@ -7171,9 +7461,9 @@ } }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -7189,6 +7479,13 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "optional": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -7220,14 +7517,46 @@ } }, "portfinder": { - "version": "1.0.21", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", - "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", "dev": true, "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "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" + } + }, + "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 + } } }, "posix-character-classes": { @@ -7792,13 +8121,13 @@ "dev": true }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "dev": true, "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "ipaddr.js": "1.9.1" } }, "prr": { @@ -7814,15 +8143,15 @@ "dev": true }, "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, "public-encrypt": { @@ -7837,6 +8166,14 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "pump": { @@ -7897,9 +8234,9 @@ "dev": true }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, "randombytes": { @@ -8101,6 +8438,69 @@ "integrity": "sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==", "dev": true }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -8232,12 +8632,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -8387,260 +8781,76 @@ "dev": true }, "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", "dev": true, "requires": { "glob": "^7.0.0", "lodash": "^4.0.0", "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" + "yargs": "^13.3.2" + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" }, "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "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==", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + } + } + }, + "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" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.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==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "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" - } - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "dev": true, - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" + "amdefine": ">=0.0.4" } } } @@ -8652,12 +8862,12 @@ "dev": true }, "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "dev": true, "requires": { - "node-forge": "0.7.5" + "node-forge": "^0.10.0" } }, "semver": { @@ -8704,6 +8914,15 @@ } } }, + "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" + } + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -8963,19 +9182,28 @@ } }, "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", "dev": true, "requires": { "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "sockjs-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", "dev": true, "requires": { "debug": "^3.2.5", @@ -9038,9 +9266,9 @@ } }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "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", @@ -9094,9 +9322,9 @@ "dev": true }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -9107,12 +9335,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -9138,12 +9366,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -9153,9 +9381,9 @@ "dev": true }, "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "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", @@ -9276,9 +9504,9 @@ } }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "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": { @@ -9308,6 +9536,132 @@ } } }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -9401,9 +9755,9 @@ } }, "svg.draw.js": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/svg.draw.js/-/svg.draw.js-2.0.3.tgz", - "integrity": "sha512-GGK7vBzwdEgr5fJUupqDqYPhQBXxrtBd4CcrgqAt7S4/5REmF6JTSuITeAgfVlfXftOO90t5OqLOtJ4IEEUFVw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg.draw.js/-/svg.draw.js-2.0.4.tgz", + "integrity": "sha512-NMbecB0vg11AP76B0aLfI2cX7g9WurPM8x3yKxuJ9feM1vkI1GVjWZZjWpo3mkEzB1UJ8pKngaPaUCIOGi8uUA==", "requires": { "svg.js": "2.x.x" } @@ -9557,9 +9911,9 @@ } }, "terser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", - "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", + "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", @@ -9576,66 +9930,27 @@ } }, "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==", + "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": "^2.1.2", + "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": { - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", - "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" - } - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "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 - }, - "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" - } } } }, @@ -9662,9 +9977,9 @@ } }, "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, "timed-out": { @@ -9674,9 +9989,9 @@ "dev": true }, "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "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" @@ -9859,9 +10174,9 @@ "dev": true }, "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", "dev": true, "requires": { "debug": "^2.2.0" @@ -10143,20 +10458,165 @@ } }, "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "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 }, "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", "dev": true, "requires": { - "chokidar": "^2.0.2", + "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": 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" + } + } } }, "wbuf": { @@ -10169,34 +10629,74 @@ } }, "webpack": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.36.1.tgz", - "integrity": "sha512-Ej01/N9W8DVyhEpeQnbUdGvOECw0L46FxS12cCOs8gSK7bhUlrbHRnWkjiXckGlHjUrmL89kDpTRIkUk6Y+fKg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", "dev": true, "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.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", + "@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.3.0", + "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", + "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.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "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" + } + } + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "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" + } + } } }, "webpack-cli": { @@ -10310,71 +10810,94 @@ } }, "webpack-dev-middleware": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", - "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", "dev": true, "requires": { "memory-fs": "^0.4.1", - "mime": "^2.4.2", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", "range-parser": "^1.2.1", "webpack-log": "^2.0.0" }, "dependencies": { "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true } } }, "webpack-dev-server": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz", - "integrity": "sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", "dev": true, "requires": { "ansi-html": "0.0.7", "bonjour": "^3.5.0", - "chokidar": "^2.1.6", + "chokidar": "^2.1.8", "compression": "^1.7.4", "connect-history-api-fallback": "^1.6.0", "debug": "^4.1.1", "del": "^4.1.1", "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "^0.19.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", "import-local": "^2.0.0", "internal-ip": "^4.3.0", "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", "killable": "^1.0.1", - "loglevel": "^1.6.3", + "loglevel": "^1.6.8", "opn": "^5.5.0", "p-retry": "^3.0.1", - "portfinder": "^1.0.20", + "portfinder": "^1.0.26", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.4", - "semver": "^6.1.1", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "^4.0.0", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.0", + "webpack-dev-middleware": "^3.7.2", "webpack-log": "^2.0.0", - "yargs": "12.0.5" + "ws": "^6.2.1", + "yargs": "^13.3.2" }, "dependencies": { + "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" + } + }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -10384,9 +10907,9 @@ "dev": true }, "semver": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", - "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -10402,9 +10925,9 @@ } }, "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "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", @@ -10420,13 +10943,11 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -10484,38 +11005,6 @@ "errno": "~0.1.7" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -10542,6 +11031,15 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", @@ -10567,29 +11065,67 @@ "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "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 + }, + "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 + }, + "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 + }, + "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" + } + }, + "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" + } + } } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "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", diff --git a/cvat-canvas/package.json b/cvat-canvas/package.json index 8792ce08..0fb63b61 100644 --- a/cvat-canvas/package.json +++ b/cvat-canvas/package.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas", - "version": "2.0.2", + "version": "2.2.1", "description": "Part of Computer Vision Annotation Tool which presents its canvas library", "main": "src/canvas.ts", "scripts": { @@ -11,7 +11,7 @@ "license": "MIT", "dependencies": { "svg.draggable.js": "2.2.2", - "svg.draw.js": "^2.0.3", + "svg.draw.js": "^2.0.4", "svg.js": "2.7.1", "svg.resize.js": "1.4.3", "svg.select.js": "3.0.1" @@ -20,6 +20,7 @@ "@babel/cli": "^7.5.5", "@babel/core": "^7.5.5", "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", "@babel/preset-env": "^7.5.5", "@babel/preset-typescript": "^7.3.3", "@types/node": "^12.6.8", @@ -32,15 +33,15 @@ "eslint-config-airbnb-typescript": "^4.0.1", "eslint-config-typescript-recommended": "^1.4.17", "eslint-plugin-import": "^2.18.2", - "node-sass": "^4.13.1", - "nodemon": "^1.19.1", + "node-sass": "^4.14.1", + "nodemon": "^1.19.4", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", "sass-loader": "^8.0.2", "style-loader": "^1.0.0", "typescript": "^3.5.3", - "webpack": "^4.36.1", + "webpack": "^4.44.2", "webpack-cli": "^3.3.6", - "webpack-dev-server": "^3.7.2" + "webpack-dev-server": "^3.11.0" } } diff --git a/cvat-canvas/postcss.config.js b/cvat-canvas/postcss.config.js index 07d9a7dc..3a833a37 100644 --- a/cvat-canvas/postcss.config.js +++ b/cvat-canvas/postcss.config.js @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: MIT -/* eslint-disable */ module.exports = { parser: false, plugins: { diff --git a/cvat-canvas/src/scss/canvas.scss b/cvat-canvas/src/scss/canvas.scss index 090ec163..57293d29 100644 --- a/cvat-canvas/src/scss/canvas.scss +++ b/cvat-canvas/src/scss/canvas.scss @@ -41,7 +41,7 @@ polyline.cvat_shape_drawing_opacity { font-size: 1.2em; fill: white; cursor: default; - font-family: Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif; + font-family: Calibri, Candara, Segoe, 'Segoe UI', Optima, Arial, sans-serif; text-shadow: 0 0 4px black; user-select: none; pointer-events: none; @@ -58,6 +58,23 @@ polyline.cvat_shape_drawing_opacity { fill: darkmagenta; } +.cvat_canvas_shape_region_selection { + @extend .cvat_shape_action_dasharray; + @extend .cvat_shape_action_opacity; + + fill: white; + stroke: white; +} + +.cvat_canvas_issue_region { + display: none; + stroke-width: 0; +} + +circle.cvat_canvas_issue_region { + opacity: 1 !important; +} + polyline.cvat_canvas_shape_grouping { @extend .cvat_shape_action_dasharray; @extend .cvat_shape_action_opacity; @@ -258,6 +275,15 @@ polyline.cvat_canvas_shape_splitting { height: 100%; } +#cvat_canvas_attachment_board { + position: absolute; + z-index: 4; + pointer-events: none; + width: 100%; + height: 100%; + user-select: none; +} + @keyframes loadingAnimation { 0% { stroke-dashoffset: 1; diff --git a/cvat-canvas/src/typescript/autoborderHandler.ts b/cvat-canvas/src/typescript/autoborderHandler.ts index 198a485e..36a8e3d5 100644 --- a/cvat-canvas/src/typescript/autoborderHandler.ts +++ b/cvat-canvas/src/typescript/autoborderHandler.ts @@ -27,10 +27,16 @@ export class AutoborderHandlerImpl implements AutoborderHandler { private groups: SVGGElement[]; private auxiliaryGroupID: number | null; private auxiliaryClicks: number[]; - private listeners: Record void; - dblclick: (event: MouseEvent) => void; - }>>; + private listeners: Record< + number, + Record< + number, + { + click: (event: MouseEvent) => void; + dblclick: (event: MouseEvent) => void; + } + > + >; public constructor(frameContent: SVGSVGElement) { this.frameContent = frameContent; @@ -47,12 +53,11 @@ export class AutoborderHandlerImpl implements AutoborderHandler { private removeMarkers(): void { this.groups.forEach((group: SVGGElement): void => { const groupID = group.dataset.groupId; - Array.from(group.children) - .forEach((circle: SVGCircleElement, pointID: number): void => { - circle.removeEventListener('click', this.listeners[+groupID][pointID].click); - circle.removeEventListener('dblclick', this.listeners[+groupID][pointID].click); - circle.remove(); - }); + Array.from(group.children).forEach((circle: SVGCircleElement, pointID: number): void => { + circle.removeEventListener('click', this.listeners[+groupID][pointID].click); + circle.removeEventListener('dblclick', this.listeners[+groupID][pointID].click); + circle.remove(); + }); group.remove(); }); @@ -89,8 +94,9 @@ export class AutoborderHandlerImpl implements AutoborderHandler { if (this.auxiliaryGroupID !== null) { while (this.auxiliaryClicks.length > 0) { const resetID = this.auxiliaryClicks.pop(); - this.groups[this.auxiliaryGroupID] - .children[resetID].classList.remove('cvat_canvas_autoborder_point_direction'); + this.groups[this.auxiliaryGroupID].children[resetID].classList.remove( + 'cvat_canvas_autoborder_point_direction', + ); } } @@ -103,125 +109,125 @@ export class AutoborderHandlerImpl implements AutoborderHandler { private drawMarkers(transformedShapes: TransformedShape[]): void { const svgNamespace = 'http://www.w3.org/2000/svg'; - this.groups = transformedShapes - .map((shape: TransformedShape, groupID: number): SVGGElement => { + this.groups = transformedShapes.map( + (shape: TransformedShape, groupID: number): SVGGElement => { const group = document.createElementNS(svgNamespace, 'g'); group.setAttribute('data-group-id', `${groupID}`); this.listeners[groupID] = this.listeners[groupID] || {}; - const circles = shape.points.split(/\s/).map(( - point: string, pointID: number, points: string[], - ): SVGCircleElement => { - const [x, y] = point.split(','); - - const circle = document.createElementNS(svgNamespace, 'circle'); - circle.classList.add('cvat_canvas_autoborder_point'); - circle.setAttribute('fill', shape.color); - circle.setAttribute('stroke', 'black'); - circle.setAttribute('stroke-width', `${consts.POINTS_STROKE_WIDTH / this.scale}`); - circle.setAttribute('cx', x); - circle.setAttribute('cy', y); - circle.setAttribute('r', `${consts.BASE_POINT_SIZE / this.scale}`); - - const click = (event: MouseEvent): void => { - event.stopPropagation(); - - // another shape was clicked - if (this.auxiliaryGroupID !== null - && this.auxiliaryGroupID !== groupID - ) { - this.resetAuxiliaryShape(); - } - - this.auxiliaryGroupID = groupID; - // up clicked group for convenience - this.frameContent.appendChild(group); - - if (this.auxiliaryClicks[1] === pointID) { - // the second point was clicked twice - this.addPointToCurrentShape(+x, +y); - this.resetAuxiliaryShape(); - return; - } - - // the first point can not be clicked twice - // just ignore such a click if it is - if (this.auxiliaryClicks[0] !== pointID) { - this.auxiliaryClicks.push(pointID); - } else { - return; - } - - // it is the first click - if (this.auxiliaryClicks.length === 1) { - const handler = this.currentShape.remember('_paintHandler'); - // draw and remove initial point just to initialize data structures - if (!handler || !handler.startPoint) { - (this.currentShape as any).draw('point', event); - (this.currentShape as any).draw('undo'); + const circles = shape.points.split(/\s/).map( + (point: string, pointID: number, points: string[]): SVGCircleElement => { + const [x, y] = point.split(','); + + const circle = document.createElementNS(svgNamespace, 'circle'); + circle.classList.add('cvat_canvas_autoborder_point'); + circle.setAttribute('fill', shape.color); + circle.setAttribute('stroke', 'black'); + circle.setAttribute('stroke-width', `${consts.POINTS_STROKE_WIDTH / this.scale}`); + circle.setAttribute('cx', x); + circle.setAttribute('cy', y); + circle.setAttribute('r', `${consts.BASE_POINT_SIZE / this.scale}`); + + const click = (event: MouseEvent): void => { + event.stopPropagation(); + + // another shape was clicked + if (this.auxiliaryGroupID !== null && this.auxiliaryGroupID !== groupID) { + this.resetAuxiliaryShape(); } - this.addPointToCurrentShape(+x, +y); - // is is the second click - } else if (this.auxiliaryClicks.length === 2) { - circle.classList.add('cvat_canvas_autoborder_point_direction'); - // it is the third click - } else { - // sign defines bypass direction - const landmarks = this.auxiliaryClicks; - const sign = Math.sign(landmarks[2] - landmarks[0]) - * Math.sign(landmarks[1] - landmarks[0]) - * Math.sign(landmarks[2] - landmarks[1]); - - // go via a polygon and get vertexes - // the first vertex has been already drawn - const way = []; - for (let i = landmarks[0] + sign; ; i += sign) { - if (i < 0) { - i = points.length - 1; - } else if (i === points.length) { - i = 0; - } + this.auxiliaryGroupID = groupID; + // up clicked group for convenience + this.frameContent.appendChild(group); - way.push(points[i]); - - if (i === this.auxiliaryClicks[this.auxiliaryClicks.length - 1]) { - // put the last element twice - // specific of svg.draw.js - // way.push(points[i]); - break; - } + if (this.auxiliaryClicks[1] === pointID) { + // the second point was clicked twice + this.addPointToCurrentShape(+x, +y); + this.resetAuxiliaryShape(); + return; } - // remove the latest cursor position from drawing array - for (const wayPoint of way) { - const [_x, _y] = wayPoint.split(',') - .map((coordinate: string): number => +coordinate); - this.addPointToCurrentShape(_x, _y); + // the first point can not be clicked twice + // just ignore such a click if it is + if (this.auxiliaryClicks[0] !== pointID) { + this.auxiliaryClicks.push(pointID); + } else { + return; } - this.resetAuxiliaryShape(); - } - }; + // it is the first click + if (this.auxiliaryClicks.length === 1) { + const handler = this.currentShape.remember('_paintHandler'); + // draw and remove initial point just to initialize data structures + if (!handler || !handler.startPoint) { + (this.currentShape as any).draw('point', event); + (this.currentShape as any).draw('undo'); + } + this.addPointToCurrentShape(+x, +y); + // is is the second click + } else if (this.auxiliaryClicks.length === 2) { + circle.classList.add('cvat_canvas_autoborder_point_direction'); + // it is the third click + } else { + // sign defines bypass direction + const landmarks = this.auxiliaryClicks; + const sign = + Math.sign(landmarks[2] - landmarks[0]) * + Math.sign(landmarks[1] - landmarks[0]) * + Math.sign(landmarks[2] - landmarks[1]); + + // go via a polygon and get vertexes + // the first vertex has been already drawn + const way = []; + for (let i = landmarks[0] + sign; ; i += sign) { + if (i < 0) { + i = points.length - 1; + } else if (i === points.length) { + i = 0; + } + + way.push(points[i]); + + if (i === this.auxiliaryClicks[this.auxiliaryClicks.length - 1]) { + // put the last element twice + // specific of svg.draw.js + // way.push(points[i]); + break; + } + } - const dblclick = (event: MouseEvent): void => { - event.stopPropagation(); - }; + // remove the latest cursor position from drawing array + for (const wayPoint of way) { + const [_x, _y] = wayPoint + .split(',') + .map((coordinate: string): number => +coordinate); + this.addPointToCurrentShape(_x, _y); + } - this.listeners[groupID][pointID] = { - click, - dblclick, - }; + this.resetAuxiliaryShape(); + } + }; - circle.addEventListener('mousedown', this.listeners[groupID][pointID].click); - circle.addEventListener('dblclick', this.listeners[groupID][pointID].click); - return circle; - }); + const dblclick = (event: MouseEvent): void => { + event.stopPropagation(); + }; + + this.listeners[groupID][pointID] = { + click, + dblclick, + }; + + circle.addEventListener('mousedown', this.listeners[groupID][pointID].click); + circle.addEventListener('dblclick', this.listeners[groupID][pointID].click); + return circle; + }, + ); group.append(...circles); return group; - }); + }, + ); this.frameContent.append(...this.groups); } @@ -231,55 +237,54 @@ export class AutoborderHandlerImpl implements AutoborderHandler { this.removeMarkers(); const currentClientID = this.currentShape.node.dataset.originClientId; - const shapes = Array.from(this.frameContent.getElementsByClassName('cvat_canvas_shape')) - .filter((shape: HTMLElement): boolean => +shape.getAttribute('clientID') !== this.currentID); - const transformedShapes = shapes.map((shape: HTMLElement): TransformedShape | null => { - const color = shape.getAttribute('fill'); - const clientID = shape.getAttribute('clientID'); - - if (color === null || clientID === null) return null; - if (+clientID === +currentClientID) { - return null; - } - - let points = ''; - if (shape.tagName === 'polyline' || shape.tagName === 'polygon') { - points = shape.getAttribute('points'); - } else if (shape.tagName === 'rect') { - const x = +shape.getAttribute('x'); - const y = +shape.getAttribute('y'); - const width = +shape.getAttribute('width'); - const height = +shape.getAttribute('height'); - - if (Number.isNaN(x) || Number.isNaN(y) || Number.isNaN(x) || Number.isNaN(x)) { + const shapes = Array.from(this.frameContent.getElementsByClassName('cvat_canvas_shape')).filter( + (shape: HTMLElement): boolean => +shape.getAttribute('clientID') !== this.currentID, + ); + const transformedShapes = shapes + .map((shape: HTMLElement): TransformedShape | null => { + const color = shape.getAttribute('fill'); + const clientID = shape.getAttribute('clientID'); + + if (color === null || clientID === null) return null; + if (+clientID === +currentClientID) { return null; } - points = `${x},${y} ${x + width},${y} ${x + width},${y + height} ${x},${y + height}`; - } else if (shape.tagName === 'g') { - const polylineID = shape.dataset.polylineId; - const polyline = this.frameContent.getElementById(polylineID); - if (polyline && polyline.getAttribute('points')) { - points = polyline.getAttribute('points'); - } else { - return null; + let points = ''; + if (shape.tagName === 'polyline' || shape.tagName === 'polygon') { + points = shape.getAttribute('points'); + } else if (shape.tagName === 'rect') { + const x = +shape.getAttribute('x'); + const y = +shape.getAttribute('y'); + const width = +shape.getAttribute('width'); + const height = +shape.getAttribute('height'); + + if (Number.isNaN(x) || Number.isNaN(y) || Number.isNaN(x) || Number.isNaN(x)) { + return null; + } + + points = `${x},${y} ${x + width},${y} ${x + width},${y + height} ${x},${y + height}`; + } else if (shape.tagName === 'g') { + const polylineID = shape.dataset.polylineId; + const polyline = this.frameContent.getElementById(polylineID); + if (polyline && polyline.getAttribute('points')) { + points = polyline.getAttribute('points'); + } else { + return null; + } } - } - return { - color, - points: points.trim(), - }; - }).filter((state: TransformedShape | null): boolean => state !== null); + return { + color, + points: points.trim(), + }; + }) + .filter((state: TransformedShape | null): boolean => state !== null); this.drawMarkers(transformedShapes); } - public autoborder( - enabled: boolean, - currentShape?: SVG.Shape, - currentID?: number, - ): void { + public autoborder(enabled: boolean, currentShape?: SVG.Shape, currentID?: number): void { if (enabled && !this.enabled && currentShape) { this.enabled = true; this.currentShape = currentShape; diff --git a/cvat-canvas/src/typescript/canvas.ts b/cvat-canvas/src/typescript/canvas.ts index 35699766..bc19a838 100644 --- a/cvat-canvas/src/typescript/canvas.ts +++ b/cvat-canvas/src/typescript/canvas.ts @@ -8,26 +8,18 @@ import { MergeData, SplitData, GroupData, + InteractionData as _InteractionData, + InteractionResult as _InteractionResult, CanvasModel, CanvasModelImpl, RectDrawingMethod, CuboidDrawingMethod, Configuration, + Geometry, } from './canvasModel'; - -import { - Master, -} from './master'; - -import { - CanvasController, - CanvasControllerImpl, -} from './canvasController'; - -import { - CanvasView, - CanvasViewImpl, -} from './canvasView'; +import { Master } from './master'; +import { CanvasController, CanvasControllerImpl } from './canvasController'; +import { CanvasView, CanvasViewImpl } from './canvasView'; import '../scss/canvas.scss'; import pjson from '../../package.json'; @@ -37,12 +29,14 @@ const CanvasVersion = pjson.version; interface Canvas { html(): HTMLDivElement; setup(frameData: any, objectStates: any[], zLayer?: number): void; + setupIssueRegions(issueRegions: Record): void; activate(clientID: number | null, attributeID?: number): void; rotate(rotationAngle: number): void; focus(clientID: number, padding?: number): void; fit(): void; grid(stepX: number, stepY: number): void; + interact(interactionData: InteractionData): void; draw(drawData: DrawData): void; group(groupData: GroupData): void; split(splitData: SplitData): void; @@ -51,6 +45,7 @@ interface Canvas { fitCanvas(): void; bitmap(enable: boolean): void; + selectRegion(enable: boolean): void; dragCanvas(enable: boolean): void; zoomCanvas(enable: boolean): void; @@ -58,6 +53,8 @@ interface Canvas { cancel(): void; configure(configuration: Configuration): void; isAbleToChangeFrame(): boolean; + + readonly geometry: Geometry; } class CanvasImpl implements Canvas { @@ -79,17 +76,22 @@ class CanvasImpl implements Canvas { this.model.setup(frameData, objectStates, zLayer); } + public setupIssueRegions(issueRegions: Record): void { + this.model.setupIssueRegions(issueRegions); + } + public fitCanvas(): void { - this.model.fitCanvas( - this.view.html().clientWidth, - this.view.html().clientHeight, - ); + this.model.fitCanvas(this.view.html().clientWidth, this.view.html().clientHeight); } public bitmap(enable: boolean): void { this.model.bitmap(enable); } + public selectRegion(enable: boolean): void { + this.model.selectRegion(enable); + } + public dragCanvas(enable: boolean): void { this.model.dragCanvas(enable); } @@ -118,6 +120,10 @@ class CanvasImpl implements Canvas { this.model.grid(stepX, stepY); } + public interact(interactionData: InteractionData): void { + this.model.interact(interactionData); + } + public draw(drawData: DrawData): void { this.model.draw(drawData); } @@ -153,13 +159,15 @@ class CanvasImpl implements Canvas { public isAbleToChangeFrame(): boolean { return this.model.isAbleToChangeFrame(); } + + public get geometry(): Geometry { + return this.model.geometry; + } } +export type InteractionData = _InteractionData; +export type InteractionResult = _InteractionResult; + export { - CanvasImpl as Canvas, - CanvasVersion, - Configuration, - RectDrawingMethod, - CuboidDrawingMethod, - Mode as CanvasMode, + CanvasImpl as Canvas, CanvasVersion, RectDrawingMethod, CuboidDrawingMethod, Mode as CanvasMode, }; diff --git a/cvat-canvas/src/typescript/canvasController.ts b/cvat-canvas/src/typescript/canvasController.ts index 179f9b32..dca3c7d8 100644 --- a/cvat-canvas/src/typescript/canvasController.ts +++ b/cvat-canvas/src/typescript/canvasController.ts @@ -13,26 +13,33 @@ import { SplitData, GroupData, Mode, + InteractionData, + Configuration, } from './canvasModel'; export interface CanvasController { readonly objects: any[]; + readonly issueRegions: Record; readonly zLayer: number | null; readonly focusData: FocusData; readonly activeElement: ActiveElement; readonly drawData: DrawData; + readonly interactionData: InteractionData; readonly mergeData: MergeData; readonly splitData: SplitData; readonly groupData: GroupData; readonly selected: any; + readonly configuration: Configuration; mode: Mode; geometry: Geometry; zoom(x: number, y: number, direction: number): void; draw(drawData: DrawData): void; + interact(interactionData: InteractionData): void; merge(mergeData: MergeData): void; split(splitData: SplitData): void; group(groupData: GroupData): void; + selectRegion(enabled: boolean): void; enableDrag(x: number, y: number): void; drag(x: number, y: number): void; disableDrag(): void; @@ -84,6 +91,10 @@ export class CanvasControllerImpl implements CanvasController { this.model.draw(drawData); } + public interact(interactionData: InteractionData): void { + this.model.interact(interactionData); + } + public merge(mergeData: MergeData): void { this.model.merge(mergeData); } @@ -96,6 +107,10 @@ export class CanvasControllerImpl implements CanvasController { this.model.group(groupData); } + public selectRegion(enable: boolean): void { + this.model.selectRegion(enable); + } + public get geometry(): Geometry { return this.model.geometry; } @@ -108,6 +123,10 @@ export class CanvasControllerImpl implements CanvasController { return this.model.zLayer; } + public get issueRegions(): Record { + return this.model.issueRegions; + } + public get objects(): any[] { return this.model.objects; } @@ -124,6 +143,10 @@ export class CanvasControllerImpl implements CanvasController { return this.model.drawData; } + public get interactionData(): InteractionData { + return this.model.interactionData; + } + public get mergeData(): MergeData { return this.model.mergeData; } @@ -140,6 +163,10 @@ export class CanvasControllerImpl implements CanvasController { return this.model.selected; } + public get configuration(): Configuration { + return this.model.configuration; + } + public set mode(value: Mode) { this.model.mode = value; } diff --git a/cvat-canvas/src/typescript/canvasModel.ts b/cvat-canvas/src/typescript/canvasModel.ts index ec860e77..4a30e618 100644 --- a/cvat-canvas/src/typescript/canvasModel.ts +++ b/cvat-canvas/src/typescript/canvasModel.ts @@ -43,7 +43,7 @@ export interface ActiveElement { export enum RectDrawingMethod { CLASSIC = 'By 2 points', - EXTREME_POINTS = 'By 4 points' + EXTREME_POINTS = 'By 4 points', } export enum CuboidDrawingMethod { @@ -56,6 +56,7 @@ export interface Configuration { displayAllText?: boolean; undefinedAttrValue?: string; showProjections?: boolean; + forceDisableEditing?: boolean; } export interface DrawData { @@ -69,6 +70,20 @@ export interface DrawData { redraw?: number; } +export interface InteractionData { + enabled: boolean; + shapeType?: string; + crosshair?: boolean; + minPosVertices?: number; + minNegVertices?: number; +} + +export interface InteractionResult { + points: number[]; + shapeType: string; + button: number; +} + export interface EditData { enabled: boolean; state: any; @@ -99,12 +114,14 @@ export enum UpdateReasons { IMAGE_MOVED = 'image_moved', GRID_UPDATED = 'grid_updated', + ISSUE_REGIONS_UPDATED = 'issue_regions_updated', OBJECTS_UPDATED = 'objects_updated', SHAPE_ACTIVATED = 'shape_activated', SHAPE_FOCUSED = 'shape_focused', FITTED_CANVAS = 'fitted_canvas', + INTERACT = 'interact', DRAW = 'draw', MERGE = 'merge', SPLIT = 'split', @@ -112,9 +129,11 @@ export enum UpdateReasons { SELECT = 'select', CANCEL = 'cancel', BITMAP = 'bitmap', + SELECT_REGION = 'select_region', DRAG_CANVAS = 'drag_canvas', ZOOM_CANVAS = 'zoom_canvas', CONFIG_UPDATED = 'config_updated', + DATA_FAILED = 'data_failed', } export enum Mode { @@ -126,6 +145,8 @@ export enum Mode { MERGE = 'merge', SPLIT = 'split', GROUP = 'group', + INTERACT = 'interact', + SELECT_REGION = 'select_region', DRAG_CANVAS = 'drag_canvas', ZOOM_CANVAS = 'zoom_canvas', } @@ -133,12 +154,14 @@ export enum Mode { export interface CanvasModel { readonly imageBitmap: boolean; readonly image: Image | null; + readonly issueRegions: Record; readonly objects: any[]; readonly zLayer: number | null; readonly gridSize: Size; readonly focusData: FocusData; readonly activeElement: ActiveElement; readonly drawData: DrawData; + readonly interactionData: InteractionData; readonly mergeData: MergeData; readonly splitData: SplitData; readonly groupData: GroupData; @@ -146,11 +169,13 @@ export interface CanvasModel { readonly selected: any; geometry: Geometry; mode: Mode; + exception: Error | null; zoom(x: number, y: number, direction: number): void; move(topOffset: number, leftOffset: number): void; setup(frameData: any, objectStates: any[], zLayer: number): void; + setupIssueRegions(issueRegions: Record): void; activate(clientID: number | null, attributeID: number | null): void; rotate(rotationAngle: number): void; focus(clientID: number, padding: number): void; @@ -162,9 +187,11 @@ export interface CanvasModel { split(splitData: SplitData): void; merge(mergeData: MergeData): void; select(objectState: any): void; + interact(interactionData: InteractionData): void; fitCanvas(width: number, height: number): void; bitmap(enabled: boolean): void; + selectRegion(enabled: boolean): void; dragCanvas(enable: boolean): void; zoomCanvas(enable: boolean): void; @@ -188,15 +215,18 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { gridSize: Size; left: number; objects: any[]; + issueRegions: Record; scale: number; top: number; zLayer: number | null; drawData: DrawData; + interactionData: InteractionData; mergeData: MergeData; groupData: GroupData; splitData: SplitData; selected: any; mode: Mode; + exception: Error | null; }; public constructor() { @@ -235,6 +265,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { }, left: 0, objects: [], + issueRegions: {}, scale: 1, top: 0, zLayer: null, @@ -242,6 +273,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { enabled: false, initialState: null, }, + interactionData: { + enabled: false, + }, mergeData: { enabled: false, }, @@ -253,28 +287,29 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { }, selected: null, mode: Mode.IDLE, + exception: null, }; } public zoom(x: number, y: number, direction: number): void { const oldScale: number = this.data.scale; - const newScale: number = direction > 0 ? oldScale * 6 / 5 : oldScale * 5 / 6; + const newScale: number = direction > 0 ? (oldScale * 6) / 5 : (oldScale * 5) / 6; this.data.scale = Math.min(Math.max(newScale, FrameZoom.MIN), FrameZoom.MAX); const { angle } = this.data; - const mutiplier = Math.sin(angle * Math.PI / 180) + Math.cos(angle * Math.PI / 180); + const mutiplier = Math.sin((angle * Math.PI) / 180) + Math.cos((angle * Math.PI) / 180); if ((angle / 90) % 2) { // 90, 270, .. - this.data.top += mutiplier * ((x - this.data.imageSize.width / 2) - * (oldScale / this.data.scale - 1)) * this.data.scale; - this.data.left -= mutiplier * ((y - this.data.imageSize.height / 2) - * (oldScale / this.data.scale - 1)) * this.data.scale; + const topMultiplier = (x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1); + const leftMultiplier = (y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1); + this.data.top += mutiplier * topMultiplier * this.data.scale; + this.data.left -= mutiplier * leftMultiplier * this.data.scale; } else { - this.data.left += mutiplier * ((x - this.data.imageSize.width / 2) - * (oldScale / this.data.scale - 1)) * this.data.scale; - this.data.top += mutiplier * ((y - this.data.imageSize.height / 2) - * (oldScale / this.data.scale - 1)) * this.data.scale; + const leftMultiplier = (x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1); + const topMultiplier = (y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1); + this.data.left += mutiplier * leftMultiplier * this.data.scale; + this.data.top += mutiplier * topMultiplier * this.data.scale; } this.notify(UpdateReasons.IMAGE_ZOOMED); @@ -290,10 +325,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { this.data.canvasSize.height = height; this.data.canvasSize.width = width; - this.data.imageOffset = Math.floor(Math.max( - this.data.canvasSize.height / FrameZoom.MIN, - this.data.canvasSize.width / FrameZoom.MIN, - )); + this.data.imageOffset = Math.floor( + Math.max(this.data.canvasSize.height / FrameZoom.MIN, this.data.canvasSize.width / FrameZoom.MIN), + ); this.notify(UpdateReasons.FITTED_CANVAS); this.notify(UpdateReasons.OBJECTS_UPDATED); @@ -304,6 +338,19 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { this.notify(UpdateReasons.BITMAP); } + public selectRegion(enable: boolean): void { + if (enable && this.data.mode !== Mode.IDLE) { + throw Error(`Canvas is busy. Action: ${this.data.mode}`); + } + + if (!enable && this.data.mode !== Mode.SELECT_REGION) { + throw Error(`Canvas is not in the region selecting mode. Action: ${this.data.mode}`); + } + + this.data.mode = enable ? Mode.SELECT_REGION : Mode.IDLE; + this.notify(UpdateReasons.SELECT_REGION); + } + public dragCanvas(enable: boolean): void { if (enable && this.data.mode !== Mode.IDLE) { throw Error(`Canvas is busy. Action: ${this.data.mode}`); @@ -345,36 +392,42 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { } this.data.imageID = frameData.number; - frameData.data( - (): void => { + frameData + .data((): void => { this.data.image = null; this.notify(UpdateReasons.IMAGE_CHANGED); - }, - ).then((data: Image): void => { - if (frameData.number !== this.data.imageID) { - // already another image - return; - } + }) + .then((data: Image): void => { + if (frameData.number !== this.data.imageID) { + // already another image + return; + } - this.data.imageSize = { - height: (frameData.height as number), - width: (frameData.width as number), - }; + this.data.imageSize = { + height: frameData.height as number, + width: frameData.width as number, + }; - this.data.image = data; - this.notify(UpdateReasons.IMAGE_CHANGED); - this.data.zLayer = zLayer; - this.data.objects = objectStates; - this.notify(UpdateReasons.OBJECTS_UPDATED); - }).catch((exception: any): void => { - throw exception; - }); + this.data.image = data; + this.notify(UpdateReasons.IMAGE_CHANGED); + this.data.zLayer = zLayer; + this.data.objects = objectStates; + this.notify(UpdateReasons.OBJECTS_UPDATED); + }) + .catch((exception: any): void => { + this.data.exception = exception; + this.notify(UpdateReasons.DATA_FAILED); + throw exception; + }); + } + + public setupIssueRegions(issueRegions: Record): void { + this.data.issueRegions = issueRegions; + this.notify(UpdateReasons.ISSUE_REGIONS_UPDATED); } public activate(clientID: number | null, attributeID: number | null): void { - if (this.data.activeElement.clientID === clientID - && this.data.activeElement.attributeID === attributeID - ) { + if (this.data.activeElement.clientID === clientID && this.data.activeElement.attributeID === attributeID) { return; } @@ -382,9 +435,8 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { throw Error(`Canvas is busy. Action: ${this.data.mode}`); } - if (typeof (clientID) === 'number') { - const [state] = this.objects - .filter((_state: any): boolean => _state.clientID === clientID); + if (typeof clientID === 'number') { + const [state] = this.objects.filter((_state: any): boolean => _state.clientID === clientID); if (!state || state.objectType === 'tag') { return; } @@ -400,7 +452,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { public rotate(rotationAngle: number): void { if (this.data.angle !== rotationAngle) { - this.data.angle = (360 + Math.floor((rotationAngle) / 90) * 90) % 360; + this.data.angle = (360 + Math.floor(rotationAngle / 90) * 90) % 360; this.fit(); } } @@ -430,13 +482,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { ); } - this.data.scale = Math.min( - Math.max(this.data.scale, FrameZoom.MIN), - FrameZoom.MAX, - ); + this.data.scale = Math.min(Math.max(this.data.scale, FrameZoom.MIN), FrameZoom.MAX); - this.data.top = (this.data.canvasSize.height / 2 - this.data.imageSize.height / 2); - this.data.left = (this.data.canvasSize.width / 2 - this.data.imageSize.width / 2); + this.data.top = this.data.canvasSize.height / 2 - this.data.imageSize.height / 2; + this.data.left = this.data.canvasSize.width / 2 - this.data.imageSize.width / 2; this.notify(UpdateReasons.IMAGE_FITTED); } @@ -460,7 +509,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { throw new Error('Drawing has been already started'); } else if (!drawData.shapeType && !drawData.initialState) { throw new Error('A shape type is not specified'); - } else if (typeof (drawData.numberOfPoints) !== 'undefined') { + } else if (typeof drawData.numberOfPoints !== 'undefined') { if (drawData.shapeType === 'polygon' && drawData.numberOfPoints < 3) { throw new Error('A polygon consists of at least 3 points'); } else if (drawData.shapeType === 'polyline' && drawData.numberOfPoints < 2) { @@ -469,10 +518,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { } } - if (typeof (drawData.redraw) === 'number') { + if (typeof drawData.redraw === 'number') { const clientID = drawData.redraw; - const [state] = this.data.objects - .filter((_state: any): boolean => _state.clientID === clientID); + const [state] = this.data.objects.filter((_state: any): boolean => _state.clientID === clientID); if (state) { this.data.drawData = { ...drawData }; @@ -490,6 +538,27 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { this.notify(UpdateReasons.DRAW); } + public interact(interactionData: InteractionData): void { + if (![Mode.IDLE, Mode.INTERACT].includes(this.data.mode)) { + throw Error(`Canvas is busy. Action: ${this.data.mode}`); + } + + if (interactionData.enabled) { + if (this.data.interactionData.enabled) { + throw new Error('Interaction has been already started'); + } else if (!interactionData.shapeType) { + throw new Error('A shape type was not specified'); + } + } + + this.data.interactionData = interactionData; + if (typeof this.data.interactionData.crosshair !== 'boolean') { + this.data.interactionData.crosshair = true; + } + + this.notify(UpdateReasons.INTERACT); + } + public split(splitData: SplitData): void { if (![Mode.IDLE, Mode.SPLIT].includes(this.data.mode)) { throw Error(`Canvas is busy. Action: ${this.data.mode}`); @@ -548,27 +617,31 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { } public configure(configuration: Configuration): void { - if (typeof (configuration.displayAllText) !== 'undefined') { + if (typeof configuration.displayAllText !== 'undefined') { this.data.configuration.displayAllText = configuration.displayAllText; } - if (typeof (configuration.showProjections) !== 'undefined') { + if (typeof configuration.showProjections !== 'undefined') { this.data.configuration.showProjections = configuration.showProjections; } - if (typeof (configuration.autoborders) !== 'undefined') { + if (typeof configuration.autoborders !== 'undefined') { this.data.configuration.autoborders = configuration.autoborders; } - if (typeof (configuration.undefinedAttrValue) !== 'undefined') { + if (typeof configuration.undefinedAttrValue !== 'undefined') { this.data.configuration.undefinedAttrValue = configuration.undefinedAttrValue; } + if (typeof configuration.forceDisableEditing !== 'undefined') { + this.data.configuration.forceDisableEditing = configuration.forceDisableEditing; + } + this.notify(UpdateReasons.CONFIG_UPDATED); } public isAbleToChangeFrame(): boolean { - const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE].includes(this.data.mode) - || (this.data.mode === Mode.DRAW && typeof (this.data.drawData.redraw) === 'number'); + const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode) + || (this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number'); return !isUnable; } @@ -604,10 +677,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { this.data.imageOffset = geometry.offset; this.data.scale = geometry.scale; - this.data.imageOffset = Math.floor(Math.max( - this.data.canvasSize.height / FrameZoom.MIN, - this.data.canvasSize.width / FrameZoom.MIN, - )); + this.data.imageOffset = Math.floor( + Math.max(this.data.canvasSize.height / FrameZoom.MIN, this.data.canvasSize.width / FrameZoom.MIN), + ); } public get zLayer(): number | null { @@ -622,10 +694,13 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { return this.data.image; } + public get issueRegions(): Record { + return { ...this.data.issueRegions }; + } + public get objects(): any[] { if (this.data.zLayer !== null) { - return this.data.objects - .filter((object: any): boolean => object.zOrder <= this.data.zLayer); + return this.data.objects.filter((object: any): boolean => object.zOrder <= this.data.zLayer); } return this.data.objects; @@ -647,6 +722,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { return { ...this.data.drawData }; } + public get interactionData(): InteractionData { + return { ...this.data.interactionData }; + } + public get mergeData(): MergeData { return { ...this.data.mergeData }; } @@ -670,4 +749,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel { public get mode(): Mode { return this.data.mode; } + public get exception(): Error { + return this.data.exception; + } } diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index 4eb95a8f..d4304f22 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -15,7 +15,9 @@ import { EditHandler, EditHandlerImpl } from './editHandler'; import { MergeHandler, MergeHandlerImpl } from './mergeHandler'; import { SplitHandler, SplitHandlerImpl } from './splitHandler'; import { GroupHandler, GroupHandlerImpl } from './groupHandler'; +import { RegionSelector, RegionSelectorImpl } from './regionSelector'; import { ZoomHandler, ZoomHandlerImpl } from './zoomHandler'; +import { InteractionHandler, InteractionHandlerImpl } from './interactionHandler'; import { AutoborderHandler, AutoborderHandlerImpl } from './autoborderHandler'; import consts from './consts'; import { @@ -42,6 +44,8 @@ import { Mode, Size, Configuration, + InteractionResult, + InteractionData, } from './canvasModel'; export interface CanvasView { @@ -56,6 +60,7 @@ export class CanvasViewImpl implements CanvasView, Listener { private bitmap: HTMLCanvasElement; private grid: SVGSVGElement; private content: SVGSVGElement; + private attachmentBoard: HTMLDivElement; private adoptedContent: SVG.Container; private canvas: HTMLDivElement; private gridPath: SVGPathElement; @@ -63,15 +68,20 @@ export class CanvasViewImpl implements CanvasView, Listener { private controller: CanvasController; private svgShapes: Record; private svgTexts: Record; + private issueRegionPattern_1: SVG.Pattern; + private issueRegionPattern_2: SVG.Pattern; private drawnStates: Record; + private drawnIssueRegions: Record; private geometry: Geometry; private drawHandler: DrawHandler; private editHandler: EditHandler; private mergeHandler: MergeHandler; private splitHandler: SplitHandler; private groupHandler: GroupHandler; + private regionSelector: RegionSelector; private zoomHandler: ZoomHandler; private autoborderHandler: AutoborderHandler; + private interactionHandler: InteractionHandler; private activeElement: ActiveElement; private configuration: Configuration; private serviceFlags: { @@ -86,6 +96,31 @@ export class CanvasViewImpl implements CanvasView, Listener { return this.controller.mode; } + private stateIsLocked(state: any): boolean { + const { configuration } = this.controller; + return state.lock || configuration.forceDisableEditing; + } + + private translateToCanvas(points: number[]): number[] { + const { offset } = this.controller.geometry; + return points.map((coord: number): number => coord + offset); + } + + private translateFromCanvas(points: number[]): number[] { + const { offset } = this.controller.geometry; + return points.map((coord: number): number => coord - offset); + } + + private stringifyToCanvas(points: number[]): string { + return points.reduce((acc: string, val: number, idx: number): string => { + if (idx % 2) { + return `${acc}${val} `; + } + + return `${acc}${val},`; + }, ''); + } + private isServiceHidden(clientID: number): boolean { return this.serviceFlags.drawHidden[clientID] || false; } @@ -98,8 +133,9 @@ export class CanvasViewImpl implements CanvasView, Listener { if (value) { if (shape) { - (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape) - .addClass('cvat_canvas_hidden'); + (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape).addClass( + 'cvat_canvas_hidden', + ); } if (text) { @@ -111,25 +147,57 @@ export class CanvasViewImpl implements CanvasView, Listener { if (state) { if (!state.outside && !state.hidden) { if (shape) { - (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape) - .removeClass('cvat_canvas_hidden'); + (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape).removeClass( + 'cvat_canvas_hidden', + ); } if (text) { text.removeClass('cvat_canvas_hidden'); - this.updateTextPosition( - text, - shape, - ); + this.updateTextPosition(text, shape); } } } } } + private onInteraction( + shapes: InteractionResult[] | null, + shapesUpdated: boolean = true, + isDone: boolean = false, + ): void { + const { zLayer } = this.controller; + if (Array.isArray(shapes)) { + const event: CustomEvent = new CustomEvent('canvas.interacted', { + bubbles: false, + cancelable: true, + detail: { + shapesUpdated, + isDone, + shapes, + zOrder: zLayer || 0, + }, + }); + + this.canvas.dispatchEvent(event); + } + + if (shapes === null || isDone) { + const event: CustomEvent = new CustomEvent('canvas.canceled', { + bubbles: false, + cancelable: true, + }); + + this.canvas.dispatchEvent(event); + this.mode = Mode.IDLE; + this.controller.interact({ + enabled: false, + }); + } + } + private onDrawDone(data: object | null, duration: number, continueDraw?: boolean): void { - const hiddenBecauseOfDraw = Object.keys(this.serviceFlags.drawHidden) - .map((_clientID): number => +_clientID); + const hiddenBecauseOfDraw = Object.keys(this.serviceFlags.drawHidden).map((_clientID): number => +_clientID); if (hiddenBecauseOfDraw.length) { for (const hidden of hiddenBecauseOfDraw) { this.setupServiceHidden(hidden, false); @@ -138,7 +206,7 @@ export class CanvasViewImpl implements CanvasView, Listener { if (data) { const { clientID, points } = data as any; - if (typeof (clientID) === 'number') { + if (typeof clientID === 'number') { const event: CustomEvent = new CustomEvent('canvas.canceled', { bubbles: false, cancelable: true, @@ -146,10 +214,7 @@ export class CanvasViewImpl implements CanvasView, Listener { this.canvas.dispatchEvent(event); - const [state] = this.controller.objects - .filter((_state: any): boolean => ( - _state.clientID === clientID - )); + const [state] = this.controller.objects.filter((_state: any): boolean => _state.clientID === clientID); this.onEditDone(state, points); return; @@ -212,7 +277,7 @@ export class CanvasViewImpl implements CanvasView, Listener { this.mode = Mode.IDLE; } - private onMergeDone(objects: any[]| null, duration?: number): void { + private onMergeDone(objects: any[] | null, duration?: number): void { if (objects) { const event: CustomEvent = new CustomEvent('canvas.merged', { bubbles: false, @@ -295,6 +360,30 @@ export class CanvasViewImpl implements CanvasView, Listener { this.mode = Mode.IDLE; } + private onRegionSelected(points?: number[]): void { + if (points) { + const event: CustomEvent = new CustomEvent('canvas.regionselected', { + bubbles: false, + cancelable: true, + detail: { + points, + }, + }); + + this.canvas.dispatchEvent(event); + } else { + const event: CustomEvent = new CustomEvent('canvas.canceled', { + bubbles: false, + cancelable: true, + }); + + this.canvas.dispatchEvent(event); + } + + this.controller.selectRegion(false); + this.mode = Mode.IDLE; + } + private onFindObject(e: MouseEvent): void { if (e.which === 1 || e.which === 0) { const { offset } = this.controller.geometry; @@ -321,24 +410,27 @@ export class CanvasViewImpl implements CanvasView, Listener { if ((this.geometry.angle / 90) % 2) { // 90, 270, .. - scale = Math.min(Math.max(Math.min( - this.geometry.canvas.width / height, - this.geometry.canvas.height / width, - ), FrameZoom.MIN), FrameZoom.MAX); + scale = Math.min( + Math.max( + Math.min(this.geometry.canvas.width / height, this.geometry.canvas.height / width), + FrameZoom.MIN, + ), + FrameZoom.MAX, + ); } else { - scale = Math.min(Math.max(Math.min( - this.geometry.canvas.width / width, - this.geometry.canvas.height / height, - ), FrameZoom.MIN), FrameZoom.MAX); + scale = Math.min( + Math.max( + Math.min(this.geometry.canvas.width / width, this.geometry.canvas.height / height), + FrameZoom.MIN, + ), + FrameZoom.MAX, + ); } this.geometry = { ...this.geometry, scale }; this.transformCanvas(); - const [canvasX, canvasY] = translateFromSVG(this.content, [ - x + width / 2, - y + height / 2, - ]); + const [canvasX, canvasY] = translateFromSVG(this.content, [x + width / 2, y + height / 2]); const canvasOffset = this.canvas.getBoundingClientRect(); const [cx, cy] = [ @@ -364,7 +456,7 @@ export class CanvasViewImpl implements CanvasView, Listener { obj.style.left = `${this.geometry.left}px`; } - for (const obj of [this.content, this.text]) { + for (const obj of [this.content, this.text, this.attachmentBoard]) { obj.style.top = `${this.geometry.top - this.geometry.offset}px`; obj.style.left = `${this.geometry.left - this.geometry.offset}px`; } @@ -373,31 +465,27 @@ export class CanvasViewImpl implements CanvasView, Listener { this.drawHandler.transform(this.geometry); this.editHandler.transform(this.geometry); this.zoomHandler.transform(this.geometry); + this.autoborderHandler.transform(this.geometry); + this.interactionHandler.transform(this.geometry); + this.regionSelector.transform(this.geometry); } private transformCanvas(): void { // Transform canvas - for (const obj of [this.background, this.grid, this.content, this.bitmap]) { + for (const obj of [this.background, this.grid, this.content, this.bitmap, this.attachmentBoard]) { obj.style.transform = `scale(${this.geometry.scale}) rotate(${this.geometry.angle}deg)`; } // Transform grid - this.gridPath.setAttribute('stroke-width', `${consts.BASE_GRID_WIDTH / (this.geometry.scale)}px`); + this.gridPath.setAttribute('stroke-width', `${consts.BASE_GRID_WIDTH / this.geometry.scale}px`); // Transform all shape points for (const element of window.document.getElementsByClassName('svg_select_points')) { - element.setAttribute( - 'stroke-width', - `${consts.POINTS_STROKE_WIDTH / this.geometry.scale}`, - ); - element.setAttribute( - 'r', - `${consts.BASE_POINT_SIZE / this.geometry.scale}`, - ); + element.setAttribute('stroke-width', `${consts.POINTS_STROKE_WIDTH / this.geometry.scale}`); + element.setAttribute('r', `${consts.BASE_POINT_SIZE / this.geometry.scale}`); } - for (const element of - window.document.getElementsByClassName('cvat_canvas_poly_direction')) { + for (const element of window.document.getElementsByClassName('cvat_canvas_poly_direction')) { const angle = (element as any).instance.data('angle'); (element as any).instance.style({ @@ -405,13 +493,9 @@ export class CanvasViewImpl implements CanvasView, Listener { }); } - for (const element of - window.document.getElementsByClassName('cvat_canvas_selected_point')) { + for (const element of window.document.getElementsByClassName('cvat_canvas_selected_point')) { const previousWidth = element.getAttribute('stroke-width') as string; - element.setAttribute( - 'stroke-width', - `${+previousWidth * 2}`, - ); + element.setAttribute('stroke-width', `${+previousWidth * 2}`); } // Transform all drawn shapes @@ -426,19 +510,42 @@ export class CanvasViewImpl implements CanvasView, Listener { // Transform all text for (const key in this.svgShapes) { - if (Object.prototype.hasOwnProperty.call(this.svgShapes, key) - && Object.prototype.hasOwnProperty.call(this.svgTexts, key)) { - this.updateTextPosition( - this.svgTexts[key], - this.svgShapes[key], - ); + if ( + Object.prototype.hasOwnProperty.call(this.svgShapes, key) + && Object.prototype.hasOwnProperty.call(this.svgTexts, key) + ) { + this.updateTextPosition(this.svgTexts[key], this.svgShapes[key]); } } + // Transform all drawn issues region + for (const issueRegion of Object.values(this.drawnIssueRegions)) { + ((issueRegion as any) as SVG.Shape).attr('r', `${(consts.BASE_POINT_SIZE * 3) / this.geometry.scale}`); + ((issueRegion as any) as SVG.Shape).attr( + 'stroke-width', + `${consts.BASE_STROKE_WIDTH / this.geometry.scale}`, + ); + } + + // Transform patterns + for (const pattern of [this.issueRegionPattern_1, this.issueRegionPattern_2]) { + pattern.attr({ + width: consts.BASE_PATTERN_SIZE / this.geometry.scale, + height: consts.BASE_PATTERN_SIZE / this.geometry.scale, + }); + + pattern.children().forEach((element: SVG.Element): void => { + element.attr('stroke-width', consts.BASE_STROKE_WIDTH / this.geometry.scale); + }); + } + // Transform handlers this.drawHandler.transform(this.geometry); this.editHandler.transform(this.geometry); + this.zoomHandler.transform(this.geometry); this.autoborderHandler.transform(this.geometry); + this.interactionHandler.transform(this.geometry); + this.regionSelector.transform(this.geometry); } private resizeCanvas(): void { @@ -447,18 +554,66 @@ export class CanvasViewImpl implements CanvasView, Listener { obj.style.height = `${this.geometry.image.height}px`; } - for (const obj of [this.content, this.text]) { + for (const obj of [this.content, this.text, this.attachmentBoard]) { obj.style.width = `${this.geometry.image.width + this.geometry.offset * 2}px`; obj.style.height = `${this.geometry.image.height + this.geometry.offset * 2}px`; } } + private setupIssueRegions(issueRegions: Record): void { + for (const issueRegion of Object.keys(this.drawnIssueRegions)) { + if (!(issueRegion in issueRegions) || !+issueRegion) { + this.drawnIssueRegions[+issueRegion].remove(); + delete this.drawnIssueRegions[+issueRegion]; + } + } - private setupObjects(states: any[]): void { - const { offset } = this.controller.geometry; - const translate = (points: number[]): number[] => points - .map((coord: number): number => coord + offset); + for (const issueRegion of Object.keys(issueRegions)) { + if (issueRegion in this.drawnIssueRegions) continue; + const points = this.translateToCanvas(issueRegions[+issueRegion]); + if (points.length === 2) { + this.drawnIssueRegions[+issueRegion] = this.adoptedContent + .circle((consts.BASE_POINT_SIZE * 3 * 2) / this.geometry.scale) + .center(points[0], points[1]) + .addClass('cvat_canvas_issue_region') + .attr({ + id: `cvat_canvas_issue_region_${issueRegion}`, + fill: 'url(#cvat_issue_region_pattern_1)', + }); + } else if (points.length === 4) { + const stringified = this.stringifyToCanvas([ + points[0], + points[1], + points[2], + points[1], + points[2], + points[3], + points[0], + points[3], + ]); + this.drawnIssueRegions[+issueRegion] = this.adoptedContent + .polygon(stringified) + .addClass('cvat_canvas_issue_region') + .attr({ + id: `cvat_canvas_issue_region_${issueRegion}`, + fill: 'url(#cvat_issue_region_pattern_1)', + 'stroke-width': `${consts.BASE_STROKE_WIDTH / this.geometry.scale}`, + }); + } else { + const stringified = this.stringifyToCanvas(points); + this.drawnIssueRegions[+issueRegion] = this.adoptedContent + .polygon(stringified) + .addClass('cvat_canvas_issue_region') + .attr({ + id: `cvat_canvas_issue_region_${issueRegion}`, + fill: 'url(#cvat_issue_region_pattern_1)', + 'stroke-width': `${consts.BASE_STROKE_WIDTH / this.geometry.scale}`, + }); + } + } + } + private setupObjects(states: any[]): void { const created = []; const updated = []; for (const state of states) { @@ -473,7 +628,8 @@ export class CanvasViewImpl implements CanvasView, Listener { } } const newIDs = states.map((state: any): number => state.clientID); - const deleted = Object.keys(this.drawnStates).map((clientID: string): number => +clientID) + const deleted = Object.keys(this.drawnStates) + .map((clientID: string): number => +clientID) .filter((id: number): boolean => !newIDs.includes(id)) .map((id: number): any => this.drawnStates[id]); @@ -492,8 +648,8 @@ export class CanvasViewImpl implements CanvasView, Listener { delete this.drawnStates[state.clientID]; } - this.addObjects(created, translate); - this.updateObjects(updated, translate); + this.addObjects(created); + this.updateObjects(updated); this.sortObjects(); if (this.controller.activeElement.clientID !== null) { @@ -519,7 +675,7 @@ export class CanvasViewImpl implements CanvasView, Listener { const node = nested.node as SVG.LinkedHTMLElement; const directions = node.getElementsByClassName('cvat_canvas_poly_direction'); for (const direction of directions) { - const { instance } = (direction as any); + const { instance } = direction as any; instance.off('click'); instance.remove(); } @@ -536,10 +692,7 @@ export class CanvasViewImpl implements CanvasView, Listener { const secondCircle = handler.nested.children()[1]; firstCircle.addClass('cvat_canvas_first_poly_point'); - const [cx, cy] = [ - (secondCircle.cx() + firstCircle.cx()) / 2, - (secondCircle.cy() + firstCircle.cy()) / 2, - ]; + const [cx, cy] = [(secondCircle.cx() + firstCircle.cx()) / 2, (secondCircle.cy() + firstCircle.cy()) / 2]; const [firstPoint, secondPoint] = points.slice(0, 2); const xAxis = { i: 1, j: 0 }; const baseVector = { i: secondPoint.x - firstPoint.x, j: secondPoint.y - firstPoint.y }; @@ -548,19 +701,23 @@ export class CanvasViewImpl implements CanvasView, Listener { if (baseVectorLength !== 0) { // two points have the same coordinates - cosinus = scalarProduct(xAxis, baseVector) - / (vectorLength(xAxis) * baseVectorLength); + cosinus = scalarProduct(xAxis, baseVector) / (vectorLength(xAxis) * baseVectorLength); } - const angle = Math.acos(cosinus) * (Math.sign(baseVector.j) || 1) * 180 / Math.PI; + const angle = (Math.acos(cosinus) * (Math.sign(baseVector.j) || 1) * 180) / Math.PI; - const pathElement = handler.nested.path(path).fill('white') + const pathElement = handler.nested + .path(path) + .fill('white') .stroke({ width: 1, color: 'black', - }).addClass('cvat_canvas_poly_direction').style({ + }) + .addClass('cvat_canvas_poly_direction') + .style({ 'transform-origin': `${cx}px ${cy}px`, transform: `scale(${1 / this.geometry.scale}) rotate(${angle}deg)`, - }).move(cx, cy); + }) + .move(cx, cy); pathElement.on('click', (e: MouseEvent): void => { if (e.button === 0) { @@ -581,35 +738,32 @@ export class CanvasViewImpl implements CanvasView, Listener { private selectize(value: boolean, shape: SVG.Element): void { const self = this; - const { offset } = this.controller.geometry; - const translate = (points: number[]): number[] => points - .map((coord: number): number => coord - offset); function mousedownHandler(e: MouseEvent): void { if (e.button !== 0) return; e.preventDefault(); - const pointID = Array.prototype.indexOf - .call(((e.target as HTMLElement).parentElement as HTMLElement).children, e.target); + const pointID = Array.prototype.indexOf.call( + ((e.target as HTMLElement).parentElement as HTMLElement).children, + e.target, + ); if (self.activeElement.clientID !== null) { - const [state] = self.controller.objects - .filter((_state: any): boolean => ( - _state.clientID === self.activeElement.clientID - )); + const [state] = self.controller.objects.filter( + (_state: any): boolean => _state.clientID === self.activeElement.clientID, + ); if (['polygon', 'polyline', 'points'].includes(state.shapeType)) { - if (e.ctrlKey) { + if (e.altKey) { const { points } = state; - self.onEditDone( - state, - points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)), - ); + self.onEditDone(state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2))); } else if (e.shiftKey) { - self.canvas.dispatchEvent(new CustomEvent('canvas.editstart', { - bubbles: false, - cancelable: true, - })); + self.canvas.dispatchEvent( + new CustomEvent('canvas.editstart', { + bubbles: false, + cancelable: true, + }), + ); self.mode = Mode.EDIT; self.deactivate(); @@ -627,41 +781,41 @@ export class CanvasViewImpl implements CanvasView, Listener { e.preventDefault(); if (self.activeElement.clientID !== null) { - const [state] = self.controller.objects - .filter((_state: any): boolean => ( - _state.clientID === self.activeElement.clientID - )); + const [state] = self.controller.objects.filter( + (_state: any): boolean => _state.clientID === self.activeElement.clientID, + ); if (state.shapeType === 'cuboid') { if (e.shiftKey) { - const points = translate(pointsToNumberArray((e.target as any) - .parentElement.parentElement.instance.attr('points'))); - self.onEditDone( - state, - points, + const points = self.translateFromCanvas( + pointsToNumberArray((e.target as any).parentElement.parentElement.instance.attr('points')), ); + self.onEditDone(state, points); } } } } function contextMenuHandler(e: MouseEvent): void { - const pointID = Array.prototype.indexOf - .call(((e.target as HTMLElement).parentElement as HTMLElement).children, e.target); + const pointID = Array.prototype.indexOf.call( + ((e.target as HTMLElement).parentElement as HTMLElement).children, + e.target, + ); if (self.activeElement.clientID !== null) { - const [state] = self.controller.objects - .filter((_state: any): boolean => ( - _state.clientID === self.activeElement.clientID - )); - self.canvas.dispatchEvent(new CustomEvent('canvas.contextmenu', { - bubbles: false, - cancelable: true, - detail: { - mouseEvent: e, - objectState: state, - pointID, - }, - })); + const [state] = self.controller.objects.filter( + (_state: any): boolean => _state.clientID === self.activeElement.clientID, + ); + self.canvas.dispatchEvent( + new CustomEvent('canvas.contextmenu', { + bubbles: false, + cancelable: true, + detail: { + mouseEvent: e, + objectState: state, + pointID, + }, + }), + ); } e.preventDefault(); } @@ -669,7 +823,7 @@ export class CanvasViewImpl implements CanvasView, Listener { if (value) { (shape as any).selectize(value, { deepSelect: true, - pointSize: 2 * consts.BASE_POINT_SIZE / self.geometry.scale, + pointSize: (2 * consts.BASE_POINT_SIZE) / self.geometry.scale, rotationPoint: false, pointType(cx: number, cy: number): SVG.Circle { const circle: SVG.Circle = this.nested @@ -725,6 +879,7 @@ export class CanvasViewImpl implements CanvasView, Listener { this.svgShapes = {}; this.svgTexts = {}; this.drawnStates = {}; + this.drawnIssueRegions = {}; this.activeElement = { clientID: null, attributeID: null, @@ -736,10 +891,9 @@ export class CanvasViewImpl implements CanvasView, Listener { }; // Create HTML elements - this.loadingAnimation = window.document - .createElementNS('http://www.w3.org/2000/svg', 'svg'); + this.loadingAnimation = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg'); this.text = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - this.adoptedText = (SVG.adopt((this.text as any as HTMLElement)) as SVG.Container); + this.adoptedText = SVG.adopt((this.text as any) as HTMLElement) as SVG.Container; this.background = window.document.createElement('canvas'); this.bitmap = window.document.createElement('canvas'); // window.document.createElementNS('http://www.w3.org/2000/svg', 'svg'); @@ -749,16 +903,37 @@ export class CanvasViewImpl implements CanvasView, Listener { this.gridPattern = window.document.createElementNS('http://www.w3.org/2000/svg', 'pattern'); this.content = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - this.adoptedContent = (SVG.adopt((this.content as any as HTMLElement)) as SVG.Container); + this.adoptedContent = SVG.adopt((this.content as any) as HTMLElement) as SVG.Container; + + this.attachmentBoard = window.document.createElement('div'); this.canvas = window.document.createElement('div'); - const loadingCircle: SVGCircleElement = window.document - .createElementNS('http://www.w3.org/2000/svg', 'circle'); - const gridDefs: SVGDefsElement = window.document - .createElementNS('http://www.w3.org/2000/svg', 'defs'); - const gridRect: SVGRectElement = window.document - .createElementNS('http://www.w3.org/2000/svg', 'rect'); + const loadingCircle: SVGCircleElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'circle'); + const gridDefs: SVGDefsElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'defs'); + const gridRect: SVGRectElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + + // Setup defs + const contentDefs = this.adoptedContent.defs(); + this.issueRegionPattern_1 = contentDefs + .pattern(consts.BASE_PATTERN_SIZE, consts.BASE_PATTERN_SIZE, (add): void => { + add.line(0, 0, 0, 10).stroke('red'); + }) + .attr({ + id: 'cvat_issue_region_pattern_1', + patternTransform: 'rotate(45)', + patternUnits: 'userSpaceOnUse', + }); + + this.issueRegionPattern_2 = contentDefs + .pattern(consts.BASE_PATTERN_SIZE, consts.BASE_PATTERN_SIZE, (add): void => { + add.line(0, 0, 0, 10).stroke('yellow'); + }) + .attr({ + id: 'cvat_issue_region_pattern_2', + patternTransform: 'rotate(45)', + patternUnits: 'userSpaceOnUse', + }); // Setup loading animation this.loadingAnimation.setAttribute('id', 'cvat_canvas_loading_animation'); @@ -789,6 +964,9 @@ export class CanvasViewImpl implements CanvasView, Listener { this.bitmap.setAttribute('id', 'cvat_canvas_bitmap'); this.bitmap.style.display = 'none'; + // Setup sticked div + this.attachmentBoard.setAttribute('id', 'cvat_canvas_attachment_board'); + // Setup wrappers this.canvas.setAttribute('id', 'cvat_canvas_wrapper'); @@ -806,25 +984,19 @@ export class CanvasViewImpl implements CanvasView, Listener { this.canvas.appendChild(this.bitmap); this.canvas.appendChild(this.grid); this.canvas.appendChild(this.content); - + this.canvas.appendChild(this.attachmentBoard); const self = this; // Setup API handlers - this.autoborderHandler = new AutoborderHandlerImpl( - this.content, - ); + this.autoborderHandler = new AutoborderHandlerImpl(this.content); this.drawHandler = new DrawHandlerImpl( this.onDrawDone.bind(this), this.adoptedContent, this.adoptedText, this.autoborderHandler, ); - this.editHandler = new EditHandlerImpl( - this.onEditDone.bind(this), - this.adoptedContent, - this.autoborderHandler, - ); + this.editHandler = new EditHandlerImpl(this.onEditDone.bind(this), this.adoptedContent, this.autoborderHandler); this.mergeHandler = new MergeHandlerImpl( this.onMergeDone.bind(this), this.onFindObject.bind(this), @@ -841,23 +1013,30 @@ export class CanvasViewImpl implements CanvasView, Listener { this.onFindObject.bind(this), this.adoptedContent, ); - this.zoomHandler = new ZoomHandlerImpl( - this.onFocusRegion.bind(this), + this.regionSelector = new RegionSelectorImpl( + this.onRegionSelected.bind(this), + this.adoptedContent, + this.geometry, + ); + this.zoomHandler = new ZoomHandlerImpl(this.onFocusRegion.bind(this), this.adoptedContent, this.geometry); + this.interactionHandler = new InteractionHandlerImpl( + this.onInteraction.bind(this), this.adoptedContent, this.geometry, ); // Setup event handlers this.content.addEventListener('dblclick', (e: MouseEvent): void => { - if (e.ctrlKey || e.shiftKey) return; self.controller.fit(); e.preventDefault(); }); this.content.addEventListener('mousedown', (event): void => { if ([0, 1].includes(event.button)) { - if ([Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT].includes(this.mode) - || event.button === 1 || event.altKey + if ( + [Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT].includes(this.mode) + || event.button === 1 + || event.altKey ) { self.controller.enableDrag(event.clientX, event.clientY); } @@ -874,10 +1053,12 @@ export class CanvasViewImpl implements CanvasView, Listener { const { offset } = this.controller.geometry; const point = translateToSVG(this.content, [event.clientX, event.clientY]); self.controller.zoom(point[0] - offset, point[1] - offset, event.deltaY > 0 ? -1 : 1); - this.canvas.dispatchEvent(new CustomEvent('canvas.zoom', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.zoom', { + bubbles: false, + cancelable: true, + }), + ); event.preventDefault(); }); @@ -885,7 +1066,7 @@ export class CanvasViewImpl implements CanvasView, Listener { self.controller.drag(e.clientX, e.clientY); if (this.mode !== Mode.IDLE) return; - if (e.ctrlKey || e.shiftKey) return; + if (e.ctrlKey || e.altKey) return; const { offset } = this.controller.geometry; const [x, y] = translateToSVG(this.content, [e.clientX, e.clientY]); @@ -916,14 +1097,10 @@ export class CanvasViewImpl implements CanvasView, Listener { for (const i in this.drawnStates) { if (!(i in this.svgTexts)) { this.svgTexts[i] = this.addText(this.drawnStates[i]); - this.updateTextPosition( - this.svgTexts[i], - this.svgShapes[i], - ); + this.updateTextPosition(this.svgTexts[i], this.svgShapes[i]); } } - } else if (model.configuration.displayAllText === false - && this.configuration.displayAllText) { + } else if (model.configuration.displayAllText === false && this.configuration.displayAllText) { for (const i in this.drawnStates) { if (i in this.svgTexts && Number.parseInt(i, 10) !== activeElement.clientID) { this.svgTexts[i].remove(); @@ -960,8 +1137,10 @@ export class CanvasViewImpl implements CanvasView, Listener { if (ctx) { if (image.imageData instanceof ImageData) { - ctx.scale(image.renderWidth / image.imageData.width, - image.renderHeight / image.imageData.height); + ctx.scale( + image.renderWidth / image.imageData.width, + image.renderHeight / image.imageData.height, + ); ctx.putImageData(image.imageData, 0, 0); // Transformation matrix must not affect the putImageData() method. // By this reason need to redraw the image to apply scale. @@ -984,10 +1163,12 @@ export class CanvasViewImpl implements CanvasView, Listener { this.moveCanvas(); this.transformCanvas(); if (reason === UpdateReasons.IMAGE_FITTED) { - this.canvas.dispatchEvent(new CustomEvent('canvas.fit', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.fit', { + bubbles: false, + cancelable: true, + }), + ); } } else if (reason === UpdateReasons.IMAGE_MOVED) { this.moveCanvas(); @@ -1001,50 +1182,68 @@ export class CanvasViewImpl implements CanvasView, Listener { } const event: CustomEvent = new CustomEvent('canvas.setup'); this.canvas.dispatchEvent(event); + } else if (reason === UpdateReasons.ISSUE_REGIONS_UPDATED) { + this.setupIssueRegions(this.controller.issueRegions); } else if (reason === UpdateReasons.GRID_UPDATED) { const size: Size = this.geometry.grid; this.gridPattern.setAttribute('width', `${size.width}`); this.gridPattern.setAttribute('height', `${size.height}`); } else if (reason === UpdateReasons.SHAPE_FOCUSED) { - const { - padding, - clientID, - } = this.controller.focusData; + const { padding, clientID } = this.controller.focusData; const object = this.svgShapes[clientID]; if (object) { const bbox: SVG.BBox = object.bbox(); - this.onFocusRegion(bbox.x - padding, bbox.y - padding, - bbox.width + padding * 2, bbox.height + padding * 2); + this.onFocusRegion( + bbox.x - padding, + bbox.y - padding, + bbox.width + padding * 2, + bbox.height + padding * 2, + ); } } else if (reason === UpdateReasons.SHAPE_ACTIVATED) { this.activate(this.controller.activeElement); + } else if (reason === UpdateReasons.SELECT_REGION) { + if (this.mode === Mode.SELECT_REGION) { + this.regionSelector.select(true); + this.canvas.style.cursor = 'pointer'; + } else { + this.regionSelector.select(false); + } } else if (reason === UpdateReasons.DRAG_CANVAS) { if (this.mode === Mode.DRAG_CANVAS) { - this.canvas.dispatchEvent(new CustomEvent('canvas.dragstart', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.dragstart', { + bubbles: false, + cancelable: true, + }), + ); this.canvas.style.cursor = 'move'; } else { - this.canvas.dispatchEvent(new CustomEvent('canvas.dragstop', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.dragstop', { + bubbles: false, + cancelable: true, + }), + ); this.canvas.style.cursor = ''; } } else if (reason === UpdateReasons.ZOOM_CANVAS) { if (this.mode === Mode.ZOOM_CANVAS) { - this.canvas.dispatchEvent(new CustomEvent('canvas.zoomstart', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.zoomstart', { + bubbles: false, + cancelable: true, + }), + ); this.canvas.style.cursor = 'zoom-in'; this.zoomHandler.zoom(); } else { - this.canvas.dispatchEvent(new CustomEvent('canvas.zoomstop', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.zoomstop', { + bubbles: false, + cancelable: true, + }), + ); this.canvas.style.cursor = ''; this.zoomHandler.cancel(); } @@ -1053,7 +1252,7 @@ export class CanvasViewImpl implements CanvasView, Listener { if (data.enabled && this.mode === Mode.IDLE) { this.canvas.style.cursor = 'crosshair'; this.mode = Mode.DRAW; - if (typeof (data.redraw) === 'number') { + if (typeof data.redraw === 'number') { this.setupServiceHidden(data.redraw, true); } this.drawHandler.draw(data, this.geometry); @@ -1063,6 +1262,18 @@ export class CanvasViewImpl implements CanvasView, Listener { this.drawHandler.draw(data, this.geometry); } } + } else if (reason === UpdateReasons.INTERACT) { + const data: InteractionData = this.controller.interactionData; + if (data.enabled && this.mode === Mode.IDLE) { + this.canvas.style.cursor = 'crosshair'; + this.mode = Mode.INTERACT; + this.interactionHandler.interact(data); + } else { + this.canvas.style.cursor = ''; + if (this.mode !== Mode.IDLE) { + this.interactionHandler.interact(data); + } + } } else if (reason === UpdateReasons.MERGE) { const data: MergeData = this.controller.mergeData; if (data.enabled) { @@ -1101,35 +1312,46 @@ export class CanvasViewImpl implements CanvasView, Listener { } else if (reason === UpdateReasons.CANCEL) { if (this.mode === Mode.DRAW) { this.drawHandler.cancel(); + } else if (this.mode === Mode.INTERACT) { + this.interactionHandler.cancel(); } else if (this.mode === Mode.MERGE) { this.mergeHandler.cancel(); } else if (this.mode === Mode.SPLIT) { this.splitHandler.cancel(); } else if (this.mode === Mode.GROUP) { this.groupHandler.cancel(); + } else if (this.mode === Mode.SELECT_REGION) { + this.regionSelector.cancel(); } else if (this.mode === Mode.EDIT) { this.editHandler.cancel(); } else if (this.mode === Mode.DRAG_CANVAS) { - this.canvas.dispatchEvent(new CustomEvent('canvas.dragstop', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.dragstop', { + bubbles: false, + cancelable: true, + }), + ); } else if (this.mode === Mode.ZOOM_CANVAS) { this.zoomHandler.cancel(); - this.canvas.dispatchEvent(new CustomEvent('canvas.zoomstop', { - bubbles: false, - cancelable: true, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.zoomstop', { + bubbles: false, + cancelable: true, + }), + ); } this.mode = Mode.IDLE; this.canvas.style.cursor = ''; + } else if (reason === UpdateReasons.DATA_FAILED) { + const event: CustomEvent = new CustomEvent('canvas.error', { + detail: { + exception: model.exception, + }, + }); + this.canvas.dispatchEvent(event); } - if (model.imageBitmap - && [UpdateReasons.IMAGE_CHANGED, - UpdateReasons.OBJECTS_UPDATED, - ].includes(reason) - ) { + if (model.imageBitmap && [UpdateReasons.IMAGE_CHANGED, UpdateReasons.OBJECTS_UPDATED].includes(reason)) { this.redrawBitmap(); } } @@ -1231,39 +1453,36 @@ export class CanvasViewImpl implements CanvasView, Listener { }; } - private updateObjects(states: any[], translate: (points: number[]) => number[]): void { + private updateObjects(states: any[]): void { for (const state of states) { const { clientID } = state; const drawnState = this.drawnStates[clientID]; const shape = this.svgShapes[state.clientID]; const text = this.svgTexts[state.clientID]; - const isInvisible = state.hidden || state.outside - || this.isServiceHidden(state.clientID); + const isInvisible = state.hidden || state.outside || this.isServiceHidden(state.clientID); if (drawnState.hidden !== state.hidden || drawnState.outside !== state.outside) { if (isInvisible) { - (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape) - .addClass('cvat_canvas_hidden'); + (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape).addClass( + 'cvat_canvas_hidden', + ); if (text) { text.addClass('cvat_canvas_hidden'); } } else { - (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape) - .removeClass('cvat_canvas_hidden'); + (state.shapeType === 'points' ? shape.remember('_selectHandler').nested : shape).removeClass( + 'cvat_canvas_hidden', + ); if (text) { text.removeClass('cvat_canvas_hidden'); - this.updateTextPosition( - text, - shape, - ); + this.updateTextPosition(text, shape); } } } if (drawnState.zOrder !== state.zOrder) { if (state.shapeType === 'points') { - shape.remember('_selectHandler').nested - .attr('data-z-order', state.zOrder); + shape.remember('_selectHandler').nested.attr('data-z-order', state.zOrder); } else { shape.attr('data-z-order', state.zOrder); } @@ -1283,10 +1502,11 @@ export class CanvasViewImpl implements CanvasView, Listener { this.activate(activeElement); } - if (state.points.length !== drawnState.points.length || state.points - .some((p: number, id: number): boolean => p !== drawnState.points[id]) + if ( + state.points.length !== drawnState.points.length + || state.points.some((p: number, id: number): boolean => p !== drawnState.points[id]) ) { - const translatedPoints: number[] = translate(state.points); + const translatedPoints: number[] = this.translateToCanvas(state.points); if (state.shapeType === 'rectangle') { const [xtl, ytl, xbr, ybr] = translatedPoints; @@ -1298,15 +1518,7 @@ export class CanvasViewImpl implements CanvasView, Listener { height: ybr - ytl, }); } else { - const stringified = translatedPoints.reduce( - (acc: string, val: number, idx: number): string => { - if (idx % 2) { - return `${acc}${val} `; - } - - return `${acc}${val},`; - }, '', - ); + const stringified = this.stringifyToCanvas(translatedPoints); if (state.shapeType !== 'cuboid') { (shape as any).clear(); } @@ -1322,8 +1534,7 @@ export class CanvasViewImpl implements CanvasView, Listener { for (const attrID of Object.keys(state.attributes)) { if (state.attributes[attrID] !== drawnState.attributes[+attrID]) { if (text) { - const [span] = text.node - .querySelectorAll(`[attrID="${attrID}"]`) as any as SVGTSpanElement[]; + const [span] = (text.node.querySelectorAll(`[attrID="${attrID}"]`) as any) as SVGTSpanElement[]; if (span && span.textContent) { const prefix = span.textContent.split(':').slice(0, -1).join(':'); span.textContent = `${prefix}: ${state.attributes[attrID]}`; @@ -1336,61 +1547,47 @@ export class CanvasViewImpl implements CanvasView, Listener { } } - private addObjects(states: any[], translate: (points: number[]) => number[]): void { + private addObjects(states: any[]): void { const { displayAllText } = this.configuration; for (const state of states) { - const points: number[] = (state.points as number[]); - const translatedPoints: number[] = translate(points); + const points: number[] = state.points as number[]; + const translatedPoints: number[] = this.translateToCanvas(points); // TODO: Use enums after typification cvat-core if (state.shapeType === 'rectangle') { - this.svgShapes[state.clientID] = this - .addRect(translatedPoints, state); + this.svgShapes[state.clientID] = this.addRect(translatedPoints, state); } else { - const stringified = translatedPoints.reduce( - (acc: string, val: number, idx: number): string => { - if (idx % 2) { - return `${acc}${val} `; - } - - return `${acc}${val},`; - }, '', - ); + const stringified = this.stringifyToCanvas(translatedPoints); if (state.shapeType === 'polygon') { - this.svgShapes[state.clientID] = this - .addPolygon(stringified, state); + this.svgShapes[state.clientID] = this.addPolygon(stringified, state); } else if (state.shapeType === 'polyline') { - this.svgShapes[state.clientID] = this - .addPolyline(stringified, state); + this.svgShapes[state.clientID] = this.addPolyline(stringified, state); } else if (state.shapeType === 'points') { - this.svgShapes[state.clientID] = this - .addPoints(stringified, state); + this.svgShapes[state.clientID] = this.addPoints(stringified, state); } else if (state.shapeType === 'cuboid') { - this.svgShapes[state.clientID] = this - .addCuboid(stringified, state); + this.svgShapes[state.clientID] = this.addCuboid(stringified, state); } else { continue; } } this.svgShapes[state.clientID].on('click.canvas', (): void => { - this.canvas.dispatchEvent(new CustomEvent('canvas.clicked', { - bubbles: false, - cancelable: true, - detail: { - state, - }, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.clicked', { + bubbles: false, + cancelable: true, + detail: { + state, + }, + }), + ); }); if (displayAllText) { this.svgTexts[state.clientID] = this.addText(state); - this.updateTextPosition( - this.svgTexts[state.clientID], - this.svgShapes[state.clientID], - ); + this.updateTextPosition(this.svgTexts[state.clientID], this.svgShapes[state.clientID]); } this.saveState(state); @@ -1399,11 +1596,15 @@ export class CanvasViewImpl implements CanvasView, Listener { private sortObjects(): void { // TODO: Can be significantly optimized - const states = Array.from( - this.content.getElementsByClassName('cvat_canvas_shape'), - ).map((state: SVGElement): [SVGElement, number] => ( - [state, +state.getAttribute('data-z-order')] - )); + const states = Array.from(this.content.getElementsByClassName('cvat_canvas_shape')).map((state: SVGElement): [ + SVGElement, + number, + ] => [state, +state.getAttribute('data-z-order')]); + + const crosshair = Array.from(this.content.getElementsByClassName('cvat_canvas_crosshair')); + crosshair.forEach((line: SVGLineElement): void => this.content.append(line)); + const interaction = Array.from(this.content.getElementsByClassName('cvat_interaction_point')); + interaction.forEach((circle: SVGCircleElement): void => this.content.append(circle)); const needSort = states.some((pair): boolean => pair[1] !== states[0][1]); if (!states.length || !needSort) { @@ -1423,8 +1624,7 @@ export class CanvasViewImpl implements CanvasView, Listener { if (clientID !== null && attributeID !== null) { const text = this.svgTexts[clientID]; if (text) { - const [span] = text.node - .querySelectorAll(`[attrID="${attributeID}"]`) as any as SVGTSpanElement[]; + const [span] = (text.node.querySelectorAll(`[attrID="${attributeID}"]`) as any) as SVGTSpanElement[]; if (span) { span.style.fill = ''; } @@ -1490,8 +1690,7 @@ export class CanvasViewImpl implements CanvasView, Listener { private activateAttribute(clientID: number, attributeID: number): void { const text = this.svgTexts[clientID]; if (text) { - const [span] = text.node - .querySelectorAll(`[attrID="${attributeID}"]`) as any as SVGTSpanElement[]; + const [span] = (text.node.querySelectorAll(`[attrID="${attributeID}"]`) as any) as SVGTSpanElement[]; if (span) { span.style.fill = 'red'; } @@ -1504,12 +1703,12 @@ export class CanvasViewImpl implements CanvasView, Listener { } private activateShape(clientID: number): void { - const [state] = this.controller.objects - .filter((_state: any): boolean => _state.clientID === clientID); + const [state] = this.controller.objects.filter((_state: any): boolean => _state.clientID === clientID); if (state && state.shapeType === 'points') { - this.svgShapes[clientID].remember('_selectHandler').nested - .style('pointer-events', state.lock ? 'none' : ''); + this.svgShapes[clientID] + .remember('_selectHandler') + .nested.style('pointer-events', this.stateIsLocked(state) ? 'none' : ''); } if (!state || state.hidden || state.outside) { @@ -1517,15 +1716,20 @@ export class CanvasViewImpl implements CanvasView, Listener { } const shape = this.svgShapes[clientID]; + let text = this.svgTexts[clientID]; + if (!text) { + text = this.addText(state); + this.svgTexts[state.clientID] = text; + } + this.updateTextPosition(text, shape); - if (state.lock) { + if (this.stateIsLocked(state)) { return; } shape.addClass('cvat_canvas_shape_activated'); if (state.shapeType === 'points') { - this.content.append(this.svgShapes[clientID] - .remember('_selectHandler').nested.node); + this.content.append(this.svgShapes[clientID].remember('_selectHandler').nested.node); } else { this.content.append(shape.node); } @@ -1535,12 +1739,6 @@ export class CanvasViewImpl implements CanvasView, Listener { (shape as any).attr('projections', true); } - let text = this.svgTexts[clientID]; - if (!text) { - text = this.addText(state); - this.svgTexts[state.clientID] = text; - } - const hideText = (): void => { if (text) { text.addClass('cvat_canvas_hidden'); @@ -1556,34 +1754,42 @@ export class CanvasViewImpl implements CanvasView, Listener { if (!state.pinned) { shape.addClass('cvat_canvas_shape_draggable'); - (shape as any).draggable().on('dragstart', (): void => { - this.mode = Mode.DRAG; - hideText(); - }).on('dragend', (e: CustomEvent): void => { - showText(); - this.mode = Mode.IDLE; - const p1 = e.detail.handler.startPoints.point; - const p2 = e.detail.p; - const delta = 1; - const { offset } = this.controller.geometry; - if (Math.sqrt(((p1.x - p2.x) ** 2) + ((p1.y - p2.y) ** 2)) >= delta) { - const points = pointsToNumberArray( - shape.attr('points') || `${shape.attr('x')},${shape.attr('y')} ` - + `${shape.attr('x') + shape.attr('width')},` - + `${shape.attr('y') + shape.attr('height')}`, - ).map((x: number): number => x - offset); - - this.drawnStates[state.clientID].points = points; - this.canvas.dispatchEvent(new CustomEvent('canvas.dragshape', { - bubbles: false, - cancelable: true, - detail: { - id: state.clientID, - }, - })); - this.onEditDone(state, points); - } - }); + (shape as any) + .draggable() + .on('dragstart', (): void => { + this.mode = Mode.DRAG; + hideText(); + }) + .on('dragend', (e: CustomEvent): void => { + showText(); + this.mode = Mode.IDLE; + const p1 = e.detail.handler.startPoints.point; + const p2 = e.detail.p; + const delta = 1; + const { offset } = this.controller.geometry; + const dx2 = (p1.x - p2.x) ** 2; + const dy2 = (p1.y - p2.y) ** 2; + if (Math.sqrt(dx2 + dy2) >= delta) { + const points = pointsToNumberArray( + shape.attr('points') + || `${shape.attr('x')},${shape.attr('y')} ` + + `${shape.attr('x') + shape.attr('width')},` + + `${shape.attr('y') + shape.attr('height')}`, + ).map((x: number): number => x - offset); + + this.drawnStates[state.clientID].points = points; + this.canvas.dispatchEvent( + new CustomEvent('canvas.dragshape', { + bubbles: false, + cancelable: true, + detail: { + id: state.clientID, + }, + }), + ); + this.onEditDone(state, points); + } + }); } if (state.shapeType !== 'points') { @@ -1606,60 +1812,68 @@ export class CanvasViewImpl implements CanvasView, Listener { let shapeSizeElement: ShapeSizeElement | null = null; let resized = false; - (shape as any).resize({ - snapToGrid: 0.1, - }).on('resizestart', (): void => { - this.mode = Mode.RESIZE; - resized = false; - hideDirection(); - hideText(); - if (state.shapeType === 'rectangle') { - shapeSizeElement = displayShapeSize(this.adoptedContent, this.adoptedText); - } - }).on('resizing', (): void => { - resized = true; - if (shapeSizeElement) { - shapeSizeElement.update(shape); - } - }).on('resizedone', (): void => { - if (shapeSizeElement) { - shapeSizeElement.rm(); - } + (shape as any) + .resize({ + snapToGrid: 0.1, + }) + .on('resizestart', (): void => { + this.mode = Mode.RESIZE; + resized = false; + hideDirection(); + hideText(); + if (state.shapeType === 'rectangle') { + shapeSizeElement = displayShapeSize(this.adoptedContent, this.adoptedText); + } + }) + .on('resizing', (): void => { + resized = true; + if (shapeSizeElement) { + shapeSizeElement.update(shape); + } + }) + .on('resizedone', (): void => { + if (shapeSizeElement) { + shapeSizeElement.rm(); + } - showDirection(); - showText(); + showDirection(); + showText(); - this.mode = Mode.IDLE; + this.mode = Mode.IDLE; - if (resized) { - const { offset } = this.controller.geometry; + if (resized) { + const { offset } = this.controller.geometry; - const points = pointsToNumberArray( - shape.attr('points') || `${shape.attr('x')},${shape.attr('y')} ` - + `${shape.attr('x') + shape.attr('width')},` - + `${shape.attr('y') + shape.attr('height')}`, - ).map((x: number): number => x - offset); + const points = pointsToNumberArray( + shape.attr('points') + || `${shape.attr('x')},${shape.attr('y')} ` + + `${shape.attr('x') + shape.attr('width')},` + + `${shape.attr('y') + shape.attr('height')}`, + ).map((x: number): number => x - offset); - this.drawnStates[state.clientID].points = points; - this.canvas.dispatchEvent(new CustomEvent('canvas.resizeshape', { - bubbles: false, - cancelable: true, - detail: { - id: state.clientID, - }, - })); - this.onEditDone(state, points); - } - }); + this.drawnStates[state.clientID].points = points; + this.canvas.dispatchEvent( + new CustomEvent('canvas.resizeshape', { + bubbles: false, + cancelable: true, + detail: { + id: state.clientID, + }, + }), + ); + this.onEditDone(state, points); + } + }); - this.updateTextPosition(text, shape); - this.canvas.dispatchEvent(new CustomEvent('canvas.activated', { - bubbles: false, - cancelable: true, - detail: { - state, - }, - })); + this.canvas.dispatchEvent( + new CustomEvent('canvas.activated', { + bubbles: false, + cancelable: true, + detail: { + state, + }, + }), + ); } private activate(activeElement: ActiveElement): void { @@ -1682,10 +1896,7 @@ export class CanvasViewImpl implements CanvasView, Listener { }; } - if (clientID !== null - && attributeID !== null - && this.activeElement.attributeID !== attributeID - ) { + if (clientID !== null && attributeID !== null && this.activeElement.attributeID !== attributeID) { this.activateAttribute(clientID, attributeID); } } @@ -1712,9 +1923,11 @@ export class CanvasViewImpl implements CanvasView, Listener { // Find the best place for a text let [clientX, clientY]: number[] = [box.x + box.width, box.y]; - if (clientX + (text.node as any as SVGTextElement) - .getBBox().width + consts.TEXT_MARGIN > this.canvas.offsetWidth) { - ([clientX, clientY] = [box.x, box.y]); + if ( + clientX + ((text.node as any) as SVGTextElement).getBBox().width + consts.TEXT_MARGIN + > this.canvas.offsetWidth + ) { + [clientX, clientY] = [box.x, box.y]; } // Translate back to text SVG @@ -1733,42 +1946,45 @@ export class CanvasViewImpl implements CanvasView, Listener { private addText(state: any): SVG.Text { const { undefinedAttrValue } = this.configuration; const { - label, - clientID, - attributes, - source, + label, clientID, attributes, source, } = state; const attrNames = label.attributes.reduce((acc: any, val: any): void => { acc[val.id] = val.name; return acc; }, {}); - return this.adoptedText.text((block): void => { - block.tspan(`${label.name} ${clientID} (${source})`).style('text-transform', 'uppercase'); - for (const attrID of Object.keys(attributes)) { - const value = attributes[attrID] === undefinedAttrValue - ? '' : attributes[attrID]; - block.tspan(`${attrNames[attrID]}: ${value}`).attr({ - attrID, - dy: '1em', - x: 0, - }); - } - }).move(0, 0).addClass('cvat_canvas_text'); + return this.adoptedText + .text((block): void => { + block.tspan(`${label.name} ${clientID} (${source})`).style('text-transform', 'uppercase'); + for (const attrID of Object.keys(attributes)) { + const value = attributes[attrID] === undefinedAttrValue ? '' : attributes[attrID]; + block.tspan(`${attrNames[attrID]}: ${value}`).attr({ + attrID, + dy: '1em', + x: 0, + }); + } + }) + .move(0, 0) + .addClass('cvat_canvas_text'); } private addRect(points: number[], state: any): SVG.Rect { const [xtl, ytl, xbr, ybr] = points; - const rect = this.adoptedContent.rect().size(xbr - xtl, ybr - ytl).attr({ - clientID: state.clientID, - 'color-rendering': 'optimizeQuality', - id: `cvat_canvas_shape_${state.clientID}`, - fill: state.color, - 'shape-rendering': 'geometricprecision', - stroke: state.color, - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - 'data-z-order': state.zOrder, - }).move(xtl, ytl) + const rect = this.adoptedContent + .rect() + .size(xbr - xtl, ybr - ytl) + .attr({ + clientID: state.clientID, + 'color-rendering': 'optimizeQuality', + id: `cvat_canvas_shape_${state.clientID}`, + fill: state.color, + 'shape-rendering': 'geometricprecision', + stroke: state.color, + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + 'data-z-order': state.zOrder, + }) + .move(xtl, ytl) .addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1783,16 +1999,19 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolygon(points: string, state: any): SVG.Polygon { - const polygon = this.adoptedContent.polygon(points).attr({ - clientID: state.clientID, - 'color-rendering': 'optimizeQuality', - id: `cvat_canvas_shape_${state.clientID}`, - fill: state.color, - 'shape-rendering': 'geometricprecision', - stroke: state.color, - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - 'data-z-order': state.zOrder, - }).addClass('cvat_canvas_shape'); + const polygon = this.adoptedContent + .polygon(points) + .attr({ + clientID: state.clientID, + 'color-rendering': 'optimizeQuality', + id: `cvat_canvas_shape_${state.clientID}`, + fill: state.color, + 'shape-rendering': 'geometricprecision', + stroke: state.color, + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + 'data-z-order': state.zOrder, + }) + .addClass('cvat_canvas_shape'); if (state.occluded) { polygon.addClass('cvat_canvas_shape_occluded'); @@ -1806,16 +2025,19 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolyline(points: string, state: any): SVG.PolyLine { - const polyline = this.adoptedContent.polyline(points).attr({ - clientID: state.clientID, - 'color-rendering': 'optimizeQuality', - id: `cvat_canvas_shape_${state.clientID}`, - fill: state.color, - 'shape-rendering': 'geometricprecision', - stroke: state.color, - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - 'data-z-order': state.zOrder, - }).addClass('cvat_canvas_shape'); + const polyline = this.adoptedContent + .polyline(points) + .attr({ + clientID: state.clientID, + 'color-rendering': 'optimizeQuality', + id: `cvat_canvas_shape_${state.clientID}`, + fill: state.color, + 'shape-rendering': 'geometricprecision', + stroke: state.color, + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + 'data-z-order': state.zOrder, + }) + .addClass('cvat_canvas_shape'); if (state.occluded) { polyline.addClass('cvat_canvas_shape_occluded'); @@ -1829,8 +2051,10 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addCuboid(points: string, state: any): any { - const cube = (this.adoptedContent as any).cube(points) - .fill(state.color).attr({ + const cube = (this.adoptedContent as any) + .cube(points) + .fill(state.color) + .attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', id: `cvat_canvas_shape_${state.clientID}`, @@ -1839,7 +2063,8 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - }).addClass('cvat_canvas_shape'); + }) + .addClass('cvat_canvas_shape'); if (state.occluded) { cube.addClass('cvat_canvas_shape_occluded'); @@ -1855,8 +2080,10 @@ export class CanvasViewImpl implements CanvasView, Listener { private setupPoints(basicPolyline: SVG.PolyLine, state: any): any { this.selectize(true, basicPolyline); - const group: SVG.G = basicPolyline.remember('_selectHandler').nested - .addClass('cvat_canvas_shape').attr({ + const group: SVG.G = basicPolyline + .remember('_selectHandler') + .nested.addClass('cvat_canvas_shape') + .attr({ clientID: state.clientID, id: `cvat_canvas_shape_${state.clientID}`, 'data-polyline-id': basicPolyline.attr('id'), @@ -1877,15 +2104,18 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPoints(points: string, state: any): SVG.PolyLine { - const shape = this.adoptedContent.polyline(points).attr({ - 'color-rendering': 'optimizeQuality', - 'pointer-events': 'none', - 'shape-rendering': 'geometricprecision', - 'stroke-width': 0, - fill: state.color, // to right fill property when call SVG.Shape::clone() - }).style({ - opacity: 0, - }); + const shape = this.adoptedContent + .polyline(points) + .attr({ + 'color-rendering': 'optimizeQuality', + 'pointer-events': 'none', + 'shape-rendering': 'geometricprecision', + 'stroke-width': 0, + fill: state.color, // to right fill property when call SVG.Shape::clone() + }) + .style({ + opacity: 0, + }); const group = this.setupPoints(shape, state); diff --git a/cvat-canvas/src/typescript/consts.ts b/cvat-canvas/src/typescript/consts.ts index b9110b39..7dea5032 100644 --- a/cvat-canvas/src/typescript/consts.ts +++ b/cvat-canvas/src/typescript/consts.ts @@ -2,13 +2,13 @@ // // SPDX-License-Identifier: MIT -const BASE_STROKE_WIDTH = 1.75; +const BASE_STROKE_WIDTH = 1.25; const BASE_GRID_WIDTH = 2; const BASE_POINT_SIZE = 5; const TEXT_MARGIN = 10; const AREA_THRESHOLD = 9; const SIZE_THRESHOLD = 3; -const POINTS_STROKE_WIDTH = 1.5; +const POINTS_STROKE_WIDTH = 1; const POINTS_SELECTED_STROKE_WIDTH = 4; const MIN_EDGE_LENGTH = 3; const CUBOID_ACTIVE_EDGE_STROKE_WIDTH = 2.5; @@ -16,6 +16,7 @@ const CUBOID_UNACTIVE_EDGE_STROKE_WIDTH = 1.75; const UNDEFINED_ATTRIBUTE_VALUE = '__undefined__'; const ARROW_PATH = 'M13.162 6.284L.682.524a.483.483 0 0 0-.574.134.477.477 0 ' + '0 0-.012.59L4.2 6.72.096 12.192a.479.479 0 0 0 .585.724l12.48-5.76a.48.48 0 0 0 0-.872z'; +const BASE_PATTERN_SIZE = 5; export default { BASE_STROKE_WIDTH, @@ -31,4 +32,5 @@ export default { CUBOID_UNACTIVE_EDGE_STROKE_WIDTH, UNDEFINED_ATTRIBUTE_VALUE, ARROW_PATH, + BASE_PATTERN_SIZE, }; diff --git a/cvat-canvas/src/typescript/crosshair.ts b/cvat-canvas/src/typescript/crosshair.ts new file mode 100644 index 00000000..24175c59 --- /dev/null +++ b/cvat-canvas/src/typescript/crosshair.ts @@ -0,0 +1,76 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import * as SVG from 'svg.js'; +import consts from './consts'; + +export default class Crosshair { + private x: SVG.Line | null; + private y: SVG.Line | null; + private canvas: SVG.Container | null; + + public constructor() { + this.x = null; + this.y = null; + this.canvas = null; + } + + public show(canvas: SVG.Container, x: number, y: number, scale: number): void { + if (this.canvas && this.canvas !== canvas) { + if (this.x) this.x.remove(); + if (this.y) this.y.remove(); + this.x = null; + this.y = null; + } + + this.canvas = canvas; + this.x = this.canvas + .line(0, y, this.canvas.node.clientWidth, y) + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * scale), + }) + .addClass('cvat_canvas_crosshair'); + + this.y = this.canvas + .line(x, 0, x, this.canvas.node.clientHeight) + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * scale), + }) + .addClass('cvat_canvas_crosshair'); + } + + public hide(): void { + if (this.x) { + this.x.remove(); + this.x = null; + } + + if (this.y) { + this.y.remove(); + this.y = null; + } + + this.canvas = null; + } + + public move(x: number, y: number): void { + if (this.x) { + this.x.attr({ y1: y, y2: y }); + } + + if (this.y) { + this.y.attr({ x1: x, x2: x }); + } + } + + public scale(scale: number): void { + if (this.x) { + this.x.attr('stroke-width', consts.BASE_STROKE_WIDTH / (2 * scale)); + } + + if (this.y) { + this.y.attr('stroke-width', consts.BASE_STROKE_WIDTH / (2 * scale)); + } + } +} diff --git a/cvat-canvas/src/typescript/cuboid.ts b/cvat-canvas/src/typescript/cuboid.ts index 7bf04777..920bc39e 100644 --- a/cvat-canvas/src/typescript/cuboid.ts +++ b/cvat-canvas/src/typescript/cuboid.ts @@ -1,12 +1,3 @@ -/* eslint-disable func-names */ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable curly */ -/* - * Copyright (C) 2020 Intel Corporation - * - * SPDX-License-Identifier: MIT - */ - import consts from './consts'; export interface Point { @@ -26,9 +17,7 @@ function line(p1: Point, p2: Point): number[] { return [a, b, c]; } -function intersection( - p1: Point, p2: Point, p3: Point, p4: Point, -): Point | null { +function intersection(p1: Point, p2: Point, p3: Point, p4: Point): Point | null { const L1 = line(p1, p2); const L2 = line(p3, p4); @@ -246,8 +235,20 @@ export class CuboidModel { this.rb = new Edge([3, 5], this.points); this.db = new Edge([7, 5], this.points); - this.edgeList = [this.fl, this.fr, this.dl, this.dr, this.ft, this.lt, - this.rt, this.dt, this.fb, this.lb, this.rb, this.db]; + this.edgeList = [ + this.fl, + this.fr, + this.dl, + this.dr, + this.ft, + this.lt, + this.rt, + this.dt, + this.fb, + this.lb, + this.rb, + this.db, + ]; } private initFaces(): void { @@ -324,7 +325,7 @@ function sortPointsClockwise(points: any[]): any[] { let ang = Math.atan2(point.y - center.y, point.x - center.x); if (!startAng) { startAng = ang; - // ensure that all points are clockwise of the start point + // ensure that all points are clockwise of the start point } else if (ang < startAng) { ang += Math.PI * 2; } @@ -347,18 +348,18 @@ function setupCuboidPoints(points: Point[]): any[] { let p3; let p4; - const height = Math.abs(points[0].x - points[1].x) - < Math.abs(points[1].x - points[2].x) - ? Math.abs(points[1].y - points[0].y) - : Math.abs(points[1].y - points[2].y); + const height = + Math.abs(points[0].x - points[1].x) < Math.abs(points[1].x - points[2].x) + ? Math.abs(points[1].y - points[0].y) + : Math.abs(points[1].y - points[2].y); // seperate into left and right point // we pick the first and third point because we know assume they will be on // opposite corners if (points[0].x < points[2].x) { - [left,, right] = points; + [left, , right] = points; } else { - [right,, left] = points; + [right, , left] = points; } // get other 2 points using the given height @@ -408,7 +409,7 @@ export function cuboidFrom4Points(flattenedPoints: any[]): any[] { points.push({ x, y }); } const unsortedPlanePoints = points.slice(0, 3); - function rotate(array: any[], times: number): void{ + function rotate(array: any[], times: number): void { let t = times; while (t--) { const temp = array.shift(); @@ -460,28 +461,21 @@ export function cuboidFrom4Points(flattenedPoints: any[]): any[] { plane2.p3 = { x: plane1.p3.x + vec.x, y: plane1.p3.y + vec.y }; plane2.p4 = { x: plane1.p4.x + vec.x, y: plane1.p4.y + vec.y }; - let cuboidPoints; // right if (Math.abs(angle) < Math.PI / 2 - 0.1) { cuboidPoints = setupCuboidPoints(points); - // left + // left } else if (Math.abs(angle) > Math.PI / 2 + 0.1) { cuboidPoints = setupCuboidPoints(points); - // down + // down } else if (angle > 0) { - cuboidPoints = [ - plane1.p1, plane2.p1, plane1.p2, plane2.p2, - plane1.p3, plane2.p3, plane1.p4, plane2.p4, - ]; + cuboidPoints = [plane1.p1, plane2.p1, plane1.p2, plane2.p2, plane1.p3, plane2.p3, plane1.p4, plane2.p4]; cuboidPoints[0].y += 0.1; cuboidPoints[4].y += 0.1; - // up + // up } else { - cuboidPoints = [ - plane2.p1, plane1.p1, plane2.p2, plane1.p2, - plane2.p3, plane1.p3, plane2.p4, plane1.p4, - ]; + cuboidPoints = [plane2.p1, plane1.p1, plane2.p2, plane1.p2, plane2.p3, plane1.p3, plane2.p4, plane1.p4]; cuboidPoints[0].y += 0.1; cuboidPoints[4].y += 0.1; } diff --git a/cvat-canvas/src/typescript/drawHandler.ts b/cvat-canvas/src/typescript/drawHandler.ts index 404157bd..c0ff78ca 100644 --- a/cvat-canvas/src/typescript/drawHandler.ts +++ b/cvat-canvas/src/typescript/drawHandler.ts @@ -16,14 +16,9 @@ import { BBox, Box, } from './shared'; +import Crosshair from './crosshair'; import consts from './consts'; -import { - DrawData, - Geometry, - RectDrawingMethod, - Configuration, - CuboidDrawingMethod, -} from './canvasModel'; +import { DrawData, Geometry, RectDrawingMethod, Configuration, CuboidDrawingMethod } from './canvasModel'; import { cuboidFrom4Points } from './cuboid'; @@ -44,10 +39,7 @@ export class DrawHandlerImpl implements DrawHandler { x: number; y: number; }; - private crosshair: { - x: SVG.Line; - y: SVG.Line; - }; + private crosshair: Crosshair; private drawData: DrawData; private geometry: Geometry; private autoborderHandler: AutoborderHandler; @@ -66,8 +58,9 @@ export class DrawHandlerImpl implements DrawHandler { const frameHeight = this.geometry.image.height; const { offset } = this.geometry; - let [xtl, ytl, xbr, ybr] = [bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height] - .map((coord: number): number => coord - offset); + let [xtl, ytl, xbr, ybr] = [bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height].map( + (coord: number): number => coord - offset, + ); xtl = Math.min(Math.max(xtl, 0), frameWidth); xbr = Math.min(Math.max(xbr, 0), frameWidth); @@ -77,7 +70,9 @@ export class DrawHandlerImpl implements DrawHandler { return [xtl, ytl, xbr, ybr]; } - private getFinalPolyshapeCoordinates(targetPoints: number[]): { + private getFinalPolyshapeCoordinates( + targetPoints: number[], + ): { points: number[]; box: Box; } { @@ -108,7 +103,9 @@ export class DrawHandlerImpl implements DrawHandler { }; } - private getFinalCuboidCoordinates(targetPoints: number[]): { + private getFinalCuboidCoordinates( + targetPoints: number[], + ): { points: number[]; box: Box; } { @@ -135,8 +132,7 @@ export class DrawHandlerImpl implements DrawHandler { for (let i = 0; i < points.length - 1; i += 2) { const [x, y] = points.slice(i); - if (x >= offset && x <= offset + frameWidth - && y >= offset && y <= offset + frameHeight) continue; + if (x >= offset && x <= offset + frameWidth && y >= offset && y <= offset + frameHeight) continue; let xOffset = 0; let yOffset = 0; @@ -158,9 +154,8 @@ export class DrawHandlerImpl implements DrawHandler { if (cuboidOffsets.length === points.length / 2) { cuboidOffsets.forEach((offsetCoords: number[]): void => { - if (Math.sqrt((offsetCoords[0] ** 2) + (offsetCoords[1] ** 2)) - < minCuboidOffset.d) { - minCuboidOffset.d = Math.sqrt((offsetCoords[0] ** 2) + (offsetCoords[1] ** 2)); + if (Math.sqrt(offsetCoords[0] ** 2 + offsetCoords[1] ** 2) < minCuboidOffset.d) { + minCuboidOffset.d = Math.sqrt(offsetCoords[0] ** 2 + offsetCoords[1] ** 2); [minCuboidOffset.dx, minCuboidOffset.dy] = offsetCoords; } }); @@ -188,22 +183,11 @@ export class DrawHandlerImpl implements DrawHandler { private addCrosshair(): void { const { x, y } = this.cursorPosition; - this.crosshair = { - x: this.canvas.line(0, y, this.canvas.node.clientWidth, y).attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale), - zOrder: Number.MAX_SAFE_INTEGER, - }).addClass('cvat_canvas_crosshair'), - y: this.canvas.line(x, 0, x, this.canvas.node.clientHeight).attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale), - zOrder: Number.MAX_SAFE_INTEGER, - }).addClass('cvat_canvas_crosshair'), - }; + this.crosshair.show(this.canvas, x, y, this.geometry.scale); } private removeCrosshair(): void { - this.crosshair.x.remove(); - this.crosshair.y.remove(); - this.crosshair = null; + this.crosshair.hide(); } private release(): void { @@ -228,8 +212,10 @@ export class DrawHandlerImpl implements DrawHandler { // Or when no drawn points, but we call cancel() drawing // We check if it is activated with remember function if (this.drawInstance.remember('_paintHandler')) { - if (this.drawData.shapeType !== 'rectangle' - && this.drawData.cuboidDrawingMethod !== CuboidDrawingMethod.CLASSIC) { + if ( + this.drawData.shapeType !== 'rectangle' && + this.drawData.cuboidDrawingMethod !== CuboidDrawingMethod.CLASSIC + ) { // Check for unsaved drawn shapes this.drawInstance.draw('done'); } @@ -261,37 +247,48 @@ export class DrawHandlerImpl implements DrawHandler { private drawBox(): void { this.drawInstance = this.canvas.rect(); - this.drawInstance.on('drawstop', (e: Event): void => { - const bbox = (e.target as SVGRectElement).getBBox(); - const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); - const { shapeType, redraw: clientID } = this.drawData; - this.release(); + this.drawInstance + .on('drawstop', (e: Event): void => { + const bbox = (e.target as SVGRectElement).getBBox(); + const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); + const { shapeType, redraw: clientID } = this.drawData; + this.release(); - if (this.canceled) return; - if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - this.onDrawDone({ - clientID, - shapeType, - points: [xtl, ytl, xbr, ybr], - }, Date.now() - this.startTimestamp); - } - }).on('drawupdate', (): void => { - this.shapeSizeElement.update(this.drawInstance); - }).addClass('cvat_canvas_shape_drawing').attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - }); + if (this.canceled) return; + if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { + this.onDrawDone( + { + clientID, + shapeType, + points: [xtl, ytl, xbr, ybr], + }, + Date.now() - this.startTimestamp, + ); + } + }) + .on('drawupdate', (): void => { + this.shapeSizeElement.update(this.drawInstance); + }) + .addClass('cvat_canvas_shape_drawing') + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + }); } private drawBoxBy4Points(): void { let numberOfPoints = 0; - this.drawInstance = (this.canvas as any).polygon() - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polygon() + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': 0, opacity: 0, - }).on('drawstart', (): void => { + }) + .on('drawstart', (): void => { // init numberOfPoints as one on drawstart numberOfPoints = 1; - }).on('drawpoint', (e: CustomEvent): void => { + }) + .on('drawpoint', (e: CustomEvent): void => { // increase numberOfPoints by one on drawpoint numberOfPoints += 1; @@ -303,14 +300,18 @@ export class DrawHandlerImpl implements DrawHandler { this.cancel(); if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - this.onDrawDone({ - shapeType, - clientID, - points: [xtl, ytl, xbr, ybr], - }, Date.now() - this.startTimestamp); + this.onDrawDone( + { + shapeType, + clientID, + points: [xtl, ytl, xbr, ybr], + }, + Date.now() - this.startTimestamp, + ); } } - }).on('undopoint', (): void => { + }) + .on('undopoint', (): void => { if (numberOfPoints > 0) { numberOfPoints -= 1; } @@ -324,12 +325,16 @@ export class DrawHandlerImpl implements DrawHandler { const sizeDecrement = (): void => { if (--size === 0) { - this.drawInstance.draw('done'); + // we need additional settimeout because we cannot invoke draw('done') + // from event listener for drawstart event + // because of implementation of svg.js + setTimeout((): void => this.drawInstance.draw('done')); } }; this.drawInstance.on('drawstart', sizeDecrement); this.drawInstance.on('drawpoint', sizeDecrement); + this.drawInstance.on('drawupdate', (): void => this.transform(this.geometry)); this.drawInstance.on('undopoint', (): number => size++); // Add ability to cancel the latest drawn point @@ -360,10 +365,7 @@ export class DrawHandlerImpl implements DrawHandler { } else { this.drawInstance.draw('update', e); const deltaTreshold = 15; - const delta = Math.sqrt( - ((e.clientX - lastDrawnPoint.x) ** 2) - + ((e.clientY - lastDrawnPoint.y) ** 2), - ); + const delta = Math.sqrt((e.clientX - lastDrawnPoint.x) ** 2 + (e.clientY - lastDrawnPoint.y) ** 2); if (delta > deltaTreshold) { this.drawInstance.draw('point', e); } @@ -384,50 +386,67 @@ export class DrawHandlerImpl implements DrawHandler { this.drawInstance.on('drawdone', (e: CustomEvent): void => { const targetPoints = pointsToNumberArray((e.target as SVGElement).getAttribute('points')); const { shapeType, redraw: clientID } = this.drawData; - const { points, box } = shapeType === 'cuboid' ? this.getFinalCuboidCoordinates(targetPoints) - : this.getFinalPolyshapeCoordinates(targetPoints); + const { points, box } = + shapeType === 'cuboid' + ? this.getFinalCuboidCoordinates(targetPoints) + : this.getFinalPolyshapeCoordinates(targetPoints); this.release(); if (this.canceled) return; - if (shapeType === 'polygon' - && ((box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD) - && points.length >= 3 * 2) { - this.onDrawDone({ - clientID, - shapeType, - points, - }, Date.now() - this.startTimestamp); - } else if (shapeType === 'polyline' - && ((box.xbr - box.xtl) >= consts.SIZE_THRESHOLD - || (box.ybr - box.ytl) >= consts.SIZE_THRESHOLD) - && points.length >= 2 * 2) { - this.onDrawDone({ - clientID, - shapeType, - points, - }, Date.now() - this.startTimestamp); - } else if (shapeType === 'points' - && (e.target as any).getAttribute('points') !== '0,0') { - this.onDrawDone({ - clientID, - shapeType, - points, - }, Date.now() - this.startTimestamp); + if ( + shapeType === 'polygon' && + (box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD && + points.length >= 3 * 2 + ) { + this.onDrawDone( + { + clientID, + shapeType, + points, + }, + Date.now() - this.startTimestamp, + ); + } else if ( + shapeType === 'polyline' && + (box.xbr - box.xtl >= consts.SIZE_THRESHOLD || box.ybr - box.ytl >= consts.SIZE_THRESHOLD) && + points.length >= 2 * 2 + ) { + this.onDrawDone( + { + clientID, + shapeType, + points, + }, + Date.now() - this.startTimestamp, + ); + } else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') { + this.onDrawDone( + { + clientID, + shapeType, + points, + }, + Date.now() - this.startTimestamp, + ); // TODO: think about correct constraign for cuboids - } else if (shapeType === 'cuboid' - && points.length === 4 * 2) { - this.onDrawDone({ - clientID, - shapeType, - points: cuboidFrom4Points(points), - }, Date.now() - this.startTimestamp); + } else if (shapeType === 'cuboid' && points.length === 4 * 2) { + this.onDrawDone( + { + clientID, + shapeType, + points: cuboidFrom4Points(points), + }, + Date.now() - this.startTimestamp, + ); } }); } private drawPolygon(): void { - this.drawInstance = (this.canvas as any).polygon() - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polygon() + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, }); @@ -438,8 +457,10 @@ export class DrawHandlerImpl implements DrawHandler { } private drawPolyline(): void { - this.drawInstance = (this.canvas as any).polyline() - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polyline() + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'fill-opacity': 0, }); @@ -451,18 +472,19 @@ export class DrawHandlerImpl implements DrawHandler { } private drawPoints(): void { - this.drawInstance = (this.canvas as any).polygon() - .addClass('cvat_canvas_shape_drawing').attr({ - 'stroke-width': 0, - opacity: 0, - }); + this.drawInstance = (this.canvas as any).polygon().addClass('cvat_canvas_shape_drawing').attr({ + 'stroke-width': 0, + opacity: 0, + }); this.drawPolyshape(); } private drawCuboidBy4Points(): void { - this.drawInstance = (this.canvas as any).polyline() - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polyline() + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, }); this.drawPolyshape(); @@ -470,25 +492,32 @@ export class DrawHandlerImpl implements DrawHandler { private drawCuboid(): void { this.drawInstance = this.canvas.rect(); - this.drawInstance.on('drawstop', (e: Event): void => { - const bbox = (e.target as SVGRectElement).getBBox(); - const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); - const { shapeType } = this.drawData; - this.release(); + this.drawInstance + .on('drawstop', (e: Event): void => { + const bbox = (e.target as SVGRectElement).getBBox(); + const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); + const { shapeType } = this.drawData; + this.release(); - if (this.canceled) return; - if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - const d = { x: (xbr - xtl) * 0.1, y: (ybr - ytl) * 0.1 }; - this.onDrawDone({ - shapeType, - points: cuboidFrom4Points([xtl, ybr, xbr, ybr, xbr, ytl, xbr + d.x, ytl - d.y]), - }, Date.now() - this.startTimestamp); - } - }).on('drawupdate', (): void => { - this.shapeSizeElement.update(this.drawInstance); - }).addClass('cvat_canvas_shape_drawing').attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - }); + if (this.canceled) return; + if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { + const d = { x: (xbr - xtl) * 0.1, y: (ybr - ytl) * 0.1 }; + this.onDrawDone( + { + shapeType, + points: cuboidFrom4Points([xtl, ybr, xbr, ybr, xbr, ytl, xbr + d.x, ytl - d.y]), + }, + Date.now() - this.startTimestamp, + ); + } + }) + .on('drawupdate', (): void => { + this.shapeSizeElement.update(this.drawInstance); + }) + .addClass('cvat_canvas_shape_drawing') + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + }); } private pastePolyshape(): void { @@ -498,22 +527,28 @@ export class DrawHandlerImpl implements DrawHandler { .split(/[,\s]/g) .map((coord: string): number => +coord); - const { points } = this.drawData.initialState.shapeType === 'cuboid' ? this.getFinalCuboidCoordinates(targetPoints) - : this.getFinalPolyshapeCoordinates(targetPoints); + const { points } = + this.drawData.initialState.shapeType === 'cuboid' + ? this.getFinalCuboidCoordinates(targetPoints) + : this.getFinalPolyshapeCoordinates(targetPoints); if (!e.detail.originalEvent.ctrlKey) { this.release(); } - this.onDrawDone({ - shapeType: this.drawData.initialState.shapeType, - objectType: this.drawData.initialState.objectType, - points, - occluded: this.drawData.initialState.occluded, - attributes: { ...this.drawData.initialState.attributes }, - label: this.drawData.initialState.label, - color: this.drawData.initialState.color, - }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); + this.onDrawDone( + { + shapeType: this.drawData.initialState.shapeType, + objectType: this.drawData.initialState.objectType, + points, + occluded: this.drawData.initialState.occluded, + attributes: { ...this.drawData.initialState.attributes }, + label: this.drawData.initialState.label, + color: this.drawData.initialState.color, + }, + Date.now() - this.startTimestamp, + e.detail.originalEvent.ctrlKey, + ); }); } @@ -534,9 +569,11 @@ export class DrawHandlerImpl implements DrawHandler { } private pasteBox(box: BBox): void { - this.drawInstance = (this.canvas as any).rect(box.width, box.height) + this.drawInstance = (this.canvas as any) + .rect(box.width, box.height) .move(box.x, box.y) - .addClass('cvat_canvas_shape_drawing').attr({ + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, }); this.pasteShape(); @@ -548,22 +585,27 @@ export class DrawHandlerImpl implements DrawHandler { this.release(); } - this.onDrawDone({ - shapeType: this.drawData.initialState.shapeType, - objectType: this.drawData.initialState.objectType, - points: [xtl, ytl, xbr, ybr], - occluded: this.drawData.initialState.occluded, - attributes: { ...this.drawData.initialState.attributes }, - label: this.drawData.initialState.label, - color: this.drawData.initialState.color, - }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); + this.onDrawDone( + { + shapeType: this.drawData.initialState.shapeType, + objectType: this.drawData.initialState.objectType, + points: [xtl, ytl, xbr, ybr], + occluded: this.drawData.initialState.occluded, + attributes: { ...this.drawData.initialState.attributes }, + label: this.drawData.initialState.label, + color: this.drawData.initialState.color, + }, + Date.now() - this.startTimestamp, + e.detail.originalEvent.ctrlKey, + ); }); } - private pastePolygon(points: string): void { - this.drawInstance = (this.canvas as any).polygon(points) - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polygon(points) + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, }); this.pasteShape(); @@ -571,8 +613,10 @@ export class DrawHandlerImpl implements DrawHandler { } private pastePolyline(points: string): void { - this.drawInstance = (this.canvas as any).polyline(points) - .addClass('cvat_canvas_shape_drawing').attr({ + this.drawInstance = (this.canvas as any) + .polyline(points) + .addClass('cvat_canvas_shape_drawing') + .attr({ 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, }); this.pasteShape(); @@ -580,22 +624,19 @@ export class DrawHandlerImpl implements DrawHandler { } private pasteCuboid(points: string): void { - this.drawInstance = (this.canvas as any).cube(points).addClass('cvat_canvas_shape_drawing').attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, - 'face-stroke': 'black', - }); + this.drawInstance = (this.canvas as any) + .cube(points) + .addClass('cvat_canvas_shape_drawing') + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + 'face-stroke': 'black', + }); this.pasteShape(); this.pastePolyshape(); } private pastePoints(initialPoints: string): void { - function moveShape( - shape: SVG.PolyLine, - group: SVG.G, - x: number, - y: number, - scale: number, - ): void { + function moveShape(shape: SVG.PolyLine, group: SVG.G, x: number, y: number, scale: number): void { const bbox = shape.bbox(); shape.move(x - bbox.width / 2, y - bbox.height / 2); @@ -610,10 +651,9 @@ export class DrawHandlerImpl implements DrawHandler { const { x: initialX, y: initialY } = this.cursorPosition; this.pointsGroup = this.canvas.group(); - this.drawInstance = (this.canvas as any).polyline(initialPoints) - .addClass('cvat_canvas_shape_drawing').style({ - 'stroke-width': 0, - }); + this.drawInstance = (this.canvas as any).polyline(initialPoints).addClass('cvat_canvas_shape_drawing').style({ + 'stroke-width': 0, + }); let numOfPoints = initialPoints.split(' ').length; while (numOfPoints) { @@ -626,15 +666,11 @@ export class DrawHandlerImpl implements DrawHandler { }); } - moveShape( - this.drawInstance, this.pointsGroup, initialX, initialY, this.geometry.scale, - ); + moveShape(this.drawInstance, this.pointsGroup, initialX, initialY, this.geometry.scale); this.canvas.on('mousemove.draw', (): void => { const { x, y } = this.cursorPosition; // was computer in another callback - moveShape( - this.drawInstance, this.pointsGroup, x, y, this.geometry.scale, - ); + moveShape(this.drawInstance, this.pointsGroup, x, y, this.geometry.scale); }); this.pastePolyshape(); @@ -668,8 +704,9 @@ export class DrawHandlerImpl implements DrawHandler { if (this.drawData.initialState) { const { offset } = this.geometry; if (this.drawData.shapeType === 'rectangle') { - const [xtl, ytl, xbr, ybr] = this.drawData.initialState.points - .map((coord: number): number => coord + offset); + const [xtl, ytl, xbr, ybr] = this.drawData.initialState.points.map( + (coord: number): number => coord + offset, + ); this.pasteBox({ x: xtl, @@ -678,8 +715,7 @@ export class DrawHandlerImpl implements DrawHandler { height: ybr - ytl, }); } else { - const points = this.drawData.initialState.points - .map((coord: number): number => coord + offset); + const points = this.drawData.initialState.points.map((coord: number): number => coord + offset); const stringifiedPoints = stringifyPoints(points); if (this.drawData.shapeType === 'polygon') { @@ -741,7 +777,7 @@ export class DrawHandlerImpl implements DrawHandler { this.canceled = false; this.drawData = null; this.geometry = null; - this.crosshair = null; + this.crosshair = new Crosshair(); this.drawInstance = null; this.pointsGroup = null; this.cursorPosition = { @@ -750,28 +786,20 @@ export class DrawHandlerImpl implements DrawHandler { }; this.canvas.on('mousemove.crosshair', (e: MouseEvent): void => { - const [x, y] = translateToSVG( - this.canvas.node as any as SVGSVGElement, - [e.clientX, e.clientY], - ); + const [x, y] = translateToSVG((this.canvas.node as any) as SVGSVGElement, [e.clientX, e.clientY]); this.cursorPosition = { x, y }; if (this.crosshair) { - this.crosshair.x.attr({ y1: y, y2: y }); - this.crosshair.y.attr({ x1: x, x2: x }); + this.crosshair.move(x, y); } }); } public configurate(configuration: Configuration): void { - if (typeof (configuration.autoborders) === 'boolean') { + if (typeof configuration.autoborders === 'boolean') { this.autobordersEnabled = configuration.autoborders; if (this.drawInstance) { if (this.autobordersEnabled) { - this.autoborderHandler.autoborder( - true, - this.drawInstance, - this.drawData.redraw, - ); + this.autoborderHandler.autoborder(true, this.drawInstance, this.drawData.redraw); } else { this.autoborderHandler.autoborder(false); } @@ -787,12 +815,7 @@ export class DrawHandlerImpl implements DrawHandler { } if (this.crosshair) { - this.crosshair.x.attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * geometry.scale), - }); - this.crosshair.y.attr({ - 'stroke-width': consts.BASE_STROKE_WIDTH / (2 * geometry.scale), - }); + this.crosshair.scale(this.geometry.scale); } if (this.pointsGroup) { @@ -813,14 +836,8 @@ export class DrawHandlerImpl implements DrawHandler { const paintHandler = this.drawInstance.remember('_paintHandler'); for (const point of (paintHandler as any).set.members) { - point.attr( - 'stroke-width', - `${consts.POINTS_STROKE_WIDTH / geometry.scale}`, - ); - point.attr( - 'r', - `${consts.BASE_POINT_SIZE / geometry.scale}`, - ); + point.attr('stroke-width', `${consts.POINTS_STROKE_WIDTH / geometry.scale}`); + point.attr('r', `${consts.BASE_POINT_SIZE / geometry.scale}`); } } } diff --git a/cvat-canvas/src/typescript/editHandler.ts b/cvat-canvas/src/typescript/editHandler.ts index 8cea079d..c10450bc 100644 --- a/cvat-canvas/src/typescript/editHandler.ts +++ b/cvat-canvas/src/typescript/editHandler.ts @@ -47,7 +47,8 @@ export class EditHandlerImpl implements EditHandler { if (e.button !== 0) return; const { offset } = this.geometry; const stringifiedPoints = `${head} ${this.editLine.node.getAttribute('points').slice(0, -2)}`; - const points = pointsToNumberArray(stringifiedPoints).slice(0, -2) + const points = pointsToNumberArray(stringifiedPoints) + .slice(0, -2) .map((coord: number): number => coord - offset); if (points.length >= minimumPoints * 2) { @@ -63,7 +64,7 @@ export class EditHandlerImpl implements EditHandler { private startEdit(): void { // get started coordinates const [clientX, clientY] = translateFromSVG( - this.canvas.node as any as SVGSVGElement, + (this.canvas.node as any) as SVGSVGElement, this.editedShape.attr('points').split(' ')[this.editData.pointID].split(','), ); @@ -92,10 +93,7 @@ export class EditHandlerImpl implements EditHandler { (this.editLine as any).draw('point', e); } else { const deltaTreshold = 15; - const delta = Math.sqrt( - ((e.clientX - lastDrawnPoint.x) ** 2) - + ((e.clientY - lastDrawnPoint.y) ** 2), - ); + const delta = Math.sqrt((e.clientX - lastDrawnPoint.x) ** 2 + (e.clientY - lastDrawnPoint.y) ** 2); if (delta > deltaTreshold) { (this.editLine as any).draw('point', e); } @@ -112,17 +110,23 @@ export class EditHandlerImpl implements EditHandler { } const strokeColor = this.editedShape.attr('stroke'); - (this.editLine as any).addClass('cvat_canvas_shape_drawing').style({ - 'pointer-events': 'none', - 'fill-opacity': 0, - 'stroke': strokeColor, - }).attr({ - 'data-origin-client-id': this.editData.state.clientID, - }).on('drawstart drawpoint', (e: CustomEvent): void => { - this.transform(this.geometry); - lastDrawnPoint.x = e.detail.event.clientX; - lastDrawnPoint.y = e.detail.event.clientY; - }).draw(dummyEvent, { snapToGrid: 0.1 }); + (this.editLine as any) + .addClass('cvat_canvas_shape_drawing') + .style({ + 'pointer-events': 'none', + 'fill-opacity': 0, + stroke: strokeColor, + }) + .attr({ + 'data-origin-client-id': this.editData.state.clientID, + }) + .on('drawstart drawpoint', (e: CustomEvent): void => { + this.transform(this.geometry); + lastDrawnPoint.x = e.detail.event.clientX; + lastDrawnPoint.y = e.detail.event.clientY; + }) + .on('drawupdate', (): void => this.transform(this.geometry)) + .draw(dummyEvent, { snapToGrid: 0.1 }); if (this.editData.state.shapeType === 'points') { this.editLine.attr('stroke-width', 0); @@ -140,9 +144,7 @@ export class EditHandlerImpl implements EditHandler { if (e.button === 0 && !e.altKey) { (this.editLine as any).draw('point', e); } else if (e.button === 2 && this.editLine) { - if (this.editData.state.shapeType === 'points' - || this.editLine.attr('points').split(' ').length > 2 - ) { + if (this.editData.state.shapeType === 'points' || this.editLine.attr('points').split(' ').length > 2) { (this.editLine as any).draw('undo'); } } @@ -151,8 +153,7 @@ export class EditHandlerImpl implements EditHandler { private selectPolygon(shape: SVG.Polygon): void { const { offset } = this.geometry; - const points = pointsToNumberArray(shape.attr('points')) - .map((coord: number): number => coord - offset); + const points = pointsToNumberArray(shape.attr('points')).map((coord: number): number => coord - offset); const { state } = this.editData; this.edit({ @@ -167,8 +168,7 @@ export class EditHandlerImpl implements EditHandler { } // Get stop point and all points - const stopPointID = Array.prototype.indexOf - .call((e.target as HTMLElement).parentElement.children, e.target); + const stopPointID = Array.prototype.indexOf.call((e.target as HTMLElement).parentElement.children, e.target); const oldPoints = this.editedShape.attr('points').trim().split(' '); const linePoints = this.editLine.attr('points').trim().split(' '); @@ -178,8 +178,7 @@ export class EditHandlerImpl implements EditHandler { } // Compute new point array - const [start, stop] = [this.editData.pointID, stopPointID] - .sort((a, b): number => +a - +b); + const [start, stop] = [this.editData.pointID, stopPointID].sort((a, b): number => +a - +b); if (this.editData.state.shapeType !== 'polygon') { let points = null; @@ -189,15 +188,15 @@ export class EditHandlerImpl implements EditHandler { if (start !== this.editData.pointID) { linePoints.reverse(); } - points = oldPoints.slice(0, start) + points = oldPoints + .slice(0, start) .concat(linePoints) .concat(oldPoints.slice(stop + 1)); } else { points = oldPoints.concat(linePoints.slice(0, -1)); } - points = pointsToNumberArray(points.join(' ')) - .map((coord: number): number => coord - offset); + points = pointsToNumberArray(points.join(' ')).map((coord: number): number => coord - offset); const { state } = this.editData; this.edit({ @@ -208,25 +207,27 @@ export class EditHandlerImpl implements EditHandler { return; } - const cutIndexes1 = oldPoints.reduce((acc: string[], _: string, i: number) => - i >= stop || i <= start ? [...acc, i] : acc, []); - const cutIndexes2 = oldPoints.reduce((acc: string[], _: string, i: number) => - i <= stop && i >= start ? [...acc, i] : acc, []); + const cutIndexes1 = oldPoints.reduce( + (acc: string[], _: string, i: number) => (i >= stop || i <= start ? [...acc, i] : acc), + [], + ); + const cutIndexes2 = oldPoints.reduce( + (acc: string[], _: string, i: number) => (i <= stop && i >= start ? [...acc, i] : acc), + [], + ); - const curveLength = (indexes: number[]) => { - const points = indexes.map((index: number): string => oldPoints[index]) + const curveLength = (indexes: number[]): number => { + const points = indexes + .map((index: number): string => oldPoints[index]) .map((point: string): string[] => point.split(',')) .map((point: string[]): number[] => [+point[0], +point[1]]); let length = 0; for (let i = 1; i < points.length; i++) { - length += Math.sqrt( - (points[i][0] - points[i - 1][0]) ** 2 - + (points[i][1] - points[i - 1][1]) ** 2, - ); + length += Math.sqrt((points[i][0] - points[i - 1][0]) ** 2 + (points[i][1] - points[i - 1][1]) ** 2); } return length; - } + }; const pointsCriteria = cutIndexes1.length > cutIndexes2.length; const lengthCriteria = curveLength(cutIndexes1) > curveLength(cutIndexes2); @@ -235,11 +236,11 @@ export class EditHandlerImpl implements EditHandler { linePoints.reverse(); } - const firstPart = oldPoints.slice(0, start) + const firstPart = oldPoints + .slice(0, start) .concat(linePoints) .concat(oldPoints.slice(stop + 1)); - const secondPart = oldPoints.slice(start, stop) - .concat(linePoints.slice(1).reverse()); + const secondPart = oldPoints.slice(start, stop).concat(linePoints.slice(1).reverse()); if (firstPart.length < 3 || secondPart.length < 3) { this.cancel(); @@ -263,23 +264,26 @@ export class EditHandlerImpl implements EditHandler { this.selectPolygon(this.clones[0]); } else { for (const points of [firstPart, secondPart]) { - this.clones.push(this.canvas.polygon(points.join(' ')) - .attr('fill', this.editedShape.attr('fill')) - .attr('fill-opacity', '0.5') - .addClass('cvat_canvas_shape')); + this.clones.push( + this.canvas + .polygon(points.join(' ')) + .attr('fill', this.editedShape.attr('fill')) + .attr('fill-opacity', '0.5') + .addClass('cvat_canvas_shape'), + ); } for (const clone of this.clones) { clone.on('click', (): void => this.selectPolygon(clone)); - clone.on('mouseenter', (): void => { - clone.addClass('cvat_canvas_shape_splitting'); - }).on('mouseleave', (): void => { - clone.removeClass('cvat_canvas_shape_splitting'); - }); + clone + .on('mouseenter', (): void => { + clone.addClass('cvat_canvas_shape_splitting'); + }) + .on('mouseleave', (): void => { + clone.removeClass('cvat_canvas_shape_splitting'); + }); } } - - return; } private setupPoints(enabled: boolean): void { @@ -289,7 +293,7 @@ export class EditHandlerImpl implements EditHandler { if (enabled) { (this.editedShape as any).selectize(true, { deepSelect: true, - pointSize: 2 * consts.BASE_POINT_SIZE / self.geometry.scale, + pointSize: (2 * consts.BASE_POINT_SIZE) / self.geometry.scale, rotationPoint: false, pointType(cx: number, cy: number): SVG.Circle { const circle: SVG.Circle = this.nested @@ -355,9 +359,7 @@ export class EditHandlerImpl implements EditHandler { } private initEditing(): void { - this.editedShape = this.canvas - .select(`#cvat_canvas_shape_${this.editData.state.clientID}`) - .first().clone(); + this.editedShape = this.canvas.select(`#cvat_canvas_shape_${this.editData.state.clientID}`).first().clone(); this.setupPoints(true); this.startEdit(); // draw points for this with selected and start editing till another point is clicked @@ -407,15 +409,11 @@ export class EditHandlerImpl implements EditHandler { } public configurate(configuration: Configuration): void { - if (typeof (configuration.autoborders) === 'boolean') { + if (typeof configuration.autoborders === 'boolean') { this.autobordersEnabled = configuration.autoborders; if (this.editLine) { if (this.autobordersEnabled) { - this.autoborderHandler.autoborder( - true, - this.editLine, - this.editData.state.clientID, - ); + this.autoborderHandler.autoborder(true, this.editLine, this.editData.state.clientID); } else { this.autoborderHandler.autoborder(false); } @@ -443,14 +441,8 @@ export class EditHandlerImpl implements EditHandler { const paintHandler = this.editLine.remember('_paintHandler'); for (const point of (paintHandler as any).set.members) { - point.attr( - 'stroke-width', - `${consts.POINTS_STROKE_WIDTH / geometry.scale}`, - ); - point.attr( - 'r', - `${consts.BASE_POINT_SIZE / geometry.scale}`, - ); + point.attr('stroke-width', `${consts.POINTS_STROKE_WIDTH / geometry.scale}`); + point.attr('r', `${consts.BASE_POINT_SIZE / geometry.scale}`); } } } diff --git a/cvat-canvas/src/typescript/groupHandler.ts b/cvat-canvas/src/typescript/groupHandler.ts index f92cdab6..c94b5cbf 100644 --- a/cvat-canvas/src/typescript/groupHandler.ts +++ b/cvat-canvas/src/typescript/groupHandler.ts @@ -5,10 +5,7 @@ import * as SVG from 'svg.js'; import { GroupData } from './canvasModel'; -import { - translateToSVG, -} from './shared'; - +import { translateToSVG } from './shared'; export interface GroupHandler { group(groupData: GroupData): void; @@ -35,16 +32,15 @@ export class GroupHandlerImpl implements GroupHandler { private statesToBeGroupped: any[]; private highlightedShapes: Record; - private getSelectionBox(event: MouseEvent): { - xtl: number; - ytl: number; - xbr: number; - ybr: number; - } { - const point = translateToSVG( - (this.canvas.node as any as SVGSVGElement), - [event.clientX, event.clientY], - ); + private getSelectionBox( + event: MouseEvent, + ): { + xtl: number; + ytl: number; + xbr: number; + ybr: number; + } { + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); const stopSelectionPoint = { x: point[0], y: point[1], @@ -60,10 +56,7 @@ export class GroupHandlerImpl implements GroupHandler { private onSelectStart(event: MouseEvent): void { if (!this.selectionRect) { - const point = translateToSVG( - this.canvas.node as any as SVGSVGElement, - [event.clientX, event.clientY], - ); + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); this.startSelectionPoint = { x: point[0], y: point[1], @@ -102,12 +95,16 @@ export class GroupHandlerImpl implements GroupHandler { // TODO: Doesn't work properly for groups const bbox = shape.bbox(); const clientID = shape.attr('clientID'); - if (bbox.x > box.xtl && bbox.y > box.ytl + if ( + bbox.x > box.xtl + && bbox.y > box.ytl && bbox.x + bbox.width < box.xbr && bbox.y + bbox.height < box.ybr - && !(clientID in this.highlightedShapes)) { - const objectState = this.getStates() - .filter((state: any): boolean => state.clientID === clientID)[0]; + && !(clientID in this.highlightedShapes) + ) { + const objectState = this.getStates().filter( + (state: any): boolean => state.clientID === clientID, + )[0]; if (objectState) { this.statesToBeGroupped.push(objectState); @@ -127,7 +124,6 @@ export class GroupHandlerImpl implements GroupHandler { this.resetSelectedObjects(); this.initialized = false; - this.selectionRect = null; this.startSelectionPoint = { x: null, y: null, @@ -216,6 +212,10 @@ export class GroupHandlerImpl implements GroupHandler { } this.statesToBeGroupped = []; this.highlightedShapes = {}; + if (this.selectionRect) { + this.selectionRect.remove(); + this.selectionRect = null; + } } public cancel(): void { diff --git a/cvat-canvas/src/typescript/interactionHandler.ts b/cvat-canvas/src/typescript/interactionHandler.ts new file mode 100644 index 00000000..ee2fbc90 --- /dev/null +++ b/cvat-canvas/src/typescript/interactionHandler.ts @@ -0,0 +1,268 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import * as SVG from 'svg.js'; +import consts from './consts'; +import Crosshair from './crosshair'; +import { translateToSVG } from './shared'; +import { InteractionData, InteractionResult, Geometry } from './canvasModel'; + +export interface InteractionHandler { + transform(geometry: Geometry): void; + interact(interactData: InteractionData): void; + cancel(): void; +} + +export class InteractionHandlerImpl implements InteractionHandler { + private onInteraction: (shapes: InteractionResult[] | null, shapesUpdated?: boolean, isDone?: boolean) => void; + private geometry: Geometry; + private canvas: SVG.Container; + private interactionData: InteractionData; + private cursorPosition: { x: number; y: number }; + private shapesWereUpdated: boolean; + private interactionShapes: SVG.Shape[]; + private currentInteractionShape: SVG.Shape | null; + private crosshair: Crosshair; + + private prepareResult(): InteractionResult[] { + return this.interactionShapes.map( + (shape: SVG.Shape): InteractionResult => { + if (shape.type === 'circle') { + const points = [(shape as SVG.Circle).cx(), (shape as SVG.Circle).cy()]; + return { + points: points.map((coord: number): number => coord - this.geometry.offset), + shapeType: 'points', + button: shape.attr('stroke') === 'green' ? 0 : 2, + }; + } + + const bbox = ((shape.node as any) as SVGRectElement).getBBox(); + const points = [bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height]; + return { + points: points.map((coord: number): number => coord - this.geometry.offset), + shapeType: 'rectangle', + button: 0, + }; + }, + ); + } + + private shouldRaiseEvent(ctrlKey: boolean): boolean { + const { interactionData, interactionShapes, shapesWereUpdated } = this; + const { minPosVertices, minNegVertices, enabled } = interactionData; + + const positiveShapes = interactionShapes.filter( + (shape: SVG.Shape): boolean => (shape as any).attr('stroke') === 'green', + ); + const negativeShapes = interactionShapes.filter( + (shape: SVG.Shape): boolean => (shape as any).attr('stroke') !== 'green', + ); + + if (interactionData.shapeType === 'rectangle') { + return enabled && !ctrlKey && !!interactionShapes.length; + } + + const minimumVerticesAchieved = + (typeof minPosVertices === 'undefined' || minPosVertices <= positiveShapes.length) && + (typeof minNegVertices === 'undefined' || minPosVertices <= negativeShapes.length); + return enabled && !ctrlKey && minimumVerticesAchieved && shapesWereUpdated; + } + + private addCrosshair(): void { + const { x, y } = this.cursorPosition; + this.crosshair.show(this.canvas, x, y, this.geometry.scale); + } + + private removeCrosshair(): void { + this.crosshair.hide(); + } + + private interactPoints(): void { + const eventListener = (e: MouseEvent): void => { + if ((e.button === 0 || e.button === 2) && !e.altKey) { + e.preventDefault(); + const [cx, cy] = translateToSVG((this.canvas.node as any) as SVGSVGElement, [e.clientX, e.clientY]); + this.currentInteractionShape = this.canvas + .circle((consts.BASE_POINT_SIZE * 2) / this.geometry.scale) + .center(cx, cy) + .fill('white') + .stroke(e.button === 0 ? 'green' : 'red') + .addClass('cvat_interaction_point') + .attr({ + 'stroke-width': consts.POINTS_STROKE_WIDTH / this.geometry.scale, + }); + + this.interactionShapes.push(this.currentInteractionShape); + this.shapesWereUpdated = true; + if (this.shouldRaiseEvent(e.ctrlKey)) { + this.onInteraction(this.prepareResult(), true, false); + } + + const self = this.currentInteractionShape; + self.on('mouseenter', (): void => { + self.attr({ + 'stroke-width': consts.POINTS_SELECTED_STROKE_WIDTH / this.geometry.scale, + }); + + self.on('mousedown', (_e: MouseEvent): void => { + _e.preventDefault(); + _e.stopPropagation(); + self.remove(); + this.interactionShapes = this.interactionShapes.filter( + (shape: SVG.Shape): boolean => shape !== self, + ); + this.shapesWereUpdated = true; + if (this.shouldRaiseEvent(_e.ctrlKey)) { + this.onInteraction(this.prepareResult(), true, false); + } + }); + }); + + self.on('mouseleave', (): void => { + self.attr({ + 'stroke-width': consts.POINTS_STROKE_WIDTH / this.geometry.scale, + }); + + self.off('mousedown'); + }); + } + }; + + // clear this listener in relese() + this.canvas.on('mousedown.interaction', eventListener); + } + + private interactRectangle(): void { + let initialized = false; + const eventListener = (e: MouseEvent): void => { + if (e.button === 0 && !e.altKey) { + if (!initialized) { + (this.currentInteractionShape as any).draw(e, { snapToGrid: 0.1 }); + initialized = true; + } else { + (this.currentInteractionShape as any).draw(e); + } + } + }; + + this.currentInteractionShape = this.canvas.rect(); + this.canvas.on('mousedown.interaction', eventListener); + this.currentInteractionShape + .on('drawstop', (): void => { + this.interactionShapes.push(this.currentInteractionShape); + this.shapesWereUpdated = true; + + this.canvas.off('mousedown.interaction', eventListener); + this.interact({ enabled: false }); + }) + .addClass('cvat_canvas_shape_drawing') + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + }); + } + + private initInteraction(): void { + if (this.interactionData.crosshair) { + this.addCrosshair(); + } + } + + private startInteraction(): void { + if (this.interactionData.shapeType === 'rectangle') { + this.interactRectangle(); + } else if (this.interactionData.shapeType === 'points') { + this.interactPoints(); + } else { + throw new Error('Interactor implementation supports only rectangle and points'); + } + } + + private release(): void { + if (this.crosshair) { + this.removeCrosshair(); + } + + this.canvas.off('mousedown.interaction'); + this.interactionShapes.forEach((shape: SVG.Shape): SVG.Shape => shape.remove()); + this.interactionShapes = []; + if (this.currentInteractionShape) { + this.currentInteractionShape.remove(); + this.currentInteractionShape = null; + } + } + + public constructor( + onInteraction: (shapes: InteractionResult[] | null, shapesUpdated?: boolean, isDone?: boolean) => void, + canvas: SVG.Container, + geometry: Geometry, + ) { + this.onInteraction = (shapes: InteractionResult[] | null, shapesUpdated?: boolean, isDone?: boolean): void => { + this.shapesWereUpdated = false; + onInteraction(shapes, shapesUpdated, isDone); + }; + this.canvas = canvas; + this.geometry = geometry; + this.shapesWereUpdated = false; + this.interactionShapes = []; + this.interactionData = { enabled: false }; + this.currentInteractionShape = null; + this.crosshair = new Crosshair(); + this.cursorPosition = { + x: 0, + y: 0, + }; + + this.canvas.on('mousemove.interaction', (e: MouseEvent): void => { + const [x, y] = translateToSVG((this.canvas.node as any) as SVGSVGElement, [e.clientX, e.clientY]); + this.cursorPosition = { x, y }; + if (this.crosshair) { + this.crosshair.move(x, y); + } + }); + + document.body.addEventListener('keyup', (e: KeyboardEvent): void => { + if (e.keyCode === 17 && this.shouldRaiseEvent(false)) { + // 17 is ctrl + this.onInteraction(this.prepareResult(), true, false); + } + }); + } + + public transform(geometry: Geometry): void { + this.geometry = geometry; + + if (this.crosshair) { + this.crosshair.scale(this.geometry.scale); + } + + const shapesToBeScaled = this.currentInteractionShape + ? [...this.interactionShapes, this.currentInteractionShape] + : [...this.interactionShapes]; + for (const shape of shapesToBeScaled) { + if (shape.type === 'circle') { + (shape as SVG.Circle).radius(consts.BASE_POINT_SIZE / this.geometry.scale); + shape.attr('stroke-width', consts.POINTS_STROKE_WIDTH / this.geometry.scale); + } else { + shape.attr('stroke-width', consts.BASE_STROKE_WIDTH / this.geometry.scale); + } + } + } + + public interact(interactionData: InteractionData): void { + if (interactionData.enabled) { + this.interactionData = interactionData; + this.initInteraction(); + this.startInteraction(); + } else { + this.onInteraction(this.prepareResult(), this.shouldRaiseEvent(false), true); + this.release(); + this.interactionData = interactionData; + } + } + + public cancel(): void { + this.release(); + this.onInteraction(null); + } +} diff --git a/cvat-canvas/src/typescript/mergeHandler.ts b/cvat-canvas/src/typescript/mergeHandler.ts index cfb3f78c..530f363c 100644 --- a/cvat-canvas/src/typescript/mergeHandler.ts +++ b/cvat-canvas/src/typescript/mergeHandler.ts @@ -12,7 +12,6 @@ export interface MergeHandler { repeatSelection(): void; } - export class MergeHandlerImpl implements MergeHandler { // callback is used to notify about merging end private onMergeDone: (objects: any[] | null, duration?: number) => void; @@ -40,8 +39,10 @@ export class MergeHandlerImpl implements MergeHandler { } private checkConstraints(state: any): boolean { - return !this.constraints || (state.label.id === this.constraints.labelID - && state.shapeType === this.constraints.shapeType); + return ( + !this.constraints || + (state.label.id === this.constraints.labelID && state.shapeType === this.constraints.shapeType) + ); } private release(): void { @@ -118,8 +119,7 @@ export class MergeHandlerImpl implements MergeHandler { } } else { const shape = this.canvas.select(`#cvat_canvas_shape_${objectState.clientID}`).first(); - if (shape && this.checkConstraints(objectState) - && !stateFrames.includes(objectState.frame)) { + if (shape && this.checkConstraints(objectState) && !stateFrames.includes(objectState.frame)) { this.statesToBeMerged.push(objectState); this.highlightedShapes[objectState.clientID] = shape; shape.addClass('cvat_canvas_shape_merging'); diff --git a/cvat-canvas/src/typescript/regionSelector.ts b/cvat-canvas/src/typescript/regionSelector.ts new file mode 100644 index 00000000..189c1bbf --- /dev/null +++ b/cvat-canvas/src/typescript/regionSelector.ts @@ -0,0 +1,133 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import * as SVG from 'svg.js'; + +import consts from './consts'; +import { translateToSVG } from './shared'; +import { Geometry } from './canvasModel'; + +export interface RegionSelector { + select(enabled: boolean): void; + cancel(): void; + transform(geometry: Geometry): void; +} + +export class RegionSelectorImpl implements RegionSelector { + private onRegionSelected: (points?: number[]) => void; + private geometry: Geometry; + private canvas: SVG.Container; + private selectionRect: SVG.Rect | null; + private startSelectionPoint: { + x: number; + y: number; + }; + + private getSelectionBox(event: MouseEvent): { xtl: number; ytl: number; xbr: number; ybr: number } { + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); + const stopSelectionPoint = { + x: point[0], + y: point[1], + }; + + return { + xtl: Math.min(this.startSelectionPoint.x, stopSelectionPoint.x), + ytl: Math.min(this.startSelectionPoint.y, stopSelectionPoint.y), + xbr: Math.max(this.startSelectionPoint.x, stopSelectionPoint.x), + ybr: Math.max(this.startSelectionPoint.y, stopSelectionPoint.y), + }; + } + + private onMouseMove = (event: MouseEvent): void => { + if (this.selectionRect) { + const box = this.getSelectionBox(event); + + this.selectionRect.attr({ + x: box.xtl, + y: box.ytl, + width: box.xbr - box.xtl, + height: box.ybr - box.ytl, + }); + } + }; + + private onMouseDown = (event: MouseEvent): void => { + if (!this.selectionRect && !event.altKey) { + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); + this.startSelectionPoint = { + x: point[0], + y: point[1], + }; + + this.selectionRect = this.canvas + .rect() + .attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, + }) + .addClass('cvat_canvas_shape_region_selection'); + this.selectionRect.attr({ ...this.startSelectionPoint }); + } + }; + + private onMouseUp = (): void => { + const { offset } = this.geometry; + if (this.selectionRect) { + const { + w, h, x, y, x2, y2, + } = this.selectionRect.bbox(); + this.selectionRect.remove(); + this.selectionRect = null; + if (w === 0 && h === 0) { + this.onRegionSelected([x - offset, y - offset]); + } else { + this.onRegionSelected([x - offset, y - offset, x2 - offset, y2 - offset]); + } + } + }; + + private startSelection(): void { + this.canvas.node.addEventListener('mousemove', this.onMouseMove); + this.canvas.node.addEventListener('mousedown', this.onMouseDown); + this.canvas.node.addEventListener('mouseup', this.onMouseUp); + } + + private stopSelection(): void { + this.canvas.node.removeEventListener('mousemove', this.onMouseMove); + this.canvas.node.removeEventListener('mousedown', this.onMouseDown); + this.canvas.node.removeEventListener('mouseup', this.onMouseUp); + } + + private release(): void { + this.stopSelection(); + } + + public constructor(onRegionSelected: (points?: number[]) => void, canvas: SVG.Container, geometry: Geometry) { + this.onRegionSelected = onRegionSelected; + this.geometry = geometry; + this.canvas = canvas; + this.selectionRect = null; + } + + public select(enabled: boolean): void { + if (enabled) { + this.startSelection(); + } else { + this.release(); + } + } + + public cancel(): void { + this.release(); + this.onRegionSelected(); + } + + public transform(geometry: Geometry): void { + this.geometry = geometry; + if (this.selectionRect) { + this.selectionRect.attr({ + 'stroke-width': consts.BASE_STROKE_WIDTH / geometry.scale, + }); + } + } +} diff --git a/cvat-canvas/src/typescript/shared.ts b/cvat-canvas/src/typescript/shared.ts index d1f9cb8c..5eb09324 100644 --- a/cvat-canvas/src/typescript/shared.ts +++ b/cvat-canvas/src/typescript/shared.ts @@ -83,22 +83,25 @@ export function translateToSVG(svg: SVGSVGElement, points: number[]): number[] { return output; } -export function displayShapeSize( - shapesContainer: SVG.Container, - textContainer: SVG.Container, -): ShapeSizeElement { +export function displayShapeSize(shapesContainer: SVG.Container, textContainer: SVG.Container): ShapeSizeElement { const shapeSize: ShapeSizeElement = { - sizeElement: textContainer.text('').font({ - weight: 'bolder', - }).fill('white').addClass('cvat_canvas_text'), - update(shape: SVG.Shape): void{ + sizeElement: textContainer + .text('') + .font({ + weight: 'bolder', + }) + .fill('white') + .addClass('cvat_canvas_text'), + update(shape: SVG.Shape): void { const bbox = shape.bbox(); const text = `${bbox.width.toFixed(1)}x${bbox.height.toFixed(1)}`; const [x, y]: number[] = translateToSVG( - textContainer.node as any as SVGSVGElement, - translateFromSVG((shapesContainer.node as any as SVGSVGElement), [bbox.x, bbox.y]), + (textContainer.node as any) as SVGSVGElement, + translateFromSVG((shapesContainer.node as any) as SVGSVGElement, [bbox.x, bbox.y]), ); - this.sizeElement.clear().plain(text) + this.sizeElement + .clear() + .plain(text) .move(x + consts.TEXT_MARGIN, y + consts.TEXT_MARGIN); }, rm(): void { @@ -120,7 +123,9 @@ export function pointsToNumberArray(points: string | Point[]): number[] { }, []); } - return points.trim().split(/[,\s]+/g) + return points + .trim() + .split(/[,\s]+/g) .map((coord: string): number => +coord); } @@ -138,14 +143,19 @@ export function parsePoints(source: string | number[]): Point[] { }, []); } - return source.trim().split(/\s/).map((point: string): Point => { - const [x, y] = point.split(',').map((coord: string): number => +coord); - return { x, y }; - }); + return source + .trim() + .split(/\s/) + .map( + (point: string): Point => { + const [x, y] = point.split(',').map((coord: string): number => +coord); + return { x, y }; + }, + ); } export function stringifyPoints(points: (Point | number)[]): string { - if (typeof (points[0]) === 'number') { + if (typeof points[0] === 'number') { return points.reduce((acc: string, val: number, idx: number): string => { if (idx % 2) { return `${acc},${val}`; @@ -166,5 +176,5 @@ export function scalarProduct(a: Vector2D, b: Vector2D): number { } export function vectorLength(vector: Vector2D): number { - return Math.sqrt((vector.i ** 2) + (vector.j ** 2)); + return Math.sqrt(vector.i ** 2 + vector.j ** 2); } diff --git a/cvat-canvas/src/typescript/splitHandler.ts b/cvat-canvas/src/typescript/splitHandler.ts index c0756526..b8224d33 100644 --- a/cvat-canvas/src/typescript/splitHandler.ts +++ b/cvat-canvas/src/typescript/splitHandler.ts @@ -85,12 +85,16 @@ export class SplitHandlerImpl implements SplitHandler { this.highlightedShape = shape; this.highlightedShape.addClass('cvat_canvas_shape_splitting'); this.canvas.node.append(this.highlightedShape.node); - this.highlightedShape.on('click.split', (): void => { - this.splitDone = true; - this.onSplitDone(state); - }, { - once: true, - }); + this.highlightedShape.on( + 'click.split', + (): void => { + this.splitDone = true; + this.onSplitDone(state); + }, + { + once: true, + }, + ); } } } diff --git a/cvat-canvas/src/typescript/svg.patch.ts b/cvat-canvas/src/typescript/svg.patch.ts index 3d88c7da..d2728630 100644 --- a/cvat-canvas/src/typescript/svg.patch.ts +++ b/cvat-canvas/src/typescript/svg.patch.ts @@ -10,13 +10,7 @@ import 'svg.select.js'; import 'svg.draw.js'; import consts from './consts'; -import { - Point, - Equation, - CuboidModel, - Orientation, - Edge, -} from './cuboid'; +import { Point, Equation, CuboidModel, Orientation, Edge } from './cuboid'; import { parsePoints, clamp } from './shared'; // Update constructor @@ -51,20 +45,19 @@ function undo(): void { } } -SVG.Element.prototype.draw.extend('polyline', Object.assign({}, - SVG.Element.prototype.draw.plugins.polyline, - { +SVG.Element.prototype.draw.extend( + 'polyline', + Object.assign({}, SVG.Element.prototype.draw.plugins.polyline, { undo: undo, - }, -)); + }), +); -SVG.Element.prototype.draw.extend('polygon', Object.assign({}, - SVG.Element.prototype.draw.plugins.polygon, - { +SVG.Element.prototype.draw.extend( + 'polygon', + Object.assign({}, SVG.Element.prototype.draw.plugins.polygon, { undo: undo, - }, -)); - + }), +); // Create transform for rect, polyline and polygon function transform(): void { @@ -72,26 +65,26 @@ function transform(): void { this.offset = { x: window.pageXOffset, y: window.pageYOffset }; } -SVG.Element.prototype.draw.extend('rect', Object.assign({}, - SVG.Element.prototype.draw.plugins.rect, - { +SVG.Element.prototype.draw.extend( + 'rect', + Object.assign({}, SVG.Element.prototype.draw.plugins.rect, { transform: transform, - }, -)); + }), +); -SVG.Element.prototype.draw.extend('polyline', Object.assign({}, - SVG.Element.prototype.draw.plugins.polyline, - { +SVG.Element.prototype.draw.extend( + 'polyline', + Object.assign({}, SVG.Element.prototype.draw.plugins.polyline, { transform: transform, - }, -)); + }), +); -SVG.Element.prototype.draw.extend('polygon', Object.assign({}, - SVG.Element.prototype.draw.plugins.polygon, - { +SVG.Element.prototype.draw.extend( + 'polygon', + Object.assign({}, SVG.Element.prototype.draw.plugins.polygon, { transform: transform, - }, -)); + }), +); // Fix method drawCircles function drawCircles(): void { @@ -108,9 +101,7 @@ function drawCircles(): void { [, this.p.y] = array[i]; const p = this.p.matrixTransform( - this.parent.node.getScreenCTM() - .inverse() - .multiply(this.el.node.getScreenCTM()), + this.parent.node.getScreenCTM().inverse().multiply(this.el.node.getScreenCTM()), ); this.set.add( @@ -118,32 +109,33 @@ function drawCircles(): void { .circle(5) .stroke({ width: 1, - }).fill('#ccc') + }) + .fill('#ccc') .center(p.x, p.y), ); } } -SVG.Element.prototype.draw.extend('line', Object.assign({}, - SVG.Element.prototype.draw.plugins.line, - { +SVG.Element.prototype.draw.extend( + 'line', + Object.assign({}, SVG.Element.prototype.draw.plugins.line, { drawCircles: drawCircles, - } -)); + }), +); -SVG.Element.prototype.draw.extend('polyline', Object.assign({}, - SVG.Element.prototype.draw.plugins.polyline, - { +SVG.Element.prototype.draw.extend( + 'polyline', + Object.assign({}, SVG.Element.prototype.draw.plugins.polyline, { drawCircles: drawCircles, - } -)); + }), +); -SVG.Element.prototype.draw.extend('polygon', Object.assign({}, - SVG.Element.prototype.draw.plugins.polygon, - { +SVG.Element.prototype.draw.extend( + 'polygon', + Object.assign({}, SVG.Element.prototype.draw.plugins.polygon, { drawCircles: drawCircles, - } -)); + }), +); // Fix method drag const originalDraggable = SVG.Element.prototype.draggable; @@ -152,10 +144,10 @@ SVG.Element.prototype.draggable = function constructor(...args: any): any { if (!handler) { originalDraggable.call(this, ...args); handler = this.remember('_draggable'); - handler.drag = function(e: any) { + handler.drag = function (e: any) { this.m = this.el.node.getScreenCTM().inverse(); return handler.constructor.prototype.drag.call(this, e); - } + }; } else { originalDraggable.call(this, ...args); } @@ -173,16 +165,16 @@ SVG.Element.prototype.resize = function constructor(...args: any): any { if (!handler) { originalResize.call(this, ...args); handler = this.remember('_resizeHandler'); - handler.resize = function(e: any) { + handler.resize = function (e: any) { const { event } = e.detail; - if (event.button === 0 && !event.shiftKey && !event.ctrlKey) { + if (event.button === 0 && !event.shiftKey && !event.altKey) { return handler.constructor.prototype.resize.call(this, e); } - } - handler.update = function(e: any) { + }; + handler.update = function (e: any) { this.m = this.el.node.getScreenCTM().inverse(); return handler.constructor.prototype.update.call(this, e); - } + }; } else { originalResize.call(this, ...args); } @@ -193,7 +185,6 @@ for (const key of Object.keys(originalResize)) { SVG.Element.prototype.resize[key] = originalResize[key]; } - enum EdgeIndex { FL = 1, FR = 2, @@ -255,14 +246,34 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { }, setupProjections() { - this.ftProj = this.line(this.updateProjectionLine(this.cuboidModel.ft.getEquation(), - this.cuboidModel.ft.points[0], this.cuboidModel.vpl)); - this.fbProj = this.line(this.updateProjectionLine(this.cuboidModel.fb.getEquation(), - this.cuboidModel.ft.points[0], this.cuboidModel.vpl)); - this.rtProj = this.line(this.updateProjectionLine(this.cuboidModel.rt.getEquation(), - this.cuboidModel.rt.points[1], this.cuboidModel.vpr)); - this.rbProj = this.line(this.updateProjectionLine(this.cuboidModel.rb.getEquation(), - this.cuboidModel.rb.points[1], this.cuboidModel.vpr)); + this.ftProj = this.line( + this.updateProjectionLine( + this.cuboidModel.ft.getEquation(), + this.cuboidModel.ft.points[0], + this.cuboidModel.vpl, + ), + ); + this.fbProj = this.line( + this.updateProjectionLine( + this.cuboidModel.fb.getEquation(), + this.cuboidModel.ft.points[0], + this.cuboidModel.vpl, + ), + ); + this.rtProj = this.line( + this.updateProjectionLine( + this.cuboidModel.rt.getEquation(), + this.cuboidModel.rt.points[1], + this.cuboidModel.vpr, + ), + ); + this.rbProj = this.line( + this.updateProjectionLine( + this.cuboidModel.rb.getEquation(), + this.cuboidModel.rb.points[1], + this.cuboidModel.vpr, + ), + ); this.ftProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections'); this.fbProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections'); @@ -308,8 +319,6 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { } else { this.drCenter.hide(); } - - }, showProjections() { @@ -358,7 +367,10 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { const x2 = direction.x; const y2 = equation.getY(x2); - return [[x1, y1], [x2, y2]]; + return [ + [x1, y1], + [x2, y2], + ]; }, selectize(value: boolean, options: object) { @@ -373,40 +385,46 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { } if (value === false) { - this.getGrabPoints().forEach((point: SVG.Element) => {point && point.remove()}); + this.getGrabPoints().forEach((point: SVG.Element) => { + point && point.remove(); + }); } else { - this.setupGrabPoints(this.face.remember('_selectHandler').drawPoint.bind( - {nested: this, options: this.face.remember('_selectHandler').options} - )); + this.setupGrabPoints( + this.face + .remember('_selectHandler') + .drawPoint.bind({ nested: this, options: this.face.remember('_selectHandler').options }), + ); // setup proper classes for selection points for proper cursor - Array.from(this.face.remember('_selectHandler').nested.node.children) - .forEach((point: SVG.LinkedHTMLElement, i: number) => { - point.classList.add(`svg_select_points_${['lt', 'lb', 'rb', 'rt'][i]}`) - }); + Array.from(this.face.remember('_selectHandler').nested.node.children).forEach( + (point: SVG.LinkedHTMLElement, i: number) => { + point.classList.add(`svg_select_points_${['lt', 'lb', 'rb', 'rt'][i]}`); + }, + ); if (this.cuboidModel.orientation === Orientation.LEFT) { - Array.from(this.dorsalRightEdge.remember('_selectHandler').nested.node.children) - .forEach((point: SVG.LinkedHTMLElement, i: number) => { - point.classList.add(`svg_select_points_${['t', 'b'][i]}`); - point.ondblclick = (e: MouseEvent) => { - if (e.shiftKey) { - this.resetPerspective() - } - }; - }); + Array.from(this.dorsalRightEdge.remember('_selectHandler').nested.node.children).forEach( + (point: SVG.LinkedHTMLElement, i: number) => { + point.classList.add(`svg_select_points_${['t', 'b'][i]}`); + point.ondblclick = (e: MouseEvent) => { + if (e.shiftKey) { + this.resetPerspective(); + } + }; + }, + ); } else { - Array.from(this.dorsalLeftEdge.remember('_selectHandler').nested.node.children) - .forEach((point: SVG.LinkedHTMLElement, i: number) => { - point.classList.add(`svg_select_points_${['t', 'b'][i]}`); - point.ondblclick = (e: MouseEvent) => { - if (e.shiftKey) { - this.resetPerspective() - } - }; - }); + Array.from(this.dorsalLeftEdge.remember('_selectHandler').nested.node.children).forEach( + (point: SVG.LinkedHTMLElement, i: number) => { + point.classList.add(`svg_select_points_${['t', 'b'][i]}`); + point.ondblclick = (e: MouseEvent) => { + if (e.shiftKey) { + this.resetPerspective(); + } + }; + }, + ); } - } return this; @@ -428,7 +446,7 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { point.off('dragmove'); point.off('dragend'); } - }) + }); return; } @@ -436,9 +454,7 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { function getResizedPointIndex(event: CustomEvent): number { const { target } = event.detail.event.detail.event; const { parentElement } = target; - return Array - .from(parentElement.children) - .indexOf(target); + return Array.from(parentElement.children).indexOf(target); } let resizedCubePoint: null | number = null; @@ -447,65 +463,69 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { y: 0, }; - this.face.on('resizestart', (event: CustomEvent) => { - accumulatedOffset.x = 0; - accumulatedOffset.y = 0; - const resizedFacePoint = getResizedPointIndex(event); - resizedCubePoint = [0, 1].includes(resizedFacePoint) ? resizedFacePoint - : 5 - resizedFacePoint; // 2,3 -> 3,2 - this.fire(new CustomEvent('resizestart', event)); - }).on('resizing', (event: CustomEvent) => { - let { dx, dy } = event.detail; - let dxPortion = dx - accumulatedOffset.x; - let dyPortion = dy - accumulatedOffset.y; - accumulatedOffset.x += dxPortion; - accumulatedOffset.y += dyPortion; - - const edge = getEdgeIndex(resizedCubePoint); - const [edgeTopIndex, edgeBottomIndex] = getTopDown(edge); - - let cuboidPoints = this.cuboidModel.getPoints(); - let x1 = cuboidPoints[edgeTopIndex].x + dxPortion; - let x2 = cuboidPoints[edgeBottomIndex].x + dxPortion; - if (edge === EdgeIndex.FL - && (cuboidPoints[2].x - (cuboidPoints[0].x + dxPortion) < consts.MIN_EDGE_LENGTH) - ) { - x1 = cuboidPoints[edgeTopIndex].x; - x2 = cuboidPoints[edgeBottomIndex].x; - } else if (edge === EdgeIndex.FR - && (cuboidPoints[2].x + dxPortion - cuboidPoints[0].x < consts.MIN_EDGE_LENGTH) - ) { - x1 = cuboidPoints[edgeTopIndex].x; - x2 = cuboidPoints[edgeBottomIndex].x; - } - const y1 = this.cuboidModel.ft.getEquation().getY(x1); - const y2 = this.cuboidModel.fb.getEquation().getY(x2); - const topPoint = { x: x1, y: y1 }; - const botPoint = { x: x2, y: y2 }; - if (edge === 1) { - this.cuboidModel.fl.points = [topPoint, botPoint]; - } else { - this.cuboidModel.fr.points = [topPoint, botPoint]; - } - this.updateViewAndVM(edge === EdgeIndex.FR); - - cuboidPoints = this.cuboidModel.getPoints(); - const midPointUp = { ...cuboidPoints[edgeTopIndex] }; - const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; - (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; - if (midPointDown.y - midPointUp.y > consts.MIN_EDGE_LENGTH) { - const topPoints = this.computeHeightFace(midPointUp, edge); - const bottomPoints = this.computeHeightFace(midPointDown, edge); - this.cuboidModel.top.points = topPoints; - this.cuboidModel.bot.points = bottomPoints; - this.updateViewAndVM(false); - } + this.face + .on('resizestart', (event: CustomEvent) => { + accumulatedOffset.x = 0; + accumulatedOffset.y = 0; + const resizedFacePoint = getResizedPointIndex(event); + resizedCubePoint = [0, 1].includes(resizedFacePoint) ? resizedFacePoint : 5 - resizedFacePoint; // 2,3 -> 3,2 + this.fire(new CustomEvent('resizestart', event)); + }) + .on('resizing', (event: CustomEvent) => { + let { dx, dy } = event.detail; + let dxPortion = dx - accumulatedOffset.x; + let dyPortion = dy - accumulatedOffset.y; + accumulatedOffset.x += dxPortion; + accumulatedOffset.y += dyPortion; - this.face.plot(this.cuboidModel.front.points); - this.fire(new CustomEvent('resizing', event)); - }).on('resizedone', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + const edge = getEdgeIndex(resizedCubePoint); + const [edgeTopIndex, edgeBottomIndex] = getTopDown(edge); + + let cuboidPoints = this.cuboidModel.getPoints(); + let x1 = cuboidPoints[edgeTopIndex].x + dxPortion; + let x2 = cuboidPoints[edgeBottomIndex].x + dxPortion; + if ( + edge === EdgeIndex.FL && + cuboidPoints[2].x - (cuboidPoints[0].x + dxPortion) < consts.MIN_EDGE_LENGTH + ) { + x1 = cuboidPoints[edgeTopIndex].x; + x2 = cuboidPoints[edgeBottomIndex].x; + } else if ( + edge === EdgeIndex.FR && + cuboidPoints[2].x + dxPortion - cuboidPoints[0].x < consts.MIN_EDGE_LENGTH + ) { + x1 = cuboidPoints[edgeTopIndex].x; + x2 = cuboidPoints[edgeBottomIndex].x; + } + const y1 = this.cuboidModel.ft.getEquation().getY(x1); + const y2 = this.cuboidModel.fb.getEquation().getY(x2); + const topPoint = { x: x1, y: y1 }; + const botPoint = { x: x2, y: y2 }; + if (edge === 1) { + this.cuboidModel.fl.points = [topPoint, botPoint]; + } else { + this.cuboidModel.fr.points = [topPoint, botPoint]; + } + this.updateViewAndVM(edge === EdgeIndex.FR); + + cuboidPoints = this.cuboidModel.getPoints(); + const midPointUp = { ...cuboidPoints[edgeTopIndex] }; + const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; + (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; + if (midPointDown.y - midPointUp.y > consts.MIN_EDGE_LENGTH) { + const topPoints = this.computeHeightFace(midPointUp, edge); + const bottomPoints = this.computeHeightFace(midPointDown, edge); + this.cuboidModel.top.points = topPoints; + this.cuboidModel.bot.points = bottomPoints; + this.updateViewAndVM(false); + } + + this.face.plot(this.cuboidModel.front.points); + this.fire(new CustomEvent('resizing', event)); + }) + .on('resizedone', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); function computeSideEdgeConstraints(edge: Edge, fr: Edge) { const midLength = fr.points[1].y - fr.points[0].y - 1; @@ -544,45 +564,47 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { accumulatedOffset.y = 0; resizedCubePoint = getResizedPointIndex(event) + (orientation === Orientation.LEFT ? 4 : 6); this.fire(new CustomEvent('resizestart', event)); - }).on('resizing', (event: CustomEvent) => { - let { dy } = event.detail; - let dyPortion = dy - accumulatedOffset.y; - accumulatedOffset.y += dyPortion; - - const edge = getEdgeIndex(resizedCubePoint); - const [edgeTopIndex, edgeBottomIndex] = getTopDown(edge); - let cuboidPoints = this.cuboidModel.getPoints(); - - if (!event.detail.event.shiftKey) { - cuboidPoints = this.cuboidModel.getPoints(); - const midPointUp = { ...cuboidPoints[edgeTopIndex] }; - const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; - (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; - if (midPointDown.y - midPointUp.y > consts.MIN_EDGE_LENGTH) { - const topPoints = this.computeHeightFace(midPointUp, edge); - const bottomPoints = this.computeHeightFace(midPointDown, edge); - this.cuboidModel.top.points = topPoints; - this.cuboidModel.bot.points = bottomPoints; + }) + .on('resizing', (event: CustomEvent) => { + let { dy } = event.detail; + let dyPortion = dy - accumulatedOffset.y; + accumulatedOffset.y += dyPortion; + + const edge = getEdgeIndex(resizedCubePoint); + const [edgeTopIndex, edgeBottomIndex] = getTopDown(edge); + let cuboidPoints = this.cuboidModel.getPoints(); + + if (!event.detail.event.shiftKey) { + cuboidPoints = this.cuboidModel.getPoints(); + const midPointUp = { ...cuboidPoints[edgeTopIndex] }; + const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; + (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; + if (midPointDown.y - midPointUp.y > consts.MIN_EDGE_LENGTH) { + const topPoints = this.computeHeightFace(midPointUp, edge); + const bottomPoints = this.computeHeightFace(midPointDown, edge); + this.cuboidModel.top.points = topPoints; + this.cuboidModel.bot.points = bottomPoints; + } + } else { + const midPointUp = { ...cuboidPoints[edgeTopIndex] }; + const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; + (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; + const dorselEdge = + orientation === Orientation.LEFT ? this.cuboidModel.dr : this.cuboidModel.dl; + const constraints = computeSideEdgeConstraints(dorselEdge, this.cuboidModel.fr); + midPointUp.y = clamp(midPointUp.y, constraints.y1Range.min, constraints.y1Range.max); + midPointDown.y = clamp(midPointDown.y, constraints.y2Range.min, constraints.y2Range.max); + dorselEdge.points = [midPointUp, midPointDown]; + this.updateViewAndVM(edge === EdgeIndex.DL); } - } else { - const midPointUp = { ...cuboidPoints[edgeTopIndex] }; - const midPointDown = { ...cuboidPoints[edgeBottomIndex] }; - (edgeTopIndex === resizedCubePoint ? midPointUp : midPointDown).y += dyPortion; - const dorselEdge = (orientation === Orientation.LEFT ? this.cuboidModel.dr : this.cuboidModel.dl); - const constraints = computeSideEdgeConstraints(dorselEdge, this.cuboidModel.fr); - midPointUp.y = clamp(midPointUp.y, constraints.y1Range.min, constraints.y1Range.max); - midPointDown.y = clamp(midPointDown.y, constraints.y2Range.min, constraints.y2Range.max); - dorselEdge.points = [midPointUp, midPointDown]; - this.updateViewAndVM(edge === EdgeIndex.DL); - } - - this.updateViewAndVM(false); - this.face.plot(this.cuboidModel.front.points); - this.fire(new CustomEvent('resizing', event)); - }).on('resizedone', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + this.updateViewAndVM(false); + this.face.plot(this.cuboidModel.front.points); + this.fire(new CustomEvent('resizing', event)); + }) + .on('resizedone', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); } if (this.cuboidModel.orientation === Orientation.LEFT) { @@ -596,149 +618,185 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { function horizontalEdgeControl(updatingFace: any, midX: number, midY: number) { const leftPoints = this.updatedEdge( this.cuboidModel.fl.points[0], - {x: midX, y: midY}, + { x: midX, y: midY }, this.cuboidModel.vpl, ); const rightPoints = this.updatedEdge( this.cuboidModel.dr.points[0], - {x: midX, y: midY}, + { x: midX, y: midY }, this.cuboidModel.vpr, ); - updatingFace.points = [leftPoints, {x: midX, y: midY}, rightPoints, null]; + updatingFace.points = [leftPoints, { x: midX, y: midY }, rightPoints, null]; } + this.drCenter + .draggable((x: number) => { + let xStatus; + if (this.drCenter.cx() < this.cuboidModel.fr.points[0].x) { + xStatus = + x < this.cuboidModel.fr.points[0].x - consts.MIN_EDGE_LENGTH && + x > this.cuboidModel.vpr.x + consts.MIN_EDGE_LENGTH; + } else { + xStatus = + x > this.cuboidModel.fr.points[0].x + consts.MIN_EDGE_LENGTH && + x < this.cuboidModel.vpr.x - consts.MIN_EDGE_LENGTH; + } + return { x: xStatus, y: this.drCenter.attr('y1') }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.dorsalRightEdge.center(this.drCenter.cx(), this.drCenter.cy()); - this.drCenter.draggable((x: number) => { - let xStatus; - if (this.drCenter.cx() < this.cuboidModel.fr.points[0].x) { - xStatus = x < this.cuboidModel.fr.points[0].x - consts.MIN_EDGE_LENGTH - && x > this.cuboidModel.vpr.x + consts.MIN_EDGE_LENGTH; - } else { - xStatus = x > this.cuboidModel.fr.points[0].x + consts.MIN_EDGE_LENGTH - && x < this.cuboidModel.vpr.x - consts.MIN_EDGE_LENGTH; - } - return { x: xStatus, y: this.drCenter.attr('y1') }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.dorsalRightEdge.center(this.drCenter.cx(), this.drCenter.cy()); - - const x = this.dorsalRightEdge.attr('x1'); - const y1 = this.cuboidModel.rt.getEquation().getY(x); - const y2 = this.cuboidModel.rb.getEquation().getY(x); - const topPoint = { x, y: y1 }; - const botPoint = { x, y: y2 }; - - this.cuboidModel.dr.points = [topPoint, botPoint]; - this.updateViewAndVM(); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + const x = this.dorsalRightEdge.attr('x1'); + const y1 = this.cuboidModel.rt.getEquation().getY(x); + const y2 = this.cuboidModel.rb.getEquation().getY(x); + const topPoint = { x, y: y1 }; + const botPoint = { x, y: y2 }; - this.dlCenter.draggable((x: number) => { - let xStatus; - if (this.dlCenter.cx() < this.cuboidModel.fl.points[0].x) { - xStatus = x < this.cuboidModel.fl.points[0].x - consts.MIN_EDGE_LENGTH - && x > this.cuboidModel.vpr.x + consts.MIN_EDGE_LENGTH; - } else { - xStatus = x > this.cuboidModel.fl.points[0].x + consts.MIN_EDGE_LENGTH - && x < this.cuboidModel.vpr.x - consts.MIN_EDGE_LENGTH; - } - return { x: xStatus, y: this.dlCenter.attr('y1') }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.dorsalLeftEdge.center(this.dlCenter.cx(), this.dlCenter.cy()); - - const x = this.dorsalLeftEdge.attr('x1'); - const y1 = this.cuboidModel.lt.getEquation().getY(x); - const y2 = this.cuboidModel.lb.getEquation().getY(x); - const topPoint = { x, y: y1 }; - const botPoint = { x, y: y2 }; - - this.cuboidModel.dl.points = [topPoint, botPoint]; - this.updateViewAndVM(true); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - });; - - this.flCenter.draggable((x: number) => { - const vpX = this.flCenter.cx() - this.cuboidModel.vpl.x > 0 ? this.cuboidModel.vpl.x : 0; - return { x: x < this.cuboidModel.fr.points[0].x && x > vpX + consts.MIN_EDGE_LENGTH }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.frontLeftEdge.center(this.flCenter.cx(), this.flCenter.cy()); - - const x = this.frontLeftEdge.attr('x1'); - const y1 = this.cuboidModel.ft.getEquation().getY(x); - const y2 = this.cuboidModel.fb.getEquation().getY(x); - const topPoint = { x, y: y1 }; - const botPoint = { x, y: y2 }; - - this.cuboidModel.fl.points = [topPoint, botPoint]; - this.updateViewAndVM(); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + this.cuboidModel.dr.points = [topPoint, botPoint]; + this.updateViewAndVM(); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); - this.frCenter.draggable((x: number) => { - return { x: x > this.cuboidModel.fl.points[0].x, y: this.frCenter.attr('y1') }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.frontRightEdge.center(this.frCenter.cx(), this.frCenter.cy()); + this.dlCenter + .draggable((x: number) => { + let xStatus; + if (this.dlCenter.cx() < this.cuboidModel.fl.points[0].x) { + xStatus = + x < this.cuboidModel.fl.points[0].x - consts.MIN_EDGE_LENGTH && + x > this.cuboidModel.vpr.x + consts.MIN_EDGE_LENGTH; + } else { + xStatus = + x > this.cuboidModel.fl.points[0].x + consts.MIN_EDGE_LENGTH && + x < this.cuboidModel.vpr.x - consts.MIN_EDGE_LENGTH; + } + return { x: xStatus, y: this.dlCenter.attr('y1') }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.dorsalLeftEdge.center(this.dlCenter.cx(), this.dlCenter.cy()); - const x = this.frontRightEdge.attr('x1'); - const y1 = this.cuboidModel.ft.getEquation().getY(x); - const y2 = this.cuboidModel.fb.getEquation().getY(x); - const topPoint = { x, y: y1 }; - const botPoint = { x, y: y2 }; + const x = this.dorsalLeftEdge.attr('x1'); + const y1 = this.cuboidModel.lt.getEquation().getY(x); + const y2 = this.cuboidModel.lb.getEquation().getY(x); + const topPoint = { x, y: y1 }; + const botPoint = { x, y: y2 }; - this.cuboidModel.fr.points = [topPoint, botPoint]; - this.updateViewAndVM(true); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + this.cuboidModel.dl.points = [topPoint, botPoint]; + this.updateViewAndVM(true); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); - this.ftCenter.draggable((x: number, y: number) => { - return { x: x === this.ftCenter.cx(), y: y < this.fbCenter.cy() - consts.MIN_EDGE_LENGTH }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.frontTopEdge.center(this.ftCenter.cx(), this.ftCenter.cy()); - horizontalEdgeControl.call(this, this.cuboidModel.top, this.frontTopEdge.attr('x2'), this.frontTopEdge.attr('y2')); - this.updateViewAndVM(); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + this.flCenter + .draggable((x: number) => { + const vpX = this.flCenter.cx() - this.cuboidModel.vpl.x > 0 ? this.cuboidModel.vpl.x : 0; + return { x: x < this.cuboidModel.fr.points[0].x && x > vpX + consts.MIN_EDGE_LENGTH }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.frontLeftEdge.center(this.flCenter.cx(), this.flCenter.cy()); - this.fbCenter.draggable((x: number, y: number) => { - return { x: x === this.fbCenter.cx(), y: y > this.ftCenter.cy() + consts.MIN_EDGE_LENGTH }; - }).on('dragstart', ((event: CustomEvent) => { - this.fire(new CustomEvent('resizestart', event)); - })).on('dragmove', (event: CustomEvent) => { - this.frontBotEdge.center(this.fbCenter.cx(), this.fbCenter.cy()); - horizontalEdgeControl.call(this, this.cuboidModel.bot, this.frontBotEdge.attr('x2'), this.frontBotEdge.attr('y2')); - this.updateViewAndVM(); - this.fire(new CustomEvent('resizing', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('resizedone', event)); - }); + const x = this.frontLeftEdge.attr('x1'); + const y1 = this.cuboidModel.ft.getEquation().getY(x); + const y2 = this.cuboidModel.fb.getEquation().getY(x); + const topPoint = { x, y: y1 }; + const botPoint = { x, y: y2 }; + + this.cuboidModel.fl.points = [topPoint, botPoint]; + this.updateViewAndVM(); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); + this.frCenter + .draggable((x: number) => { + return { x: x > this.cuboidModel.fl.points[0].x, y: this.frCenter.attr('y1') }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.frontRightEdge.center(this.frCenter.cx(), this.frCenter.cy()); + + const x = this.frontRightEdge.attr('x1'); + const y1 = this.cuboidModel.ft.getEquation().getY(x); + const y2 = this.cuboidModel.fb.getEquation().getY(x); + const topPoint = { x, y: y1 }; + const botPoint = { x, y: y2 }; + + this.cuboidModel.fr.points = [topPoint, botPoint]; + this.updateViewAndVM(true); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); + + this.ftCenter + .draggable((x: number, y: number) => { + return { x: x === this.ftCenter.cx(), y: y < this.fbCenter.cy() - consts.MIN_EDGE_LENGTH }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.frontTopEdge.center(this.ftCenter.cx(), this.ftCenter.cy()); + horizontalEdgeControl.call( + this, + this.cuboidModel.top, + this.frontTopEdge.attr('x2'), + this.frontTopEdge.attr('y2'), + ); + this.updateViewAndVM(); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); + + this.fbCenter + .draggable((x: number, y: number) => { + return { x: x === this.fbCenter.cx(), y: y > this.ftCenter.cy() + consts.MIN_EDGE_LENGTH }; + }) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('resizestart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.frontBotEdge.center(this.fbCenter.cx(), this.fbCenter.cy()); + horizontalEdgeControl.call( + this, + this.cuboidModel.bot, + this.frontBotEdge.attr('x2'), + this.frontBotEdge.attr('y2'), + ); + this.updateViewAndVM(); + this.fire(new CustomEvent('resizing', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('resizedone', event)); + }); return this; }, draggable(value: any, constraint: any) { const { cuboidModel } = this; - const faces = [this.face, this.right, this.dorsal, this.left] + const faces = [this.face, this.right, this.dorsal, this.left]; const accumulatedOffset: Point = { x: 0, y: 0, @@ -750,69 +808,84 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { face.off('dragstart'); face.off('dragmove'); face.off('dragend'); - }) - return + }); + return; } - this.face.draggable().on('dragstart', (event: CustomEvent) => { - accumulatedOffset.x = 0; - accumulatedOffset.y = 0; - - this.fire(new CustomEvent('dragstart', event)); - }).on('dragmove', (event: CustomEvent) => { - const dx = event.detail.p.x - event.detail.handler.startPoints.point.x; - const dy = event.detail.p.y - event.detail.handler.startPoints.point.y; - let dxPortion = dx - accumulatedOffset.x; - let dyPortion = dy - accumulatedOffset.y; - accumulatedOffset.x += dxPortion; - accumulatedOffset.y += dyPortion; - - this.dmove(dxPortion, dyPortion); - - this.fire(new CustomEvent('dragmove', event)); - }).on('dragend', (event: CustomEvent) => { - - this.fire(new CustomEvent('dragend', event)); - }) - - this.left.draggable((x: number, y: number) => ({ - x: x < Math.min(cuboidModel.dr.points[0].x, - cuboidModel.fr.points[0].x) - consts.MIN_EDGE_LENGTH, y - })).on('dragstart', (event: CustomEvent) => { - this.fire(new CustomEvent('dragstart', event)); - }).on('dragmove', (event: CustomEvent) => { - this.cuboidModel.left.points = parsePoints(this.left.attr('points')); - this.updateViewAndVM(); + this.face + .draggable() + .on('dragstart', (event: CustomEvent) => { + accumulatedOffset.x = 0; + accumulatedOffset.y = 0; - this.fire(new CustomEvent('dragmove', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('dragend', event)); - }); + this.fire(new CustomEvent('dragstart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + const dx = event.detail.p.x - event.detail.handler.startPoints.point.x; + const dy = event.detail.p.y - event.detail.handler.startPoints.point.y; + let dxPortion = dx - accumulatedOffset.x; + let dyPortion = dy - accumulatedOffset.y; + accumulatedOffset.x += dxPortion; + accumulatedOffset.y += dyPortion; - this.dorsal.draggable().on('dragstart', (event: CustomEvent) => { - this.fire(new CustomEvent('dragstart', event)); - }).on('dragmove', (event: CustomEvent) => { - this.cuboidModel.dorsal.points = parsePoints(this.dorsal.attr('points')); - this.updateViewAndVM(); + this.dmove(dxPortion, dyPortion); - this.fire(new CustomEvent('dragmove', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('dragend', event)); - }); + this.fire(new CustomEvent('dragmove', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('dragend', event)); + }); - this.right.draggable((x: number, y: number) => ({ - x: x > Math.min(cuboidModel.dl.points[0].x, - cuboidModel.fl.points[0].x) + consts.MIN_EDGE_LENGTH, y - })).on('dragstart', (event: CustomEvent) => { - this.fire(new CustomEvent('dragstart', event)); - }).on('dragmove', (event: CustomEvent) => { - this.cuboidModel.right.points = parsePoints(this.right.attr('points')); - this.updateViewAndVM(true); + this.left + .draggable((x: number, y: number) => ({ + x: x < Math.min(cuboidModel.dr.points[0].x, cuboidModel.fr.points[0].x) - consts.MIN_EDGE_LENGTH, + y, + })) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('dragstart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.cuboidModel.left.points = parsePoints(this.left.attr('points')); + this.updateViewAndVM(); - this.fire(new CustomEvent('dragmove', event)); - }).on('dragend', (event: CustomEvent) => { - this.fire(new CustomEvent('dragend', event)); - }); + this.fire(new CustomEvent('dragmove', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('dragend', event)); + }); + + this.dorsal + .draggable() + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('dragstart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.cuboidModel.dorsal.points = parsePoints(this.dorsal.attr('points')); + this.updateViewAndVM(); + + this.fire(new CustomEvent('dragmove', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('dragend', event)); + }); + + this.right + .draggable((x: number, y: number) => ({ + x: x > Math.min(cuboidModel.dl.points[0].x, cuboidModel.fl.points[0].x) + consts.MIN_EDGE_LENGTH, + y, + })) + .on('dragstart', (event: CustomEvent) => { + this.fire(new CustomEvent('dragstart', event)); + }) + .on('dragmove', (event: CustomEvent) => { + this.cuboidModel.right.points = parsePoints(this.right.attr('points')); + this.updateViewAndVM(true); + + this.fire(new CustomEvent('dragmove', event)); + }) + .on('dragend', (event: CustomEvent) => { + this.fire(new CustomEvent('dragend', event)); + }); return this; }, @@ -820,8 +893,7 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { _attr: SVG.Element.prototype.attr, attr(a: any, v: any, n: any) { - if ((a === 'fill' || a === 'stroke' || a === 'face-stroke') - && v !== undefined) { + if ((a === 'fill' || a === 'stroke' || a === 'face-stroke') && v !== undefined) { this._attr(a, v, n); this.paintOrientationLines(); } else if (a === 'points' && typeof v === 'string') { @@ -841,22 +913,25 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { this.rtProj.hide(); this.rbProj.hide(); } - } else if (a === 'stroke-width' && typeof v === "number") { + } else if (a === 'stroke-width' && typeof v === 'number') { this._attr(a, v, n); this.updateThickness(); } else if (a === 'data-z-order' && typeof v !== 'undefined') { this._attr(a, v, n); - [this.face, this.left, this.dorsal, this.right, ...this.getEdges(), ...this.getGrabPoints()] - .forEach((el) => {if (el) el.attr(a, v, n)}) + [this.face, this.left, this.dorsal, this.right, ...this.getEdges(), ...this.getGrabPoints()].forEach( + (el) => { + if (el) el.attr(a, v, n); + }, + ); } else { - return this._attr(a ,v, n); + return this._attr(a, v, n); } return this; }, updateThickness() { - const edges = [this.frontLeftEdge, this.frontRightEdge, this.frontTopEdge, this.frontBotEdge] + const edges = [this.frontLeftEdge, this.frontRightEdge, this.frontTopEdge, this.frontBotEdge]; const width = this.attr('stroke-width'); edges.forEach((edge: SVG.Element) => { edge.attr('stroke-width', width * (this.strokeOffset || consts.CUBOID_UNACTIVE_EDGE_STROKE_WIDTH)); @@ -864,14 +939,15 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { this.on('mouseover', () => { edges.forEach((edge: SVG.Element) => { this.strokeOffset = this.node.classList.contains('cvat_canvas_shape_activated') - ? consts.CUBOID_ACTIVE_EDGE_STROKE_WIDTH : consts.CUBOID_UNACTIVE_EDGE_STROKE_WIDTH; + ? consts.CUBOID_ACTIVE_EDGE_STROKE_WIDTH + : consts.CUBOID_UNACTIVE_EDGE_STROKE_WIDTH; edge.attr('stroke-width', width * this.strokeOffset); - }) + }); }).on('mouseout', () => { edges.forEach((edge: SVG.Element) => { this.strokeOffset = consts.CUBOID_UNACTIVE_EDGE_STROKE_WIDTH; edge.attr('stroke-width', width * this.strokeOffset); - }) + }); }); }, @@ -889,18 +965,12 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { this.dorsalRightEdge.stroke({ color: strokeColor }); this.dorsalLeftEdge.stroke({ color: strokeColor }); - this.bot.stroke({ color: strokeColor }) - .fill({ color: fillColor }); - this.top.stroke({ color: strokeColor }) - .fill({ color: fillColor }); - this.face.stroke({ color: strokeColor, width: 0 }) - .fill({ color: fillColor }); - this.right.stroke({ color: strokeColor }) - .fill({ color: fillColor }); - this.dorsal.stroke({ color: strokeColor }) - .fill({ color: fillColor }); - this.left.stroke({ color: strokeColor }) - .fill({ color: fillColor }); + this.bot.stroke({ color: strokeColor }).fill({ color: fillColor }); + this.top.stroke({ color: strokeColor }).fill({ color: fillColor }); + this.face.stroke({ color: strokeColor, width: 0 }).fill({ color: fillColor }); + this.right.stroke({ color: strokeColor }).fill({ color: fillColor }); + this.dorsal.stroke({ color: strokeColor }).fill({ color: fillColor }); + this.left.stroke({ color: strokeColor }).fill({ color: fillColor }); }, dmove(dx: number, dy: number) { @@ -932,18 +1002,18 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { } }, - resetPerspective(){ + resetPerspective() { if (this.cuboidModel.orientation === Orientation.LEFT) { const edgePoints = this.cuboidModel.dl.points; const constraints = this.cuboidModel.computeSideEdgeConstraints(this.cuboidModel.dl); edgePoints[0].y = constraints.y1Range.min; - this.cuboidModel.dl.points = [edgePoints[0],edgePoints[1]]; + this.cuboidModel.dl.points = [edgePoints[0], edgePoints[1]]; this.updateViewAndVM(true); } else { const edgePoints = this.cuboidModel.dr.points; const constraints = this.cuboidModel.computeSideEdgeConstraints(this.cuboidModel.dr); edgePoints[0].y = constraints.y1Range.min; - this.cuboidModel.dr.points = [edgePoints[0],edgePoints[1]]; + this.cuboidModel.dr.points = [edgePoints[0], edgePoints[1]]; this.updateViewAndVM(); } }, @@ -954,44 +1024,48 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { this.updateView(); // to correct getting of points in resizedone, dragdone - this._attr('points', this.cuboidModel - .getPoints() - .reduce((acc: string, point: Point): string => `${acc} ${point.x},${point.y}`, '').trim()); + this._attr( + 'points', + this.cuboidModel + .getPoints() + .reduce((acc: string, point: Point): string => `${acc} ${point.x},${point.y}`, '') + .trim(), + ); }, computeHeightFace(point: Point, index: number) { switch (index) { - // fl - case 1: { - const p2 = this.updatedEdge(this.cuboidModel.fr.points[0], point, this.cuboidModel.vpl); - const p3 = this.updatedEdge(this.cuboidModel.dr.points[0], p2, this.cuboidModel.vpr); - const p4 = this.updatedEdge(this.cuboidModel.dl.points[0], point, this.cuboidModel.vpr); - return [point, p2, p3, p4]; - } - // fr - case 2: { - const p1 = this.updatedEdge(this.cuboidModel.fl.points[0], point, this.cuboidModel.vpl); - const p3 = this.updatedEdge(this.cuboidModel.dr.points[0], point, this.cuboidModel.vpr); - const p4 = this.updatedEdge(this.cuboidModel.dl.points[0], p3, this.cuboidModel.vpr); - return [p1, point, p3, p4]; - } - // dr - case 3: { - const p2 = this.updatedEdge(this.cuboidModel.dl.points[0], point, this.cuboidModel.vpl); - const p3 = this.updatedEdge(this.cuboidModel.fr.points[0], point, this.cuboidModel.vpr); - const p4 = this.updatedEdge(this.cuboidModel.fl.points[0], p2, this.cuboidModel.vpr); - return [p4, p3, point, p2]; - } - // dl - case 4: { - const p2 = this.updatedEdge(this.cuboidModel.dr.points[0], point, this.cuboidModel.vpl); - const p3 = this.updatedEdge(this.cuboidModel.fl.points[0], point, this.cuboidModel.vpr); - const p4 = this.updatedEdge(this.cuboidModel.fr.points[0], p2, this.cuboidModel.vpr); - return [p3, p4, p2, point]; - } - default: { - return [null, null, null, null]; - } + // fl + case 1: { + const p2 = this.updatedEdge(this.cuboidModel.fr.points[0], point, this.cuboidModel.vpl); + const p3 = this.updatedEdge(this.cuboidModel.dr.points[0], p2, this.cuboidModel.vpr); + const p4 = this.updatedEdge(this.cuboidModel.dl.points[0], point, this.cuboidModel.vpr); + return [point, p2, p3, p4]; + } + // fr + case 2: { + const p1 = this.updatedEdge(this.cuboidModel.fl.points[0], point, this.cuboidModel.vpl); + const p3 = this.updatedEdge(this.cuboidModel.dr.points[0], point, this.cuboidModel.vpr); + const p4 = this.updatedEdge(this.cuboidModel.dl.points[0], p3, this.cuboidModel.vpr); + return [p1, point, p3, p4]; + } + // dr + case 3: { + const p2 = this.updatedEdge(this.cuboidModel.dl.points[0], point, this.cuboidModel.vpl); + const p3 = this.updatedEdge(this.cuboidModel.fr.points[0], point, this.cuboidModel.vpr); + const p4 = this.updatedEdge(this.cuboidModel.fl.points[0], p2, this.cuboidModel.vpr); + return [p4, p3, point, p2]; + } + // dl + case 4: { + const p2 = this.updatedEdge(this.cuboidModel.dr.points[0], point, this.cuboidModel.vpl); + const p3 = this.updatedEdge(this.cuboidModel.fl.points[0], point, this.cuboidModel.vpr); + const p4 = this.updatedEdge(this.cuboidModel.fr.points[0], p2, this.cuboidModel.vpr); + return [p3, p4, p2, point]; + } + default: { + return [null, null, null, null]; + } } }, @@ -1037,14 +1111,18 @@ function getTopDown(edgeIndex: EdgeIndex): number[] { updateProjections() { const viewModel = this.cuboidModel; - this.ftProj.plot(this.updateProjectionLine(viewModel.ft.getEquation(), - viewModel.ft.points[0], viewModel.vpl)); - this.fbProj.plot(this.updateProjectionLine(viewModel.fb.getEquation(), - viewModel.ft.points[0], viewModel.vpl)); - this.rtProj.plot(this.updateProjectionLine(viewModel.rt.getEquation(), - viewModel.rt.points[1], viewModel.vpr)); - this.rbProj.plot(this.updateProjectionLine(viewModel.rb.getEquation(), - viewModel.rt.points[1], viewModel.vpr)); + this.ftProj.plot( + this.updateProjectionLine(viewModel.ft.getEquation(), viewModel.ft.points[0], viewModel.vpl), + ); + this.fbProj.plot( + this.updateProjectionLine(viewModel.fb.getEquation(), viewModel.ft.points[0], viewModel.vpl), + ); + this.rtProj.plot( + this.updateProjectionLine(viewModel.rt.getEquation(), viewModel.rt.points[1], viewModel.vpr), + ); + this.rbProj.plot( + this.updateProjectionLine(viewModel.rb.getEquation(), viewModel.rt.points[1], viewModel.vpr), + ); }, updateGrabPoints() { diff --git a/cvat-canvas/src/typescript/zoomHandler.ts b/cvat-canvas/src/typescript/zoomHandler.ts index 1df36185..219a20f4 100644 --- a/cvat-canvas/src/typescript/zoomHandler.ts +++ b/cvat-canvas/src/typescript/zoomHandler.ts @@ -5,14 +5,9 @@ import * as SVG from 'svg.js'; import consts from './consts'; -import { - translateToSVG, -} from './shared'; - -import { - Geometry, -} from './canvasModel'; +import { translateToSVG } from './shared'; +import { Geometry } from './canvasModel'; export interface ZoomHandler { zoom(): void; @@ -35,10 +30,7 @@ export class ZoomHandlerImpl implements ZoomHandler { private onSelectStart(event: MouseEvent): void { if (!this.selectionRect && event.which === 1) { - const point = translateToSVG( - (this.canvas.node as any as SVGSVGElement), - [event.clientX, event.clientY], - ); + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); this.startSelectionPoint = { x: point[0], y: point[1], @@ -52,16 +44,15 @@ export class ZoomHandlerImpl implements ZoomHandler { } } - private getSelectionBox(event: MouseEvent): { + private getSelectionBox( + event: MouseEvent, + ): { x: number; y: number; width: number; height: number; } { - const point = translateToSVG( - (this.canvas.node as any as SVGSVGElement), - [event.clientX, event.clientY], - ); + const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); const stopSelectionPoint = { x: point[0], y: point[1], diff --git a/cvat-canvas/tsconfig.json b/cvat-canvas/tsconfig.json index b83cdaf9..5b715493 100644 --- a/cvat-canvas/tsconfig.json +++ b/cvat-canvas/tsconfig.json @@ -1,21 +1,19 @@ { - "compilerOptions": { - "baseUrl": ".", - "emitDeclarationOnly": true, - "module": "es6", - "target": "es6", - "noImplicitAny": true, - "preserveConstEnums": true, - "declaration": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "moduleResolution": "node", - "declarationDir": "dist/declaration", - "paths": { - "cvat-canvas.node": ["dist/cvat-canvas.node"] - } - }, - "include": [ - "src/typescript/*.ts" - ] + "compilerOptions": { + "baseUrl": ".", + "emitDeclarationOnly": true, + "module": "es6", + "target": "es6", + "noImplicitAny": true, + "preserveConstEnums": true, + "declaration": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "moduleResolution": "node", + "declarationDir": "dist/declaration", + "paths": { + "cvat-canvas.node": ["dist/cvat-canvas.node"] + } + }, + "include": ["src/typescript/*.ts"] } diff --git a/cvat-canvas/webpack.config.js b/cvat-canvas/webpack.config.js index 96723247..0b414c96 100644 --- a/cvat-canvas/webpack.config.js +++ b/cvat-canvas/webpack.config.js @@ -1,11 +1,12 @@ -/* - * Copyright (C) 2019 Intel Corporation - * SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT -/* eslint-disable */ +// eslint-disable-next-line @typescript-eslint/no-var-requires const path = require('path'); -const DtsBundleWebpack = require('dts-bundle-webpack') + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const DtsBundleWebpack = require('dts-bundle-webpack'); const nodeConfig = { target: 'node', @@ -22,30 +23,38 @@ const nodeConfig = { extensions: ['.ts', '.js', '.json'], }, module: { - rules: [{ - test: /\.ts$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - plugins: ['@babel/plugin-proposal-class-properties'], - presets: [ - ['@babel/preset-env'], - ['@babel/typescript'], - ], - sourceType: 'unambiguous', + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-optional-chaining', + ], + presets: [['@babel/preset-env'], ['@babel/typescript']], + sourceType: 'unambiguous', + }, }, }, - }, { - test: /\.(css|scss)$/, - exclude: /node_modules/, - use: ['style-loader', { - loader: 'css-loader', - options: { - importLoaders: 2, - }, - }, 'postcss-loader', 'sass-loader'] - }], + { + test: /\.(css|scss)$/, + exclude: /node_modules/, + use: [ + 'style-loader', + { + loader: 'css-loader', + options: { + importLoaders: 2, + }, + }, + 'postcss-loader', + 'sass-loader', + ], + }, + ], }, plugins: [ new DtsBundleWebpack({ @@ -53,7 +62,7 @@ const nodeConfig = { main: 'dist/declaration/src/typescript/canvas.d.ts', out: '../cvat-canvas.node.d.ts', }), - ] + ], }; const webConfig = { @@ -79,32 +88,43 @@ const webConfig = { extensions: ['.ts', '.js', '.json'], }, module: { - rules: [{ - test: /\.ts$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - plugins: ['@babel/plugin-proposal-class-properties'], - presets: [ - ['@babel/preset-env', { - targets: '> 2.5%', // https://github.com/browserslist/browserslist - }], - ['@babel/typescript'], - ], - sourceType: 'unambiguous', + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + plugins: ['@babel/plugin-proposal-class-properties'], + presets: [ + [ + '@babel/preset-env', + { + targets: '> 2.5%', // https://github.com/browserslist/browserslist + }, + ], + ['@babel/typescript'], + ], + sourceType: 'unambiguous', + }, }, }, - }, { - test: /\.scss$/, - exclude: /node_modules/, - use: ['style-loader', { - loader: 'css-loader', - options: { - importLoaders: 2, - }, - }, 'postcss-loader', 'sass-loader'] - }], + { + test: /\.scss$/, + exclude: /node_modules/, + use: [ + 'style-loader', + { + loader: 'css-loader', + options: { + importLoaders: 2, + }, + }, + 'postcss-loader', + 'sass-loader', + ], + }, + ], }, plugins: [ new DtsBundleWebpack({ @@ -112,7 +132,7 @@ const webConfig = { main: 'dist/declaration/src/typescript/canvas.d.ts', out: '../cvat-canvas.d.ts', }), - ] + ], }; -module.exports = [webConfig, nodeConfig] +module.exports = [webConfig, nodeConfig]; diff --git a/cvat-core/.eslintignore b/cvat-core/.eslintignore new file mode 100644 index 00000000..6de001d8 --- /dev/null +++ b/cvat-core/.eslintignore @@ -0,0 +1 @@ +webpack.config.js diff --git a/cvat-core/.eslintrc.js b/cvat-core/.eslintrc.js index f4a4e53d..122f5643 100644 --- a/cvat-core/.eslintrc.js +++ b/cvat-core/.eslintrc.js @@ -1,55 +1,47 @@ -/* - * Copyright (C) 2018 Intel Corporation - * - * SPDX-License-Identifier: MIT - */ +// Copyright (C) 2018-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT - module.exports = { - "env": { - "node": false, - "browser": true, - "es6": true, - "jquery": true, - "qunit": true, +module.exports = { + env: { + node: true, + browser: true, + es6: true, + 'jest/globals': true, }, - "parserOptions": { - "parser": "babel-eslint", - "sourceType": "module", - "ecmaVersion": 2018, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module', + ecmaVersion: 2018, }, - "plugins": [ - "security", - "no-unsanitized", - "no-unsafe-innerhtml", - ], - "extends": [ - "eslint:recommended", - "plugin:security/recommended", - "plugin:no-unsanitized/DOM", - "airbnb-base", - ], - "rules": { - "no-await-in-loop": [0], - "global-require": [0], - "no-new": [0], - "class-methods-use-this": [0], - "no-restricted-properties": [0, { - "object": "Math", - "property": "pow", - }], - "no-plusplus": [0], - "no-param-reassign": [0], - "no-underscore-dangle": ["error", { "allowAfterThis": true }], - "no-restricted-syntax": [0, {"selector": "ForOfStatement"}], - "no-continue": [0], - "no-unsafe-innerhtml/no-unsafe-innerhtml": 1, + plugins: ['security', 'jest', 'no-unsafe-innerhtml', 'no-unsanitized'], + extends: ['eslint:recommended', 'plugin:security/recommended', 'plugin:no-unsanitized/DOM', 'airbnb-base'], + rules: { + 'no-await-in-loop': [0], + 'global-require': [0], + 'no-new': [0], + 'class-methods-use-this': [0], + 'no-restricted-properties': [ + 0, + { + object: 'Math', + property: 'pow', + }, + ], + 'no-plusplus': [0], + 'no-param-reassign': [0], + 'no-underscore-dangle': ['error', { allowAfterThis: true }], + 'no-restricted-syntax': [0, { selector: 'ForOfStatement' }], + 'no-continue': [0], + 'no-unsafe-innerhtml/no-unsafe-innerhtml': 1, // This rule actual for user input data on the node.js environment mainly. - "security/detect-object-injection": 0, - "indent": ["warn", 4], - "no-useless-constructor": 0, - "func-names": [0], - "valid-typeof": [0], - "no-console": [0], // this rule deprecates console.log, console.warn etc. because "it is not good in production code" - "max-classes-per-file": [0], + 'security/detect-object-injection': 0, + indent: ['warn', 4], + 'no-useless-constructor': 0, + 'func-names': [0], + 'valid-typeof': [0], + 'no-console': [0], + 'max-classes-per-file': [0], + 'max-len': ['warn', { code: 120 }], }, }; diff --git a/cvat-core/README.md b/cvat-core/README.md index 84ae6050..22d8faa9 100644 --- a/cvat-core/README.md +++ b/cvat-core/README.md @@ -1,40 +1,47 @@ # Module CVAT-CORE ## Description + This CVAT module is a client-side JavaScipt library to management of objects, frames, logs, etc. It contains the core logic of the Computer Vision Annotation Tool. ## Versioning + If you make changes in this package, please do following: -- After not important changes (typos, backward compatible bug fixes, refactoring) do: ``npm version patch`` -- After changing API (backward compatible new features) do: ``npm version minor`` -- After changing API (changes that break backward compatibility) do: ``npm version major`` +- After not important changes (typos, backward compatible bug fixes, refactoring) do: `npm version patch` +- After changing API (backward compatible new features) do: `npm version minor` +- After changing API (changes that break backward compatibility) do: `npm version major` ### Commands - Dependencies installation + ```bash -npm install +npm ci ``` -- Building the module from sources in the ```dist``` directory: +- Building the module from sources in the `dist` directory: + ```bash npm run build npm run build -- --mode=development # without a minification ``` -- Building the documentation in the ```docs``` directory: +- Building the documentation in the `docs` directory: + ```bash npm run-script docs ``` - Running of tests: + ```bash npm run-script test ``` - Updating of a module version: + ```bash npm version patch # updated after minor fixes npm version minor # updated after major changes which don't affect API compatibility with previous versions @@ -42,5 +49,6 @@ npm version major # updated after major changes which affect API compatibility ``` Visual studio code configurations: + - cvat.js debug starts debugging with entrypoint api.js - cvat.js test builds library and runs entrypoint tests.js diff --git a/cvat-core/jest.config.js b/cvat-core/jest.config.js index c7712052..6227977b 100644 --- a/cvat-core/jest.config.js +++ b/cvat-core/jest.config.js @@ -1,32 +1,15 @@ -/* - * Copyright (C) 2019 Intel Corporation - * SPDX-License-Identifier: MIT - */ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const { defaults } = require('jest-config'); module.exports = { coverageDirectory: 'reports/coverage', coverageReporters: ['lcov'], - moduleFileExtensions: [ - ...defaults.moduleFileExtensions, - 'ts', - 'tsx', - ], - reporters: [ - 'default', - ['jest-junit', { outputDirectory: 'reports/junit' }], - ], - testMatch: [ - '**/tests/**/*.js', - ], - testPathIgnorePatterns: [ - '/node_modules/', - '/tests/mocks/*', - ], + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], + reporters: ['default', ['jest-junit', { outputDirectory: 'reports/junit' }]], + testMatch: ['**/tests/**/*.js'], + testPathIgnorePatterns: ['/node_modules/', '/tests/mocks/*'], automock: false, }; diff --git a/cvat-core/jsdoc.config.js b/cvat-core/jsdoc.config.js index a51208c5..a85e5ecc 100644 --- a/cvat-core/jsdoc.config.js +++ b/cvat-core/jsdoc.config.js @@ -1,8 +1,6 @@ -/* - * Copyright (C) 2019 Intel Corporation - * SPDX-License-Identifier: MIT - */ - +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT module.exports = { plugins: [], diff --git a/cvat-core/package-lock.json b/cvat-core/package-lock.json index 0bc2c787..663df2da 100644 --- a/cvat-core/package-lock.json +++ b/cvat-core/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-core", - "version": "3.5.0", + "version": "3.10.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -474,7 +474,14 @@ "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-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -483,7 +490,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -506,11 +512,18 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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" } @@ -519,7 +532,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -528,7 +540,6 @@ "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" } @@ -537,7 +548,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -554,7 +564,6 @@ "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" } @@ -563,7 +572,6 @@ "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" } @@ -572,7 +580,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -1050,10 +1057,65 @@ "minimist": "^1.2.0" } }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, "@jest/console": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, "requires": { "@jest/source-map": "^24.9.0", "chalk": "^2.0.1", @@ -1094,12 +1156,269 @@ "rimraf": "^2.5.4", "slash": "^2.0.0", "strip-ansi": "^5.0.0" + }, + "dependencies": { + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } } }, "@jest/environment": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dev": true, "requires": { "@jest/fake-timers": "^24.9.0", "@jest/transform": "^24.9.0", @@ -1111,228 +1430,1422 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dev": true, "requires": { "@jest/types": "^24.9.0", "jest-message-util": "^24.9.0", "jest-mock": "^24.9.0" } }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.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 - } - } - }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", - "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" - } - }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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==", + "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==" + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/reporters": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "source-map": "^0.6.0", + "string-length": "^2.0.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==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "@jest/types": { + "@jest/source-map": { "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@types/babel__core": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", - "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", - "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@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/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" - }, - "@types/yargs": { - "version": "13.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", - "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, "requires": { - "@types/yargs-parser": "*" + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "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 + } } }, - "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" - }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.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": { + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + }, + "dependencies": { + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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==", + "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==" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" + }, + "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==" + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "optional": 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==" + }, + "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==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "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==", + "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==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + } + } + }, + "@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.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 + } + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.15.tgz", + "integrity": "sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@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/node": { + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/prettier": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==" + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" + }, + "@typescript-eslint/experimental-utils": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.5.0.tgz", + "integrity": "sha512-bW9IpSAKYvkqDGRZzayBXIgPsj2xmmVHLJ+flGSoN0fF98pGoKFhbunIol0VF2Crka7z984EEhFi623Rl7e6gg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.5.0", + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/typescript-estree": "4.5.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.5.0.tgz", + "integrity": "sha512-C0cEO0cTMPJ/w4RA/KVe4LFFkkSh9VHoFzKmyaaDWAnPYIEzVCtJ+Un8GZoJhcvq+mPFXEsXa01lcZDHDG6Www==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0" + } + }, + "@typescript-eslint/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.5.0.tgz", + "integrity": "sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.5.0.tgz", + "integrity": "sha512-gN1mffq3zwRAjlYWzb5DanarOPdajQwx5MEWkWCk0XvqC8JpafDTeioDoow2L4CA/RkYZu7xEsGZRhqrTsAG8w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz", + "integrity": "sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "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==", @@ -1503,28 +3016,29 @@ "dev": true }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true }, "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" } } }, @@ -1535,9 +3049,9 @@ "dev": true }, "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "airbnb": { "version": "0.0.2", @@ -1579,7 +3093,8 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true }, "ansi-styles": { "version": "3.2.1", @@ -1608,7 +3123,6 @@ "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" } @@ -1631,7 +3145,8 @@ "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, "array-includes": { "version": "3.1.1", @@ -1644,6 +3159,12 @@ "is-string": "^1.0.5" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -1729,7 +3250,8 @@ "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==" + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true }, "asynckit": { "version": "0.4.0", @@ -1752,12 +3274,11 @@ "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" }, "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "follow-redirects": "^1.10.0" } }, "babel-code-frame": { @@ -1834,17 +3355,293 @@ } }, "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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==", + "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==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "optional": 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==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } } }, "babel-loader": { @@ -1892,6 +3689,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "find-up": "^3.0.0", @@ -1900,20 +3698,42 @@ } }, "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", "@types/babel__traverse": "^7.0.6" } }, + "babel-preset-current-node-syntax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { @@ -2001,6 +3821,7 @@ "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" @@ -2074,6 +3895,7 @@ "version": "1.11.3", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, "requires": { "resolve": "1.1.7" }, @@ -2081,7 +3903,8 @@ "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true } } }, @@ -2409,6 +4232,11 @@ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -2449,6 +4277,7 @@ "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", @@ -2466,6 +4295,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -2694,23 +4528,30 @@ } }, "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" }, "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "requires": { - "cssom": "0.3.x" + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } } }, "cvat-data": { "version": "file:../cvat-data", "requires": { - "async-mutex": "^0.1.4", - "jszip": "3.1.5" + "async-mutex": "^0.2.4", + "jszip": "3.5.0" }, "dependencies": { "@babel/cli": { @@ -3822,9 +5663,19 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" }, "async-mutex": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.1.4.tgz", - "integrity": "sha512-zVWTmAnxxHaeB2B1te84oecI8zTDJ/8G49aVBblRX6be0oq6pAybNcUSxwfgVOmOjSCvN4aYZAqwtyNI8e1YGw==" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.4.tgz", + "integrity": "sha512-fcQKOXUKMQc57JlmjBCHtkKNrfGpHyR7vu18RfuLfeTAf4hK9PgOadPR5cDrBQ682zasrLUhJFe7EKAHJOduDg==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" + } + } }, "atob": { "version": "2.1.2", @@ -4958,11 +6809,6 @@ "event-emitter": "~0.3.5" } }, - "es6-promise": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" - }, "es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -6671,22 +8517,14 @@ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" }, "jszip": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", - "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", + "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", "requires": { - "core-js": "~2.3.0", - "es6-promise": "~3.0.2", - "lie": "~3.1.0", + "lie": "~3.3.0", "pako": "~1.0.2", - "readable-stream": "~2.0.6" - }, - "dependencies": { - "core-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", - "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" - } + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" } }, "kind-of": { @@ -6712,9 +8550,9 @@ } }, "lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "requires": { "immediate": "~3.0.5" } @@ -7589,9 +9427,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "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==" }, "progress": { "version": "2.0.3", @@ -7781,15 +9619,16 @@ } }, "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "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.1", + "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, @@ -8133,6 +9972,11 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -8510,9 +10354,12 @@ } }, "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "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", @@ -9409,33 +11256,30 @@ } }, "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" } }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "dependencies": { + "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 + } } }, "decamelize": { @@ -9443,6 +11287,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -9453,10 +11302,16 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, "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" } @@ -9514,9 +11369,9 @@ } }, "detect-browser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.1.1.tgz", - "integrity": "sha512-5n2aWI57qC3kZaK4j2zYsG6L1LrxgLptGCNhMQgdKhVn6cSdcq43pp6xHPfTHG3TYM6myF4tIPWiZtfdVDgb9w==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.0.tgz", + "integrity": "sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA==" }, "detect-file": { "version": "1.0.0", @@ -9527,12 +11382,14 @@ "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true }, "diff-sequences": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "dev": true }, "diffie-hellman": { "version": "5.0.3", @@ -9553,6 +11410,23 @@ } } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -9569,11 +11443,18 @@ "dev": true }, "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "requires": { - "webidl-conversions": "^4.0.2" + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } } }, "duplexify": { @@ -9626,10 +11507,16 @@ } } }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==" + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "emojis-list": { "version": "3.0.0", @@ -9702,6 +11589,7 @@ "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", @@ -9720,6 +11608,7 @@ "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", @@ -10063,1229 +11952,1771 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + }, + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "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" + } + } + } + }, + "eslint-plugin-jest": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.1.0.tgz", + "integrity": "sha512-827YJ+E8B9PvXu/0eiVSNFfxxndbKv+qE/3GSMhdorCaeaOehtqHGX2YDW9B85TEOre9n/zscledkFW/KbnyGg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, + "eslint-plugin-no-unsafe-innerhtml": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsafe-innerhtml/-/eslint-plugin-no-unsafe-innerhtml-1.0.16.tgz", + "integrity": "sha1-fQKHjI6b95FriINtWsEitC8VGTI=", + "dev": true, + "requires": { + "eslint": "^3.7.1" + }, + "dependencies": { + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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": "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" + } + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "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" + } + }, + "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": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "dev": true, "requires": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", "esutils": "^2.0.2", - "isarray": "^1.0.0" + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, - "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=", + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, - "locate-path": { + "file-entry-cache": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "requires": { - "p-try": "^1.0.0" + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "p-limit": "^1.1.0" + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" } }, - "p-try": { + "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "dev": true, "requires": { - "pify": "^2.0.0" + "once": "^1.3.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, - "read-pkg": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.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-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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 + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.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=", + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "mkdirp": "^0.5.1" } } } }, - "eslint-plugin-no-unsafe-innerhtml": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsafe-innerhtml/-/eslint-plugin-no-unsafe-innerhtml-1.0.16.tgz", - "integrity": "sha1-fQKHjI6b95FriINtWsEitC8VGTI=", + "eslint-plugin-no-unsanitized": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-3.1.2.tgz", + "integrity": "sha512-KPShfliA3Uy9qqwQx35P1fwIOeJjZkb0FbMMUFztRYRposzaynsM8JCEb952fqkidROl1kpqY80uSvn+TcWkQQ==", + "dev": true + }, + "eslint-plugin-security": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.4.0.tgz", + "integrity": "sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA==", "dev": true, "requires": { - "eslint": "^3.7.1" + "safe-regex": "^1.1.0" + } + }, + "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" + } + }, + "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==", + "dev": true + }, + "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-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "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 - }, - "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" - } - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, + } + } + }, + "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==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "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" + } + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" + }, + "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" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "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": { "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" } }, - "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": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - } - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, + "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": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "is-descriptor": "^0.1.0" } }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "is-extendable": "^0.1.0" } - }, - "file-entry-cache": { + } + } + }, + "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" + } + }, + "expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", "dev": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "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": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" + "is-plain-object": "^2.0.4" } - }, - "is-fullwidth-code-point": { + } + } + }, + "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==", + "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/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "number-is-nan": "^1.0.0" + "is-descriptor": "^1.0.0" } }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "is-extendable": "^0.1.0" } }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, + "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": { - "once": "^1.3.0" + "kind-of": "^6.0.0" } }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "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" + } }, - "string-width": { + "is-descriptor": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "fill-range": "^7.0.1" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "to-regex-range": "^5.0.1" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "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" + } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "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 - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "is-number": "^7.0.0" } } } }, - "eslint-plugin-no-unsanitized": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-3.1.2.tgz", - "integrity": "sha512-KPShfliA3Uy9qqwQx35P1fwIOeJjZkb0FbMMUFztRYRposzaynsM8JCEb952fqkidROl1kpqY80uSvn+TcWkQQ==", + "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==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "requires": { + "bser": "2.1.1" + } + }, + "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 }, - "eslint-plugin-security": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.4.0.tgz", - "integrity": "sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA==", + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "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=", + "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==", + "dev": true, + "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==", + "dev": true, + "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==", "dev": true, "requires": { - "safe-regex": "^1.1.0" + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.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==", + "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": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" } }, - "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==", + "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": { - "eslint-visitor-keys": "^1.1.0" + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" } }, - "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==", - "dev": true + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" }, - "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "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.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", - "dev": true - } + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "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" + } }, - "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==", + "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": { - "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 - } + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" } }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "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": { - "estraverse": "^4.1.0" + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" } }, - "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==" + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "optional": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "bindings": "^1.5.0", + "nan": "^2.12.1" } }, - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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 }, - "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==", + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "is-property": "^1.0.2" } }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "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" + "is-property": "^1.0.0" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + "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==" }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "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==" }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "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": { - "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": { - "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" - } - }, - "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" - } - } + "pump": "^3.0.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, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "homedir-polyfill": "^1.0.1" + "assert-plus": "^1.0.0" } }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" + "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" } }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, + "optional": true, "requires": { - "type": "^2.0.0" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { - "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", - "dev": true + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "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": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "global-prefix": "^3.0.0" }, "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==", + "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": { - "is-plain-object": "^2.0.4" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" } } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "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": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "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" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" }, "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" - } + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true }, - "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" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "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==" }, - "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==" + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "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=" + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "requires": { - "bser": "2.1.1" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" } }, - "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 + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } }, - "figures": { + "has-ansi": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } } }, - "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, + "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=", "requires": { - "flat-cache": "^2.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, - "file-uri-to-path": { + "has-values": { "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==", - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "requires": { - "extend-shallow": "^2.0.1", "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "kind-of": "^4.0.0" }, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { - "is-extendable": "^0.1.0" + "is-buffer": "^1.1.5" } } } }, - "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==", + "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": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "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.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "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": { - "locate-path": "^3.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "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": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^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==", + "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": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "parse-passwd": "^1.0.0" } }, - "flatted": { + "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==" + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "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, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, - "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==", + "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==", "requires": { - "debug": "=3.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + "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 }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "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": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "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": { - "map-cache": "^0.2.2" + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" } }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.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==", + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "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=", + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "loose-envify": "^1.0.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": 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=", "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "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" + } + } } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, - "functional-red-black-tree": { + "is-binary-path": { "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 - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, + "optional": true, "requires": { - "is-property": "^1.0.2" + "binary-extensions": "^1.0.0" } }, - "generate-object-property": { + "is-callable": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, - "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=" + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "requires": { - "assert-plus": "^1.0.0" + "ci-info": "^2.0.0" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", "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": "^1.0.3" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "optional": 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=", "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "kind-of": "^3.0.2" }, "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, - "optional": true, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-extglob": "^2.1.0" + "is-buffer": "^1.1.5" } } } }, - "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, + "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==", "requires": { - "global-prefix": "^3.0.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.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" - } + "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==" } } }, - "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==" + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "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 }, - "har-schema": { + "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^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 }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "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": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } + "is-extglob": "^2.1.1" } }, - "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": { + "is-my-ip-valid": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.20.5", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", + "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.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=", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "kind-of": "^3.0.2" }, "dependencies": { "is-buffer": { @@ -11294,733 +13725,1778 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "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" } } } }, - "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, + "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": { - "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.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "isobject": "^3.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==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "has-symbols": "^1.0.1" } }, - "homedir-polyfill": { + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "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/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { - "parse-passwd": "^1.0.0" + "has-symbols": "^1.0.1" } }, - "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==" + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "html-encoding-sniffer": { + "is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "requires": { - "whatwg-encoding": "^1.0.1" - } + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true }, - "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" - } - }, - "https-browserify": { + "isarray": { "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 + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "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" - } + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, - "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 + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "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==", + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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==", + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "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" + } + } } }, - "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==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.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 + }, + "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 + } } }, - "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==", - "dev": true + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", "dev": true, "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" + "import-local": "^2.0.0", + "jest-cli": "^24.9.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "dev": true, + "requires": { + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" + }, + "dependencies": { + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" } } } }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "dev": true, "requires": { - "loose-envify": "^1.0.0" + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" } }, - "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=", + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "requires": { - "kind-of": "^3.0.2" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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==", + "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==" + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" + }, + "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==" + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "optional": 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==" + }, + "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==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "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==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "is-buffer": "^1.1.5" + "ansi-regex": "^5.0.0" } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "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, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "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": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "is-buffer": "^1.1.5" + "has-flag": "^4.0.0" } - } - } - }, - "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==" - }, - "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=", - "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=" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" - }, - "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-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.20.5", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", - "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "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": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "requires": { - "is-buffer": "^1.1.5" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } - } - } - }, - "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-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "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==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "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=", - "dev": true - }, - "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=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + } + } }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" + "jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "jest-docblock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "dev": true, "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } + "detect-newline": "^2.1.0" } }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" }, "dependencies": { + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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==", + "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==" + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, "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, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" } } } }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/yargs": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz", + "integrity": "sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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==", + "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==" + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "requires": { - "ms": "^2.1.1" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" } }, - "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 + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } }, - "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 - } - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } - }, - "jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", - "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", - "dev": true, - "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.9.0" - }, - "dependencies": { - "jest-cli": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", - "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", - "dev": true, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "requires": { - "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "import-local": "^2.0.0", - "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^13.3.0" + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" } } } }, - "jest-changed-files": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", - "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" - } - }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", - "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, "jest-get-type": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "dev": true }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "dev": true, "requires": { "@jest/types": "^24.9.0", "anymatch": "^2.0.0", @@ -12040,6 +15516,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "dev": true, "requires": { "@babel/traverse": "^7.1.0", "@jest/environment": "^24.9.0", @@ -12092,6 +15569,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "dev": true, "requires": { "jest-get-type": "^24.9.0", "pretty-format": "^24.9.0" @@ -12101,6 +15579,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "dev": true, "requires": { "chalk": "^2.0.1", "jest-diff": "^24.9.0", @@ -12112,6 +15591,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@jest/test-result": "^24.9.0", @@ -12127,6 +15607,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "dev": true, "requires": { "@jest/types": "^24.9.0" } @@ -12139,12 +15620,14 @@ "jest-regex-util": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==" + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true }, "jest-resolve": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "dev": true, "requires": { "@jest/types": "^24.9.0", "browser-resolve": "^1.11.3", @@ -12168,6 +15651,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dev": true, "requires": { "@jest/console": "^24.7.1", "@jest/environment": "^24.9.0", @@ -12188,12 +15672,269 @@ "jest-worker": "^24.6.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" + }, + "dependencies": { + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } } }, "jest-runtime": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", + "dev": true, "requires": { "@jest/console": "^24.7.1", "@jest/environment": "^24.9.0", @@ -12218,17 +15959,275 @@ "slash": "^2.0.0", "strip-bom": "^3.0.0", "yargs": "^13.3.0" + }, + "dependencies": { + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } } }, "jest-serializer": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true }, "jest-snapshot": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dev": true, "requires": { "@babel/types": "^7.0.0", "@jest/types": "^24.9.0", @@ -12248,7 +16247,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -12256,6 +16256,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dev": true, "requires": { "@jest/console": "^24.9.0", "@jest/fake-timers": "^24.9.0", @@ -12274,7 +16275,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -12282,6 +16284,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dev": true, "requires": { "@jest/types": "^24.9.0", "camelcase": "^5.3.1", @@ -12310,6 +16313,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, "requires": { "merge-stream": "^2.0.0", "supports-color": "^6.1.0" @@ -12319,6 +16323,7 @@ "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" } @@ -12339,7 +16344,6 @@ "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" @@ -12402,36 +16406,53 @@ } }, "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "jsesc": { @@ -12442,7 +16463,13 @@ "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==" + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.2.3", @@ -12551,7 +16578,8 @@ "left-pad": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true }, "leven": { "version": "3.1.0", @@ -12576,6 +16604,11 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", @@ -12589,6 +16622,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -12626,6 +16660,7 @@ "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" @@ -12651,6 +16686,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -12760,6 +16796,12 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -12883,6 +16925,7 @@ "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" } @@ -12916,6 +16959,7 @@ "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": { @@ -13111,12 +17155,14 @@ "object-inspect": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + "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==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object-visit": { "version": "1.0.1", @@ -13130,6 +17176,7 @@ "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", @@ -13152,6 +17199,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" @@ -13251,6 +17299,7 @@ "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" } @@ -13310,6 +17359,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -13322,9 +17372,9 @@ "dev": true }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" }, "pascalcase": { "version": "0.1.1", @@ -13347,7 +17397,8 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -13374,6 +17425,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, "requires": { "pify": "^3.0.0" } @@ -13399,14 +17451,13 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "optional": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true }, "pirates": { "version": "4.0.1", @@ -13439,7 +17490,8 @@ "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true }, "posix-character-classes": { "version": "0.1.1", @@ -13455,6 +17507,7 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dev": true, "requires": { "@jest/types": "^24.9.0", "ansi-regex": "^4.0.0", @@ -13583,6 +17636,11 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "quickhull": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/quickhull/-/quickhull-1.0.3.tgz", + "integrity": "sha512-AQbLaXdzGDJdO9Mu3qY/NY5JWlDqIutCLW8vJbsQTq+/bydIZeltnMVRKCElp81Y5/uRm4Yw/RsMdcltFYsS6w==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -13605,12 +17663,14 @@ "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==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -13621,6 +17681,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" @@ -13685,6 +17746,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", + "dev": true, "requires": { "util.promisify": "^1.0.0" } @@ -13963,6 +18025,12 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -13993,6 +18061,12 @@ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -14054,7 +18128,16 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } }, "schema-utils": { "version": "0.4.7", @@ -14165,7 +18248,8 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true }, "slice-ansi": { "version": "2.1.0", @@ -14371,8 +18455,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -14402,7 +18485,8 @@ "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true }, "stackframe": { "version": "1.2.0", @@ -14516,6 +18600,7 @@ "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", @@ -14526,6 +18611,7 @@ "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" @@ -14535,6 +18621,7 @@ "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" @@ -14553,6 +18640,7 @@ "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" } @@ -14560,7 +18648,8 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true }, "strip-eof": { "version": "1.0.0", @@ -14675,6 +18764,7 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, "requires": { "glob": "^7.1.3", "minimatch": "^3.0.4", @@ -14691,7 +18781,8 @@ "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true }, "through": { "version": "2.3.8", @@ -14796,11 +18887,11 @@ } }, "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", "requires": { - "punycode": "^2.1.0" + "punycode": "^2.1.1" } }, "tslib": { @@ -14809,6 +18900,15 @@ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "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", @@ -14842,12 +18942,30 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -15031,6 +19149,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.2", @@ -15082,6 +19201,14 @@ "browser-process-hrtime": "^1.0.0" } }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", @@ -15231,9 +19358,9 @@ } }, "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { "version": "4.44.1", @@ -15357,13 +19484,13 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", "requires": { "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" } }, "which": { @@ -15406,6 +19533,7 @@ "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", @@ -15430,6 +19558,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -15437,12 +19566,9 @@ } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" }, "xml": { "version": "1.0.1", @@ -15455,6 +19581,11 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, "xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", @@ -15482,6 +19613,7 @@ "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -15499,6 +19631,7 @@ "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/cvat-core/package.json b/cvat-core/package.json index ca65f045..3ab719d8 100644 --- a/cvat-core/package.json +++ b/cvat-core/package.json @@ -1,6 +1,6 @@ { "name": "cvat-core", - "version": "3.5.0", + "version": "3.10.0", "description": "Part of Computer Vision Tool which presents an interface for client-side integration", "main": "babel.config.js", "scripts": { @@ -25,6 +25,7 @@ "eslint-plugin-no-unsafe-innerhtml": "^1.0.16", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-security": "^1.4.0", + "eslint-plugin-jest": "^24.1.0", "jest": "^24.8.0", "jest-junit": "^6.4.0", "jsdoc": "^3.6.4", @@ -32,16 +33,17 @@ "webpack-cli": "^3.3.2" }, "dependencies": { - "axios": "^0.18.0", + "axios": "^0.21.1", "browser-or-node": "^1.2.1", "cvat-data": "../cvat-data", - "detect-browser": "^5.0.0", + "detect-browser": "^5.2.0", "error-stack-parser": "^2.0.2", "form-data": "^2.5.0", - "jest-config": "^24.8.0", + "jest-config": "^26.6.3", "js-cookie": "^2.2.0", "jsonpath": "^1.0.2", "platform": "^1.3.5", + "quickhull": "^1.0.3", "store": "^2.0.12", "worker-loader": "^2.0.0" } diff --git a/cvat-core/src/annotation-formats.js b/cvat-core/src/annotation-formats.js index a248c9d7..795c9863 100644 --- a/cvat-core/src/annotation-formats.js +++ b/cvat-core/src/annotation-formats.js @@ -1,14 +1,13 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { /** - * Class representing an annotation loader - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing an annotation loader + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Loader { constructor(initialData) { const data = { @@ -21,42 +20,42 @@ Object.defineProperties(this, { name: { /** - * @name name - * @type {string} - * @memberof module:API.cvat.classes.Loader - * @readonly - * @instance - */ + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Loader + * @readonly + * @instance + */ get: () => data.name, }, format: { /** - * @name format - * @type {string} - * @memberof module:API.cvat.classes.Loader - * @readonly - * @instance - */ + * @name format + * @type {string} + * @memberof module:API.cvat.classes.Loader + * @readonly + * @instance + */ get: () => data.format, }, version: { /** - * @name version - * @type {string} - * @memberof module:API.cvat.classes.Loader - * @readonly - * @instance - */ + * @name version + * @type {string} + * @memberof module:API.cvat.classes.Loader + * @readonly + * @instance + */ get: () => data.version, }, enabled: { /** - * @name enabled - * @type {string} - * @memberof module:API.cvat.classes.Loader - * @readonly - * @instance - */ + * @name enabled + * @type {string} + * @memberof module:API.cvat.classes.Loader + * @readonly + * @instance + */ get: () => data.enabled, }, }); @@ -64,10 +63,10 @@ } /** - * Class representing an annotation dumper - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing an annotation dumper + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Dumper { constructor(initialData) { const data = { @@ -80,42 +79,42 @@ Object.defineProperties(this, { name: { /** - * @name name - * @type {string} - * @memberof module:API.cvat.classes.Dumper - * @readonly - * @instance - */ + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Dumper + * @readonly + * @instance + */ get: () => data.name, }, format: { /** - * @name format - * @type {string} - * @memberof module:API.cvat.classes.Dumper - * @readonly - * @instance - */ + * @name format + * @type {string} + * @memberof module:API.cvat.classes.Dumper + * @readonly + * @instance + */ get: () => data.format, }, version: { /** - * @name version - * @type {string} - * @memberof module:API.cvat.classes.Dumper - * @readonly - * @instance - */ + * @name version + * @type {string} + * @memberof module:API.cvat.classes.Dumper + * @readonly + * @instance + */ get: () => data.version, }, enabled: { /** - * @name enabled - * @type {string} - * @memberof module:API.cvat.classes.Loader - * @readonly - * @instance - */ + * @name enabled + * @type {string} + * @memberof module:API.cvat.classes.Loader + * @readonly + * @instance + */ get: () => data.enabled, }, }); @@ -123,10 +122,10 @@ } /** - * Class representing an annotation format - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing an annotation format + * @memberof module:API.cvat.classes + * @hideconstructor + */ class AnnotationFormats { constructor(initialData) { const data = { @@ -138,22 +137,22 @@ Object.defineProperties(this, { loaders: { /** - * @name loaders - * @type {module:API.cvat.classes.Loader[]} - * @memberof module:API.cvat.classes.AnnotationFormats - * @readonly - * @instance - */ + * @name loaders + * @type {module:API.cvat.classes.Loader[]} + * @memberof module:API.cvat.classes.AnnotationFormats + * @readonly + * @instance + */ get: () => [...data.importers], }, dumpers: { /** - * @name dumpers - * @type {module:API.cvat.classes.Dumper[]} - * @memberof module:API.cvat.classes.AnnotationFormats - * @readonly - * @instance - */ + * @name dumpers + * @type {module:API.cvat.classes.Dumper[]} + * @memberof module:API.cvat.classes.AnnotationFormats + * @readonly + * @instance + */ get: () => [...data.exporters], }, }); diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index ed338f6b..db0c7fef 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const { @@ -28,17 +23,10 @@ const { checkObjectType } = require('./common'); const Statistics = require('./statistics'); const { Label } = require('./labels'); - const { - DataError, - ArgumentError, - ScriptingError, - } = require('./exceptions'); + const { DataError, ArgumentError, ScriptingError } = require('./exceptions'); const { - HistoryActions, - ObjectShape, - ObjectType, - colors, + HistoryActions, ObjectShape, ObjectType, colors, } = require('./enums'); const ObjectState = require('./object-state'); @@ -64,15 +52,12 @@ shapeModel = new CuboidShape(shapeData, clientID, color, injection); break; default: - throw new DataError( - `An unexpected type of shape "${type}"`, - ); + throw new DataError(`An unexpected type of shape "${type}"`); } return shapeModel; } - function trackFactory(trackData, clientID, injection) { if (trackData.shapes.length) { const { type } = trackData.shapes[0]; @@ -96,9 +81,7 @@ trackModel = new CuboidTrack(trackData, clientID, color, injection); break; default: - throw new DataError( - `An unexpected type of track "${type}"`, - ); + throw new DataError(`An unexpected type of track "${type}"`); } return trackModel; @@ -185,18 +168,20 @@ export() { const data = { - tracks: this.tracks.filter((track) => !track.removed) - .map((track) => track.toJSON()), + tracks: this.tracks.filter((track) => !track.removed).map((track) => track.toJSON()), shapes: Object.values(this.shapes) .reduce((accumulator, value) => { accumulator.push(...value); return accumulator; - }, []).filter((shape) => !shape.removed) + }, []) + .filter((shape) => !shape.removed) .map((shape) => shape.toJSON()), - tags: Object.values(this.tags).reduce((accumulator, value) => { - accumulator.push(...value); - return accumulator; - }, []).filter((tag) => !tag.removed) + tags: Object.values(this.tags) + .reduce((accumulator, value) => { + accumulator.push(...value); + return accumulator; + }, []) + .filter((tag) => !tag.removed) .map((tag) => tag.toJSON()), }; @@ -252,7 +237,7 @@ const objectsForMerge = objectStates.map((state) => { checkObjectType('object state', state, null, ObjectState); const object = this.objects[state.clientID]; - if (typeof (object) === 'undefined') { + if (typeof object === 'undefined') { throw new ArgumentError( 'The object has not been saved yet. Call ObjectState.put([state]) before you can merge it', ); @@ -263,15 +248,11 @@ const keyframes = {}; // frame: position const { label, shapeType } = objectStates[0]; if (!(label.id in this.labels)) { - throw new ArgumentError( - `Unknown label for the task: ${label.id}`, - ); + throw new ArgumentError(`Unknown label for the task: ${label.id}`); } if (!Object.values(ObjectShape).includes(shapeType)) { - throw new ArgumentError( - `Got unknown shapeType "${shapeType}"`, - ); + throw new ArgumentError(`Got unknown shapeType "${shapeType}"`); } const labelAttributes = label.attributes.reduce((accumulator, attribute) => { @@ -290,18 +271,14 @@ } if (state.shapeType !== shapeType) { - throw new ArgumentError( - `All shapes are expected to be ${shapeType}, but got ${state.shapeType}`, - ); + throw new ArgumentError(`All shapes are expected to be ${shapeType}, but got ${state.shapeType}`); } // If this object is shape, get it position and save as a keyframe if (object instanceof Shape) { // Frame already saved and it is not outside if (object.frame in keyframes && !keyframes[object.frame].outside) { - throw new ArgumentError( - 'Expected only one visible shape per frame', - ); + throw new ArgumentError('Expected only one visible shape per frame'); } keyframes[object.frame] = { @@ -325,9 +302,8 @@ // Push outside shape after each annotation shape // Any not outside shape rewrites it - if (!((object.frame + 1) in keyframes) && object.frame + 1 <= this.stopFrame) { - keyframes[object.frame + 1] = JSON - .parse(JSON.stringify(keyframes[object.frame])); + if (!(object.frame + 1 in keyframes) && object.frame + 1 <= this.stopFrame) { + keyframes[object.frame + 1] = JSON.parse(JSON.stringify(keyframes[object.frame])); keyframes[object.frame + 1].outside = true; keyframes[object.frame + 1].frame++; } @@ -344,17 +320,14 @@ continue; } - throw new ArgumentError( - 'Expected only one visible shape per frame', - ); + throw new ArgumentError('Expected only one visible shape per frame'); } // We do not save an attribute if it has the same value // We save only updates let updatedAttributes = false; for (const attrID in shape.attributes) { - if (!(attrID in attributes) - || attributes[attrID] !== shape.attributes[attrID]) { + if (!(attrID in attributes) || attributes[attrID] !== shape.attributes[attrID]) { updatedAttributes = true; attributes[attrID] = shape.attributes[attrID]; } @@ -367,15 +340,16 @@ occluded: shape.occluded, outside: shape.outside, zOrder: shape.zOrder, - attributes: updatedAttributes ? Object.keys(attributes) - .reduce((accumulator, attrID) => { + attributes: updatedAttributes + ? Object.keys(attributes).reduce((accumulator, attrID) => { accumulator.push({ spec_id: +attrID, value: attributes[attrID], }); return accumulator; - }, []) : [], + }, []) + : [], }; } } else { @@ -399,22 +373,24 @@ const clientID = ++this.count; const track = { - frame: Math.min.apply(null, Object.keys(keyframes).map((frame) => +frame)), + frame: Math.min.apply( + null, + Object.keys(keyframes).map((frame) => +frame), + ), shapes: Object.values(keyframes), group: 0, source: objectStates[0].source, label_id: label.id, - attributes: Object.keys(objectStates[0].attributes) - .reduce((accumulator, attrID) => { - if (!labelAttributes[attrID].mutable) { - accumulator.push({ - spec_id: +attrID, - value: objectStates[0].attributes[attrID], - }); - } + attributes: Object.keys(objectStates[0].attributes).reduce((accumulator, attrID) => { + if (!labelAttributes[attrID].mutable) { + accumulator.push({ + spec_id: +attrID, + value: objectStates[0].attributes[attrID], + }); + } - return accumulator; - }, []), + return accumulator; + }, []), }; const trackModel = trackFactory(track, clientID, this.injection); @@ -426,20 +402,23 @@ object.removed = true; } - this.history.do(HistoryActions.MERGED_OBJECTS, () => { - trackModel.removed = true; - for (const object of objectsForMerge) { - object.removed = false; - } - }, () => { - trackModel.removed = false; - for (const object of objectsForMerge) { - object.removed = true; - } - }, [ - ...objectsForMerge - .map((object) => object.clientID), trackModel.clientID, - ], objectStates[0].frame); + this.history.do( + HistoryActions.MERGED_OBJECTS, + () => { + trackModel.removed = true; + for (const object of objectsForMerge) { + object.removed = false; + } + }, + () => { + trackModel.removed = false; + for (const object of objectsForMerge) { + object.removed = true; + } + }, + [...objectsForMerge.map((object) => object.clientID), trackModel.clientID], + objectStates[0].frame, + ); } split(objectState, frame) { @@ -447,10 +426,8 @@ checkObjectType('frame', frame, 'integer', null); const object = this.objects[objectState.clientID]; - if (typeof (object) === 'undefined') { - throw new ArgumentError( - 'The object has not been saved yet. Call annotations.put([state]) before', - ); + if (typeof object === 'undefined') { + throw new ArgumentError('The object has not been saved yet. Call annotations.put([state]) before'); } if (objectState.objectType !== ObjectType.TRACK) { @@ -474,17 +451,16 @@ occluded: objectState.occluded, outside: objectState.outside, zOrder: objectState.zOrder, - attributes: Object.keys(objectState.attributes) - .reduce((accumulator, attrID) => { - if (!labelAttributes[attrID].mutable) { - accumulator.push({ - spec_id: +attrID, - value: objectState.attributes[attrID], - }); - } + attributes: Object.keys(objectState.attributes).reduce((accumulator, attrID) => { + if (!labelAttributes[attrID].mutable) { + accumulator.push({ + spec_id: +attrID, + value: objectState.attributes[attrID], + }); + } - return accumulator; - }, []), + return accumulator; + }, []), frame, }; @@ -526,15 +502,21 @@ // Remove source object object.removed = true; - this.history.do(HistoryActions.SPLITTED_TRACK, () => { - object.removed = false; - prevTrack.removed = true; - nextTrack.removed = true; - }, () => { - object.removed = true; - prevTrack.removed = false; - nextTrack.removed = false; - }, [object.clientID, prevTrack.clientID, nextTrack.clientID], frame); + this.history.do( + HistoryActions.SPLITTED_TRACK, + () => { + object.removed = false; + prevTrack.removed = true; + nextTrack.removed = true; + }, + () => { + object.removed = true; + prevTrack.removed = false; + nextTrack.removed = false; + }, + [object.clientID, prevTrack.clientID, nextTrack.clientID], + frame, + ); } group(objectStates, reset) { @@ -543,10 +525,8 @@ const objectsForGroup = objectStates.map((state) => { checkObjectType('object state', state, null, ObjectState); const object = this.objects[state.clientID]; - if (typeof (object) === 'undefined') { - throw new ArgumentError( - 'The object has not been saved yet. Call annotations.put([state]) before', - ); + if (typeof object === 'undefined') { + throw new ArgumentError('The object has not been saved yet. Call annotations.put([state]) before'); } return object; }); @@ -558,15 +538,21 @@ } const redoGroups = objectsForGroup.map((object) => object.group); - this.history.do(HistoryActions.GROUPED_OBJECTS, () => { - objectsForGroup.forEach((object, idx) => { - object.group = undoGroups[idx]; - }); - }, () => { - objectsForGroup.forEach((object, idx) => { - object.group = redoGroups[idx]; - }); - }, objectsForGroup.map((object) => object.clientID), objectStates[0].frame); + this.history.do( + HistoryActions.GROUPED_OBJECTS, + () => { + objectsForGroup.forEach((object, idx) => { + object.group = undoGroups[idx]; + }); + }, + () => { + objectsForGroup.forEach((object, idx) => { + object.group = redoGroups[idx]; + }); + }, + objectsForGroup.map((object) => object.clientID), + objectStates[0].frame, + ); return groupIdx; } @@ -629,9 +615,7 @@ } else if (object instanceof Tag) { objectType = 'tag'; } else { - throw new ScriptingError( - `Unexpected object type: "${objectType}"`, - ); + throw new ScriptingError(`Unexpected object type: "${objectType}"`); } const label = object.label.name; @@ -645,7 +629,8 @@ if (objectType === 'track') { const keyframes = Object.keys(object.shapes) - .sort((a, b) => +a - +b).map((el) => +el); + .sort((a, b) => +a - +b) + .map((el) => +el); let prevKeyframe = keyframes[0]; let visible = false; @@ -680,7 +665,7 @@ for (const label of Object.keys(labels)) { for (const key of Object.keys(labels[label])) { - if (typeof (labels[label][key]) === 'object') { + if (typeof labels[label][key] === 'object') { for (const objectType of Object.keys(labels[label][key])) { total[key][objectType] += labels[label][key][objectType]; } @@ -723,8 +708,7 @@ checkObjectType('state attributes', state.attributes, null, Object); checkObjectType('state label', state.label, null, Label); - const attributes = Object.keys(state.attributes) - .reduce(convertAttributes.bind(state), []); + const attributes = Object.keys(state.attributes).reduce(convertAttributes.bind(state), []); const labelAttributes = state.label.attributes.reduce((accumulator, attribute) => { accumulator[attribute.id] = attribute; return accumulator; @@ -749,8 +733,7 @@ if (!Object.values(ObjectShape).includes(state.shapeType)) { throw new ArgumentError( - 'Object shape must be one of: ' - + `${JSON.stringify(Object.values(ObjectShape))}`, + `Object shape must be one of: ${JSON.stringify(Object.values(ObjectShape))}`, ); } @@ -768,27 +751,26 @@ }); } else if (state.objectType === 'track') { constructed.tracks.push({ - attributes: attributes - .filter((attr) => !labelAttributes[attr.spec_id].mutable), + attributes: attributes.filter((attr) => !labelAttributes[attr.spec_id].mutable), frame: state.frame, group: 0, source: state.source, label_id: state.label.id, - shapes: [{ - attributes: attributes - .filter((attr) => labelAttributes[attr.spec_id].mutable), - frame: state.frame, - occluded: state.occluded || false, - outside: false, - points: [...state.points], - type: state.shapeType, - z_order: state.zOrder, - }], + shapes: [ + { + attributes: attributes.filter((attr) => labelAttributes[attr.spec_id].mutable), + frame: state.frame, + occluded: state.occluded || false, + outside: false, + points: [...state.points], + type: state.shapeType, + z_order: state.zOrder, + }, + ], }); } else { throw new ArgumentError( - 'Object type must be one of: ' - + `${JSON.stringify(Object.values(ObjectType))}`, + `Object type must be one of: ${JSON.stringify(Object.values(ObjectType))}`, ); } } @@ -796,20 +778,24 @@ // Add constructed objects to a collection const imported = this.import(constructed); - const importedArray = imported.tags - .concat(imported.tracks) - .concat(imported.shapes); + const importedArray = imported.tags.concat(imported.tracks).concat(imported.shapes); if (objectStates.length) { - this.history.do(HistoryActions.CREATED_OBJECTS, () => { - importedArray.forEach((object) => { - object.removed = true; - }); - }, () => { - importedArray.forEach((object) => { - object.removed = false; - }); - }, importedArray.map((object) => object.clientID), objectStates[0].frame); + this.history.do( + HistoryActions.CREATED_OBJECTS, + () => { + importedArray.forEach((object) => { + object.removed = true; + }); + }, + () => { + importedArray.forEach((object) => { + object.removed = false; + }); + }, + importedArray.map((object) => object.clientID), + objectStates[0].frame, + ); } return importedArray.map((value) => value.clientID); @@ -829,14 +815,11 @@ } const object = this.objects[state.clientID]; - if (typeof (object) === 'undefined') { - throw new ArgumentError( - 'The object has not been saved yet. Call annotations.put([state]) before', - ); + if (typeof object === 'undefined') { + throw new ArgumentError('The object has not been saved yet. Call annotations.put([state]) before'); } const distance = object.constructor.distance(state.points, x, y); - if (distance !== null && (minimumDistance === null - || distance < minimumDistance)) { + if (distance !== null && (minimumDistance === null || distance < minimumDistance)) { minimumDistance = distance; minimumState = state; } @@ -848,14 +831,47 @@ }; } + searchEmpty(frameFrom, frameTo) { + const sign = Math.sign(frameTo - frameFrom); + const predicate = sign > 0 ? (frame) => frame <= frameTo : (frame) => frame >= frameTo; + const update = sign > 0 ? (frame) => frame + 1 : (frame) => frame - 1; + for (let frame = frameFrom; predicate(frame); frame = update(frame)) { + if (frame in this.shapes && this.shapes[frame].some((shape) => !shape.removed)) { + continue; + } + if (frame in this.tags && this.tags[frame].some((tag) => !tag.removed)) { + continue; + } + const filteredTracks = this.tracks.filter((track) => !track.removed); + let found = false; + for (const track of filteredTracks) { + const keyframes = track.boundedKeyframes(frame); + const { prev, first } = keyframes; + const last = prev === null ? first : prev; + const lastShape = track.shapes[last]; + const isKeyfame = frame in track.shapes; + if (first <= frame && (!lastShape.outside || isKeyfame)) { + found = true; + break; + } + } + + if (found) continue; + + return frame; + } + + return null; + } + search(filters, frameFrom, frameTo) { const [groups, query] = this.annotationsFilter.toJSONQuery(filters); const sign = Math.sign(frameTo - frameFrom); const flattenedQuery = groups.flat(Number.MAX_SAFE_INTEGER); - const containsDifficultProperties = flattenedQuery - .some((fragment) => fragment - .match(/^width/) || fragment.match(/^height/)); + const containsDifficultProperties = flattenedQuery.some( + (fragment) => fragment.match(/^width/) || fragment.match(/^height/), + ); const deepSearch = (deepSearchFrom, deepSearchTo) => { // deepSearchFrom is expected to be a frame that doesn't satisfy a filter @@ -878,12 +894,8 @@ }; const keyframesMemory = {}; - const predicate = sign > 0 - ? (frame) => frame <= frameTo - : (frame) => frame >= frameTo; - const update = sign > 0 - ? (frame) => frame + 1 - : (frame) => frame - 1; + const predicate = sign > 0 ? (frame) => frame <= frameTo : (frame) => frame >= frameTo; + const update = sign > 0 ? (frame) => frame + 1 : (frame) => frame - 1; for (let frame = frameFrom; predicate(frame); frame = update(frame)) { // First prepare all data for the frame // Consider all shapes, tags, and not outside tracks that have keyframe here @@ -897,15 +909,9 @@ .map((tag) => tag.get(frame)), ); const tracks = Object.values(this.tracks) - .filter((track) => ( - frame in track.shapes - || frame === frameFrom - || frame === frameTo - )).filter((track) => !track.removed); - statesData.push( - ...tracks.map((track) => track.get(frame)) - .filter((state) => !state.outside), - ); + .filter((track) => frame in track.shapes || frame === frameFrom || frame === frameTo) + .filter((track) => !track.removed); + statesData.push(...tracks.map((track) => track.get(frame)).filter((state) => !state.outside)); // Nothing to filtering, go to the next iteration if (!statesData.length) { @@ -926,12 +932,8 @@ for (const track of tracks) { const trackIsSatisfy = filtered.includes(track.clientID); if (!trackIsSatisfy) { - keyframesMemory[track.clientID] = [ - filtered.includes(track.clientID), - frame, - ]; - } else if (keyframesMemory[track.clientID] - && keyframesMemory[track.clientID][0] === false) { + keyframesMemory[track.clientID] = [filtered.includes(track.clientID), frame]; + } else if (keyframesMemory[track.clientID] && keyframesMemory[track.clientID][0] === false) { withDeepSearch = true; } } @@ -939,9 +941,7 @@ if (withDeepSearch) { const reducer = sign > 0 ? Math.min : Math.max; - const deepSearchFrom = reducer( - ...Object.values(keyframesMemory).map((value) => value[1]), - ); + const deepSearchFrom = reducer(...Object.values(keyframesMemory).map((value) => value[1])); return deepSearch(deepSearchFrom, frame); } diff --git a/cvat-core/src/annotations-filter.js b/cvat-core/src/annotations-filter.js index 6fc0b377..f3e948cb 100644 --- a/cvat-core/src/annotations-filter.js +++ b/cvat-core/src/annotations-filter.js @@ -1,20 +1,11 @@ -/* -* Copyright (C) 2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const jsonpath = require('jsonpath'); -const { - AttributeType, - ObjectType, -} = require('./enums'); +const { AttributeType, ObjectType } = require('./enums'); const { ArgumentError } = require('./exceptions'); - class AnnotationsFilter { constructor() { // eslint-disable-next-line security/detect-unsafe-regex @@ -47,8 +38,7 @@ class AnnotationsFilter { if (operators.includes(expression[i])) { if (!nestedCounter) { - const subexpression = expression - .substr(start + 1, i - start - 1).trim(); + const subexpression = expression.substr(start + 1, i - start - 1).trim(); splitted.push(subexpression); splitted.push(expression[i]); start = i; @@ -56,18 +46,14 @@ class AnnotationsFilter { } } - const subexpression = expression - .substr(start + 1).trim(); + const subexpression = expression.substr(start + 1).trim(); splitted.push(subexpression); splitted.forEach((internalExpression) => { if (internalExpression === '|' || internalExpression === '&') { container.push(internalExpression); } else { - this._groupByBrackets( - container, - internalExpression, - ); + this._groupByBrackets(container, internalExpression); } }); } @@ -103,12 +89,8 @@ class AnnotationsFilter { endBracket = i; const subcontainer = []; - const subexpression = expression - .substr(startBracket + 1, endBracket - 1 - startBracket); - this._splitWithOperator( - subcontainer, - subexpression, - ); + const subexpression = expression.substr(startBracket + 1, endBracket - 1 - startBracket); + this._splitWithOperator(subcontainer, subexpression); container.push(subcontainer); @@ -136,7 +118,7 @@ class AnnotationsFilter { for (const group of groups) { if (Array.isArray(group)) { expression += `(${this._join(group)})`; - } else if (typeof (group) === 'string') { + } else if (typeof group === 'string') { // it can be operator or expression if (group === '|' || group === '&') { expression += group; @@ -158,11 +140,10 @@ class AnnotationsFilter { _convertObjects(statesData) { const objects = statesData.map((state) => { - const labelAttributes = state.label.attributes - .reduce((acc, attr) => { - acc[attr.id] = attr; - return acc; - }, {}); + const labelAttributes = state.label.attributes.reduce((acc, attr) => { + acc[attr.id] = attr; + return acc; + }, {}); let xtl = Number.MAX_SAFE_INTEGER; let xbr = Number.MIN_SAFE_INTEGER; @@ -172,10 +153,12 @@ class AnnotationsFilter { if (state.objectType !== ObjectType.TAG) { state.points.forEach((coord, idx) => { - if (idx % 2) { // y + if (idx % 2) { + // y ytl = Math.min(ytl, coord); ybr = Math.max(ybr, coord); - } else { // x + } else { + // x xtl = Math.min(xtl, coord); xbr = Math.max(xbr, coord); } @@ -216,7 +199,7 @@ class AnnotationsFilter { toJSONQuery(filters) { try { - if (!Array.isArray(filters) || filters.some((value) => typeof (value) !== 'string')) { + if (!Array.isArray(filters) || filters.some((value) => typeof value !== 'string')) { throw Error('Argument must be an array of strings'); } @@ -225,7 +208,10 @@ class AnnotationsFilter { } const groups = []; - const expression = filters.map((filter) => `(${filter})`).join('|').replace(/\\"/g, '`'); + const expression = filters + .map((filter) => `(${filter})`) + .join('|') + .replace(/\\"/g, '`'); this._splitWithOperator(groups, expression); return [groups, `$.objects[?(${this._join(groups)})].clientID`]; } catch (error) { diff --git a/cvat-core/src/annotations-history.js b/cvat-core/src/annotations-history.js index 4fdbf34c..5cb5ffb8 100644 --- a/cvat-core/src/annotations-history.js +++ b/cvat-core/src/annotations-history.js @@ -1,15 +1,19 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const MAX_HISTORY_LENGTH = 128; class AnnotationHistory { constructor() { + this.frozen = false; this.clear(); } + freeze(frozen) { + this.frozen = frozen; + } + get() { return { undo: this._undo.map((undo) => [undo.action, undo.frame]), @@ -18,6 +22,7 @@ class AnnotationHistory { } do(action, undo, redo, clientIDs, frame) { + if (this.frozen) return; const actionItem = { clientIDs, action, diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index 752670fe..7f5910e4 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -1,32 +1,15 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ - +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const ObjectState = require('./object-state'); + const { checkObjectType } = require('./common'); const { - checkObjectType, - } = require('./common'); - const { - colors, - Source, - ObjectShape, - ObjectType, - AttributeType, - HistoryActions, + colors, Source, ObjectShape, ObjectType, AttributeType, HistoryActions, } = require('./enums'); - const { - DataError, - ArgumentError, - ScriptingError, - } = require('./exceptions'); + const { DataError, ArgumentError, ScriptingError } = require('./exceptions'); const { Label } = require('./labels'); @@ -48,38 +31,26 @@ function checkNumberOfPoints(shapeType, points) { if (shapeType === ObjectShape.RECTANGLE) { if (points.length / 2 !== 2) { - throw new DataError( - `Rectangle must have 2 points, but got ${points.length / 2}`, - ); + throw new DataError(`Rectangle must have 2 points, but got ${points.length / 2}`); } } else if (shapeType === ObjectShape.POLYGON) { if (points.length / 2 < 3) { - throw new DataError( - `Polygon must have at least 3 points, but got ${points.length / 2}`, - ); + throw new DataError(`Polygon must have at least 3 points, but got ${points.length / 2}`); } } else if (shapeType === ObjectShape.POLYLINE) { if (points.length / 2 < 2) { - throw new DataError( - `Polyline must have at least 2 points, but got ${points.length / 2}`, - ); + throw new DataError(`Polyline must have at least 2 points, but got ${points.length / 2}`); } } else if (shapeType === ObjectShape.POINTS) { if (points.length / 2 < 1) { - throw new DataError( - `Points must have at least 1 points, but got ${points.length / 2}`, - ); + throw new DataError(`Points must have at least 1 points, but got ${points.length / 2}`); } } else if (shapeType === ObjectShape.CUBOID) { if (points.length / 2 !== 8) { - throw new DataError( - `Points must have exact 8 points, but got ${points.length / 2}`, - ); + throw new DataError(`Points must have exact 8 points, but got ${points.length / 2}`); } } else { - throw new ArgumentError( - `Unknown value of shapeType has been recieved ${shapeType}`, - ); + throw new ArgumentError(`Unknown value of shapeType has been recieved ${shapeType}`); } } @@ -104,10 +75,7 @@ } if (shapeType === ObjectShape.POLYLINE) { - const length = Math.max( - xmax - xmin, - ymax - ymin, - ); + const length = Math.max(xmax - xmin, ymax - ymin); return length >= MIN_SHAPE_LENGTH; } @@ -126,10 +94,7 @@ checkObjectType('coordinate', x, 'number', null); checkObjectType('coordinate', y, 'number', null); - fittedPoints.push( - Math.clamp(x, 0, maxX), - Math.clamp(y, 0, maxY), - ); + fittedPoints.push(Math.clamp(x, 0, maxX), Math.clamp(y, 0, maxY)); } return shapeType === ObjectShape.CUBOID ? points : fittedPoints; @@ -149,15 +114,12 @@ const { values } = attr; const type = attr.inputType; - if (typeof (value) !== 'string') { - throw new ArgumentError( - `Attribute value is expected to be string, but got ${typeof (value)}`, - ); + if (typeof value !== 'string') { + throw new ArgumentError(`Attribute value is expected to be string, but got ${typeof value}`); } if (type === AttributeType.NUMBER) { - return +value >= +values[0] - && +value <= +values[1]; + return +value >= +values[0] && +value <= +values[1]; } if (type === AttributeType.CHECKBOX) { @@ -190,25 +152,27 @@ attributeAccumulator[attr.spec_id] = attr.value; return attributeAccumulator; }, {}); - this.groupObject = Object.defineProperties({}, { - color: { - get: () => { - if (this.group) { - return this.groupColors[this.group] - || colors[this.group % colors.length]; - } - return defaultGroupColor; + this.groupObject = Object.defineProperties( + {}, + { + color: { + get: () => { + if (this.group) { + return this.groupColors[this.group] || colors[this.group % colors.length]; + } + return defaultGroupColor; + }, + set: (newColor) => { + if (this.group && typeof newColor === 'string' && /^#[0-9A-F]{6}$/i.test(newColor)) { + this.groupColors[this.group] = newColor; + } + }, }, - set: (newColor) => { - if (this.group && typeof (newColor) === 'string' && /^#[0-9A-F]{6}$/i.test(newColor)) { - this.groupColors[this.group] = newColor; - } + id: { + get: () => this.group, }, }, - id: { - get: () => this.group, - }, - }); + ); this.appendDefaultAttributes(this.label); injection.groups.max = Math.max(injection.groups.max, this.group); @@ -218,13 +182,19 @@ const undoLock = this.lock; const redoLock = lock; - this.history.do(HistoryActions.CHANGED_LOCK, () => { - this.lock = undoLock; - this.updated = Date.now(); - }, () => { - this.lock = redoLock; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_LOCK, + () => { + this.lock = undoLock; + this.updated = Date.now(); + }, + () => { + this.lock = redoLock; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.lock = lock; } @@ -233,13 +203,19 @@ const undoColor = this.color; const redoColor = color; - this.history.do(HistoryActions.CHANGED_COLOR, () => { - this.color = undoColor; - this.updated = Date.now(); - }, () => { - this.color = redoColor; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_COLOR, + () => { + this.color = undoColor; + this.updated = Date.now(); + }, + () => { + this.color = redoColor; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.color = color; } @@ -248,13 +224,19 @@ const undoHidden = this.hidden; const redoHidden = hidden; - this.history.do(HistoryActions.CHANGED_HIDDEN, () => { - this.hidden = undoHidden; - this.updated = Date.now(); - }, () => { - this.hidden = redoHidden; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_HIDDEN, + () => { + this.hidden = undoHidden; + this.updated = Date.now(); + }, + () => { + this.hidden = redoHidden; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.hidden = hidden; } @@ -268,15 +250,21 @@ this.appendDefaultAttributes(label); const redoAttributes = { ...this.attributes }; - this.history.do(HistoryActions.CHANGED_LABEL, () => { - this.label = undoLabel; - this.attributes = undoAttributes; - this.updated = Date.now(); - }, () => { - this.label = redoLabel; - this.attributes = redoAttributes; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_LABEL, + () => { + this.label = undoLabel; + this.attributes = undoAttributes; + this.updated = Date.now(); + }, + () => { + this.label = redoLabel; + this.attributes = redoAttributes; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } _saveAttributes(attributes, frame) { @@ -288,13 +276,19 @@ const redoAttributes = { ...this.attributes }; - this.history.do(HistoryActions.CHANGED_ATTRIBUTES, () => { - this.attributes = undoAttributes; - this.updated = Date.now(); - }, () => { - this.attributes = redoAttributes; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_ATTRIBUTES, + () => { + this.attributes = undoAttributes; + this.updated = Date.now(); + }, + () => { + this.attributes = redoAttributes; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } _validateStateBeforeSave(frame, data, updated) { @@ -304,11 +298,10 @@ checkObjectType('label', data.label, null, Label); } - const labelAttributes = data.label.attributes - .reduce((accumulator, value) => { - accumulator[value.id] = value; - return accumulator; - }, {}); + const labelAttributes = data.label.attributes.reduce((accumulator, value) => { + accumulator[value.id] = value; + return accumulator; + }, {}); if (updated.attributes) { for (const attrID of Object.keys(data.attributes)) { @@ -334,9 +327,7 @@ const { width, height } = this.frameMeta[frame]; fittedPoints = fitPoints(this.shapeType, data.points, width, height); - if ((!checkShapeArea(this.shapeType, fittedPoints)) - || checkOutside(fittedPoints, width, height) - ) { + if (!checkShapeArea(this.shapeType, fittedPoints) || checkOutside(fittedPoints, width, height)) { fittedPoints = []; } } @@ -364,9 +355,7 @@ if (updated.color) { checkObjectType('color', data.color, 'string', null); if (!/^#[0-9A-F]{6}$/i.test(data.color)) { - throw new ArgumentError( - `Got invalid color value: "${data.color}"`, - ); + throw new ArgumentError(`Got invalid color value: "${data.color}"`); } } @@ -396,9 +385,16 @@ } updateTimestamp(updated) { - const anyChanges = updated.label || updated.attributes || updated.points - || updated.outside || updated.occluded || updated.keyframe - || updated.zOrder || updated.hidden || updated.lock || updated.pinned; + const anyChanges = updated.label + || updated.attributes + || updated.points + || updated.outside + || updated.occluded + || updated.keyframe + || updated.zOrder + || updated.hidden + || updated.lock + || updated.pinned; if (anyChanges) { this.updated = Date.now(); @@ -409,14 +405,20 @@ if (!this.lock || force) { this.removed = true; - this.history.do(HistoryActions.REMOVED_OBJECT, () => { - this.serverID = undefined; - this.removed = false; - this.updated = Date.now(); - }, () => { - this.removed = true; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.REMOVED_OBJECT, + () => { + this.serverID = undefined; + this.removed = false; + this.updated = Date.now(); + }, + () => { + this.removed = true; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } return this.removed; @@ -436,33 +438,33 @@ const undoPinned = this.pinned; const redoPinned = pinned; - this.history.do(HistoryActions.CHANGED_PINNED, () => { - this.pinned = undoPinned; - this.updated = Date.now(); - }, () => { - this.pinned = redoPinned; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_PINNED, + () => { + this.pinned = undoPinned; + this.updated = Date.now(); + }, + () => { + this.pinned = redoPinned; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.pinned = pinned; } save() { - throw new ScriptingError( - 'Is not implemented', - ); + throw new ScriptingError('Is not implemented'); } get() { - throw new ScriptingError( - 'Is not implemented', - ); + throw new ScriptingError('Is not implemented'); } toJSON() { - throw new ScriptingError( - 'Is not implemented', - ); + throw new ScriptingError('Is not implemented'); } } @@ -501,9 +503,7 @@ // Method is used to construct ObjectState objects get(frame) { if (frame !== this.frame) { - throw new ScriptingError( - 'Got frame is not equal to the frame of the shape', - ); + throw new ScriptingError('Got frame is not equal to the frame of the shape'); } return { @@ -533,15 +533,21 @@ const undoSource = this.source; const redoSource = Source.MANUAL; - this.history.do(HistoryActions.CHANGED_POINTS, () => { - this.points = undoPoints; - this.source = undoSource; - this.updated = Date.now(); - }, () => { - this.points = redoPoints; - this.source = redoSource; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_POINTS, + () => { + this.points = undoPoints; + this.source = undoSource; + this.updated = Date.now(); + }, + () => { + this.points = redoPoints; + this.source = redoSource; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.source = Source.MANUAL; this.points = points; @@ -553,15 +559,21 @@ const undoSource = this.source; const redoSource = Source.MANUAL; - this.history.do(HistoryActions.CHANGED_OCCLUDED, () => { - this.occluded = undoOccluded; - this.source = undoSource; - this.updated = Date.now(); - }, () => { - this.occluded = redoOccluded; - this.source = redoSource; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_OCCLUDED, + () => { + this.occluded = undoOccluded; + this.source = undoSource; + this.updated = Date.now(); + }, + () => { + this.occluded = redoOccluded; + this.source = redoSource; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.source = Source.MANUAL; this.occluded = occluded; @@ -573,15 +585,21 @@ const undoSource = this.source; const redoSource = Source.MANUAL; - this.history.do(HistoryActions.CHANGED_ZORDER, () => { - this.zOrder = undoZOrder; - this.source = undoSource; - this.updated = Date.now(); - }, () => { - this.zOrder = redoZOrder; - this.source = redoSource; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_ZORDER, + () => { + this.zOrder = undoZOrder; + this.source = undoSource; + this.updated = Date.now(); + }, + () => { + this.zOrder = redoZOrder; + this.source = redoSource; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); this.source = Source.MANUAL; this.zOrder = zOrder; @@ -589,9 +607,7 @@ save(frame, data) { if (frame !== this.frame) { - throw new ScriptingError( - 'Got frame is not equal to the frame of the shape', - ); + throw new ScriptingError('Got frame is not equal to the frame of the shape'); } if (this.lock && data.lock) { @@ -696,8 +712,8 @@ z_order: this.shapes[frame].zOrder, points: [...this.shapes[frame].points], outside: this.shapes[frame].outside, - attributes: Object.keys(this.shapes[frame].attributes) - .reduce((attributeAccumulator, attrId) => { + attributes: Object.keys(this.shapes[frame].attributes).reduce( + (attributeAccumulator, attrId) => { if (labelAttributes[attrId].mutable) { attributeAccumulator.push({ spec_id: attrId, @@ -706,7 +722,9 @@ } return attributeAccumulator; - }, []), + }, + [], + ), id: this.shapes[frame].serverID, frame: +frame, }); @@ -719,10 +737,7 @@ // Method is used to construct ObjectState objects get(frame) { const { - prev, - next, - first, - last, + prev, next, first, last, } = this.boundedKeyframes(frame); return { @@ -838,30 +853,35 @@ })), }; - this.history.do(HistoryActions.CHANGED_LABEL, () => { - this.label = undoLabel; - this.attributes = undoAttributes.unmutable; - for (const mutable of undoAttributes.mutable) { - this.shapes[mutable.frame].attributes = mutable.attributes; - } - this.updated = Date.now(); - }, () => { - this.label = redoLabel; - this.attributes = redoAttributes.unmutable; - for (const mutable of redoAttributes.mutable) { - this.shapes[mutable.frame].attributes = mutable.attributes; - } - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_LABEL, + () => { + this.label = undoLabel; + this.attributes = undoAttributes.unmutable; + for (const mutable of undoAttributes.mutable) { + this.shapes[mutable.frame].attributes = mutable.attributes; + } + this.updated = Date.now(); + }, + () => { + this.label = redoLabel; + this.attributes = redoAttributes.unmutable; + for (const mutable of redoAttributes.mutable) { + this.shapes[mutable.frame].attributes = mutable.attributes; + } + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } _saveAttributes(attributes, frame) { const current = this.get(frame); - const labelAttributes = this.label.attributes - .reduce((accumulator, value) => { - accumulator[value.id] = value; - return accumulator; - }, {}); + const labelAttributes = this.label.attributes.reduce((accumulator, value) => { + accumulator[value.id] = value; + return accumulator; + }, {}); const wasKeyframe = frame in this.shapes; const undoAttributes = this.attributes; @@ -879,7 +899,7 @@ // keyframe, but without this attrID || !(attrID in this.shapes[frame].attributes) // keyframe with attrID, but with another value - || (this.shapes[frame].attributes[attrID] !== attributes[attrID]); + || this.shapes[frame].attributes[attrID] !== attributes[attrID]; } } let redoShape; @@ -904,8 +924,7 @@ } for (const attrID of Object.keys(attributes)) { - if (labelAttributes[attrID].mutable - && attributes[attrID] !== current.attributes[attrID]) { + if (labelAttributes[attrID].mutable && attributes[attrID] !== current.attributes[attrID]) { redoShape.attributes[attrID] = attributes[attrID]; } } @@ -915,41 +934,53 @@ this.shapes[frame] = redoShape; } - this.history.do(HistoryActions.CHANGED_ATTRIBUTES, () => { - this.attributes = undoAttributes; - if (undoShape) { - this.shapes[frame] = undoShape; - } else if (redoShape) { - delete this.shapes[frame]; - } - this.updated = Date.now(); - }, () => { - this.attributes = redoAttributes; - if (redoShape) { - this.shapes[frame] = redoShape; - } - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + HistoryActions.CHANGED_ATTRIBUTES, + () => { + this.attributes = undoAttributes; + if (undoShape) { + this.shapes[frame] = undoShape; + } else if (redoShape) { + delete this.shapes[frame]; + } + this.updated = Date.now(); + }, + () => { + this.attributes = redoAttributes; + if (redoShape) { + this.shapes[frame] = redoShape; + } + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } _appendShapeActionToHistory(actionType, frame, undoShape, redoShape, undoSource, redoSource) { - this.history.do(actionType, () => { - if (!undoShape) { - delete this.shapes[frame]; - } else { - this.shapes[frame] = undoShape; - } - this.source = undoSource; - this.updated = Date.now(); - }, () => { - if (!redoShape) { - delete this.shapes[frame]; - } else { - this.shapes[frame] = redoShape; - } - this.source = redoSource; - this.updated = Date.now(); - }, [this.clientID], frame); + this.history.do( + actionType, + () => { + if (!undoShape) { + delete this.shapes[frame]; + } else { + this.shapes[frame] = undoShape; + } + this.source = undoSource; + this.updated = Date.now(); + }, + () => { + if (!redoShape) { + delete this.shapes[frame]; + } else { + this.shapes[frame] = redoShape; + } + this.source = redoSource; + this.updated = Date.now(); + }, + [this.clientID], + frame, + ); } _savePoints(points, frame) { @@ -958,14 +989,16 @@ const undoSource = this.source; const redoSource = Source.MANUAL; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], points } : { - frame, - points, - zOrder: current.zOrder, - outside: current.outside, - occluded: current.occluded, - attributes: {}, - }; + const redoShape = wasKeyframe + ? { ...this.shapes[frame], points } + : { + frame, + points, + zOrder: current.zOrder, + outside: current.outside, + occluded: current.occluded, + attributes: {}, + }; this.shapes[frame] = redoShape; this.source = Source.MANUAL; @@ -985,14 +1018,16 @@ const undoSource = this.source; const redoSource = Source.MANUAL; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], outside } : { - frame, - outside, - zOrder: current.zOrder, - points: current.points, - occluded: current.occluded, - attributes: {}, - }; + const redoShape = wasKeyframe + ? { ...this.shapes[frame], outside } + : { + frame, + outside, + zOrder: current.zOrder, + points: current.points, + occluded: current.occluded, + attributes: {}, + }; this.shapes[frame] = redoShape; this.source = Source.MANUAL; @@ -1012,14 +1047,16 @@ const undoSource = this.source; const redoSource = Source.MANUAL; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], occluded } : { - frame, - occluded, - zOrder: current.zOrder, - points: current.points, - outside: current.outside, - attributes: {}, - }; + const redoShape = wasKeyframe + ? { ...this.shapes[frame], occluded } + : { + frame, + occluded, + zOrder: current.zOrder, + points: current.points, + outside: current.outside, + attributes: {}, + }; this.shapes[frame] = redoShape; this.source = Source.MANUAL; @@ -1039,14 +1076,16 @@ const undoSource = this.source; const redoSource = Source.MANUAL; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], zOrder } : { - frame, - zOrder, - occluded: current.occluded, - points: current.points, - outside: current.outside, - attributes: {}, - }; + const redoShape = wasKeyframe + ? { ...this.shapes[frame], zOrder } + : { + frame, + zOrder, + occluded: current.occluded, + points: current.points, + outside: current.outside, + attributes: {}, + }; this.shapes[frame] = redoShape; this.source = Source.MANUAL; @@ -1064,23 +1103,24 @@ const current = this.get(frame); const wasKeyframe = frame in this.shapes; - if ((keyframe && wasKeyframe) - || (!keyframe && !wasKeyframe)) { + if ((keyframe && wasKeyframe) || (!keyframe && !wasKeyframe)) { return; } const undoSource = this.source; const redoSource = Source.MANUAL; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = keyframe ? { - frame, - zOrder: current.zOrder, - points: current.points, - outside: current.outside, - occluded: current.occluded, - attributes: {}, - source: current.source, - } : undefined; + const redoShape = keyframe + ? { + frame, + zOrder: current.zOrder, + points: current.points, + outside: current.outside, + occluded: current.occluded, + attributes: {}, + source: current.source, + } + : undefined; this.source = Source.MANUAL; if (redoShape) { @@ -1195,7 +1235,7 @@ throw new DataError( 'No one left position or right position was found. ' - + `Interpolation impossible. Client ID: ${this.clientID}`, + + `Interpolation impossible. Client ID: ${this.clientID}`, ); } } @@ -1228,9 +1268,7 @@ // Method is used to construct ObjectState objects get(frame) { if (frame !== this.frame) { - throw new ScriptingError( - 'Got frame is not equal to the frame of the shape', - ); + throw new ScriptingError('Got frame is not equal to the frame of the shape'); } return { @@ -1250,9 +1288,7 @@ save(frame, data) { if (frame !== this.frame) { - throw new ScriptingError( - 'Got frame is not equal to the frame of the tag', - ); + throw new ScriptingError('Got frame is not equal to the frame of the tag'); } if (this.lock && data.lock) { @@ -1322,7 +1358,7 @@ static distance(points, x, y) { function position(x1, y1, x2, y2) { - return ((x2 - x1) * (y - y1) - (x - x1) * (y2 - y1)); + return (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1); } let wn = 0; @@ -1354,8 +1390,8 @@ // Find the shortest distance from point to an edge // Get an equation of a line in general - const aCoef = (y1 - y2); - const bCoef = (x2 - x1); + const aCoef = y1 - y2; + const bCoef = x2 - x1; // Vector (aCoef, bCoef) is a perpendicular to line // Now find the point where two lines @@ -1363,13 +1399,9 @@ const xCross = x - aCoef; const yCross = y - bCoef; - if (((xCross - x1) * (x2 - xCross)) >= 0 - && ((yCross - y1) * (y2 - yCross)) >= 0) { + if ((xCross - x1) * (x2 - xCross) >= 0 && (yCross - y1) * (y2 - yCross) >= 0) { // Cross point is on segment between p1(x1,y1) and p2(x2,y2) - distances.push(Math.sqrt( - Math.pow(x - xCross, 2) - + Math.pow(y - yCross, 2), - )); + distances.push(Math.sqrt(Math.pow(x - xCross, 2) + Math.pow(y - yCross, 2))); } else { distances.push( Math.min( @@ -1407,12 +1439,12 @@ const y2 = points[i + 3]; // Find the shortest distance from point to an edge - if (((x - x1) * (x2 - x)) >= 0 && ((y - y1) * (y2 - y)) >= 0) { + if ((x - x1) * (x2 - x) >= 0 && (y - y1) * (y2 - y) >= 0) { // Find the length of a perpendicular // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line distances.push( - Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) / Math - .sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)), + Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) + / Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)), ); } else { // The link below works for lines (which have infinit length) @@ -1445,9 +1477,7 @@ const x1 = points[i]; const y1 = points[i + 1]; - distances.push( - Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2)), - ); + distances.push(Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2))); } return Math.min.apply(null, distances); @@ -1497,11 +1527,12 @@ } lowerHull.pop(); - if (upperHull.length - === 1 && lowerHull.length - === 1 && upperHull[0].x - === lowerHull[0].x && upperHull[0].y - === lowerHull[0].y) return upperHull; + if ( + upperHull.length === 1 + && lowerHull.length === 1 + && upperHull[0].x === lowerHull[0].x + && upperHull[0].y === lowerHull[0].y + ) return upperHull; return upperHull.concat(lowerHull); } @@ -1520,7 +1551,7 @@ static contain(points, x, y) { function isLeft(P0, P1, P2) { - return ((P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y)); + return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y); } points = CuboidShape.makeHull(points); let wn = 0; @@ -1559,15 +1590,14 @@ const p2 = points[i + 1] || points[0]; // perpendicular from point to straight length - const distance = (Math.abs((p2.y - p1.y) * x - - (p2.x - p1.x) * y + p2.x * p1.y - p2.y * p1.x)) + const distance = Math.abs((p2.y - p1.y) * x - (p2.x - p1.x) * y + p2.x * p1.y - p2.y * p1.x) / Math.sqrt(Math.pow(p2.y - p1.y, 2) + Math.pow(p2.x - p1.x, 2)); // check if perpendicular belongs to the straight segment const a = Math.pow(p1.x - x, 2) + Math.pow(p1.y - y, 2); const b = Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2); const c = Math.pow(p2.x - x, 2) + Math.pow(p2.y - y, 2); - if (distance < minDistance && (a + b - c) >= 0 && (c + b - a) >= 0) { + if (distance < minDistance && a + b - c >= 0 && c + b - a >= 0) { minDistance = distance; } } @@ -1586,14 +1616,10 @@ } interpolatePosition(leftPosition, rightPosition, offset) { - const positionOffset = leftPosition.points.map((point, index) => ( - rightPosition.points[index] - point - )); + const positionOffset = leftPosition.points.map((point, index) => rightPosition.points[index] - point); return { - points: leftPosition.points.map((point, index) => ( - point + positionOffset[index] * offset - )), + points: leftPosition.points.map((point, index) => point + positionOffset[index] * offset), occluded: leftPosition.occluded, outside: leftPosition.outside, zOrder: leftPosition.zOrder, @@ -1681,7 +1707,8 @@ function matchRightLeft(leftCurve, rightCurve, leftRightMatching) { const matchedRightPoints = Object.values(leftRightMatching).flat(); - const unmatchedRightPoints = rightCurve.map((_, index) => index) + const unmatchedRightPoints = rightCurve + .map((_, index) => index) .filter((index) => !matchedRightPoints.includes(index)); const updatedMatching = { ...leftRightMatching }; @@ -1691,8 +1718,7 @@ } for (const key of Object.keys(updatedMatching)) { - const sortedRightIndexes = updatedMatching[key] - .sort((a, b) => a - b); + const sortedRightIndexes = updatedMatching[key].sort((a, b) => a - b); updatedMatching[key] = sortedRightIndexes; } @@ -1715,9 +1741,7 @@ } function computeDistance(point1, point2) { - return Math.sqrt( - ((point1.x - point2.x) ** 2) + ((point1.y - point2.y) ** 2), - ); + return Math.sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2); } function minimizeSegment(baseLength, N, startInterpolated, stopInterpolated) { @@ -1725,9 +1749,7 @@ const minimized = [interpolatedPoints[startInterpolated]]; let latestPushed = startInterpolated; for (let i = startInterpolated + 1; i < stopInterpolated; i++) { - const distance = computeDistance( - interpolatedPoints[latestPushed], interpolatedPoints[i], - ); + const distance = computeDistance(interpolatedPoints[latestPushed], interpolatedPoints[i]); if (distance >= threshold) { minimized.push(interpolatedPoints[i]); @@ -1771,9 +1793,7 @@ const baseLength = curveLength(leftPoints.slice(start, stop + 1)); const N = stop - start + 1; - reduced.push( - ...minimizeSegment(baseLength, N, startInterpolated, stopInterpolated), - ); + reduced.push(...minimizeSegment(baseLength, N, startInterpolated, stopInterpolated)); } function rightSegment(leftPoint) { @@ -1784,9 +1804,7 @@ const baseLength = curveLength(rightPoints.slice(start, stop + 1)); const N = stop - start + 1; - reduced.push( - ...minimizeSegment(baseLength, N, startInterpolated, stopInterpolated), - ); + reduced.push(...minimizeSegment(baseLength, N, startInterpolated, stopInterpolated)); } let previousOpened = null; @@ -1842,12 +1860,11 @@ const rightOffsetVec = curveToOffsetVec(rightPoints, curveLength(rightPoints)); const matching = matchLeftRight(leftOffsetVec, rightOffsetVec); - const completedMatching = matchRightLeft( - leftOffsetVec, rightOffsetVec, matching, - ); + const completedMatching = matchRightLeft(leftOffsetVec, rightOffsetVec, matching); const interpolatedPoints = Object.keys(completedMatching) - .map((leftPointIdx) => +leftPointIdx).sort((a, b) => a - b) + .map((leftPointIdx) => +leftPointIdx) + .sort((a, b) => a - b) .reduce((acc, leftPointIdx) => { const leftPoint = leftPoints[leftPointIdx]; for (const rightPointIdx of completedMatching[leftPointIdx]) { @@ -1861,12 +1878,7 @@ return acc; }, []); - const reducedPoints = reduceInterpolation( - interpolatedPoints, - completedMatching, - leftPoints, - rightPoints, - ); + const reducedPoints = reduceInterpolation(interpolatedPoints, completedMatching, leftPoints, rightPoints); return { points: toArray(reducedPoints), @@ -1897,8 +1909,7 @@ points: [...rightPosition.points, rightPosition.points[0], rightPosition.points[1]], }; - const result = PolyTrack.prototype.interpolatePosition - .call(this, copyLeft, copyRight, offset); + const result = PolyTrack.prototype.interpolatePosition.call(this, copyLeft, copyRight, offset); return { ...result, @@ -1959,14 +1970,10 @@ } interpolatePosition(leftPosition, rightPosition, offset) { - const positionOffset = leftPosition.points.map((point, index) => ( - rightPosition.points[index] - point - )); + const positionOffset = leftPosition.points.map((point, index) => rightPosition.points[index] - point); return { - points: leftPosition.points.map((point, index) => ( - point + positionOffset[index] * offset - )), + points: leftPosition.points.map((point, index) => point + positionOffset[index] * offset), occluded: leftPosition.occluded, outside: leftPosition.outside, zOrder: leftPosition.zOrder, diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js index 779db776..92c01500 100644 --- a/cvat-core/src/annotations-saver.js +++ b/cvat-core/src/annotations-saver.js @@ -1,16 +1,11 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const serverProxy = require('./server-proxy'); const { Task } = require('./session'); - const { ScriptingError } = ('./exceptions'); + const { ScriptingError } = './exceptions'; class AnnotationsSaver { constructor(version, collection, session) { @@ -53,12 +48,7 @@ } async _request(data, action) { - const result = await serverProxy.annotations.updateAnnotations( - this.sessionType, - this.id, - data, - action, - ); + const result = await serverProxy.annotations.updateAnnotations(this.sessionType, this.id, data, action); return result; } @@ -102,27 +92,37 @@ }, }; - const keys = ['id', 'label_id', 'group', 'frame', - 'occluded', 'z_order', 'points', 'type', 'shapes', - 'attributes', 'value', 'spec_id', 'source', 'outside']; + const keys = [ + 'id', + 'label_id', + 'group', + 'frame', + 'occluded', + 'z_order', + 'points', + 'type', + 'shapes', + 'attributes', + 'value', + 'spec_id', + 'source', + 'outside', + ]; // Find created and updated objects for (const type of Object.keys(exported)) { for (const object of exported[type]) { if (object.id in this.initialObjects[type]) { const exportedHash = JSON.stringify(object, keys); - const initialHash = JSON.stringify( - this.initialObjects[type][object.id], keys, - ); + const initialHash = JSON.stringify(this.initialObjects[type][object.id], keys); if (exportedHash !== initialHash) { splitted.updated[type].push(object); } - } else if (typeof (object.id) === 'undefined') { + } else if (typeof object.id === 'undefined') { splitted.created[type].push(object); } else { throw new ScriptingError( - `Id of object is defined "${object.id}"` - + 'but it absents in initial state', + `Id of object is defined "${object.id}" but it absents in initial state`, ); } } @@ -144,21 +144,17 @@ } } - return splitted; } _updateCreatedObjects(saved, indexes) { - const savedLength = saved.tracks.length - + saved.shapes.length + saved.tags.length; + const savedLength = saved.tracks.length + saved.shapes.length + saved.tags.length; - const indexesLength = indexes.tracks.length - + indexes.shapes.length + indexes.tags.length; + const indexesLength = indexes.tracks.length + indexes.shapes.length + indexes.tags.length; if (indexesLength !== savedLength) { throw new ScriptingError( - 'Number of indexes is differed by number of saved objects' - + `${indexesLength} vs ${savedLength}`, + `Number of indexes is differed by number of saved objects ${indexesLength} vs ${savedLength}`, ); } @@ -180,7 +176,9 @@ }; // Remove them from the request body - exported.tracks.concat(exported.shapes).concat(exported.tags) + exported.tracks + .concat(exported.shapes) + .concat(exported.tags) .map((value) => { delete value.clientID; return value; @@ -214,11 +212,7 @@ } } } else { - const { - created, - updated, - deleted, - } = this._split(exported); + const { created, updated, deleted } = this._split(exported); onUpdate('Created objects are being saved on the server'); const indexes = this._receiveIndexes(created); diff --git a/cvat-core/src/annotations.js b/cvat-core/src/annotations.js index 9d7eadbf..991ee33e 100644 --- a/cvat-core/src/annotations.js +++ b/cvat-core/src/annotations.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const serverProxy = require('./server-proxy'); @@ -14,15 +9,8 @@ const AnnotationsHistory = require('./annotations-history'); const { checkObjectType } = require('./common'); const { Task } = require('./session'); - const { - Loader, - Dumper, - } = require('./annotation-formats.js'); - const { - ScriptingError, - DataError, - ArgumentError, - } = require('./exceptions'); + const { Loader, Dumper } = require('./annotation-formats'); + const { ScriptingError, DataError, ArgumentError } = require('./exceptions'); const jobCache = new WeakMap(); const taskCache = new WeakMap(); @@ -36,9 +24,7 @@ return jobCache; } - throw new ScriptingError( - `Unknown session type was received ${sessionType}`, - ); + throw new ScriptingError(`Unknown session type was received ${sessionType}`); } async function getAnnotationsFromServer(session) { @@ -46,8 +32,7 @@ const cache = getCache(sessionType); if (!cache.has(session)) { - const rawAnnotations = await serverProxy.annotations - .getAnnotations(sessionType, session.id); + const rawAnnotations = await serverProxy.annotations.getAnnotations(sessionType, session.id); // Get meta information about frames const startFrame = sessionType === 'job' ? session.startFrame : 0; @@ -122,6 +107,19 @@ ); } + function searchEmptyFrame(session, frameFrom, frameTo) { + const sessionType = session instanceof Task ? 'task' : 'job'; + const cache = getCache(sessionType); + + if (cache.has(session)) { + return cache.get(session).collection.searchEmpty(frameFrom, frameTo); + } + + throw new DataError( + 'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before', + ); + } + function mergeAnnotations(session, objectStates) { const sessionType = session instanceof Task ? 'task' : 'job'; const cache = getCache(sessionType); @@ -229,28 +227,22 @@ async function uploadAnnotations(session, file, loader) { const sessionType = session instanceof Task ? 'task' : 'job'; if (!(loader instanceof Loader)) { - throw new ArgumentError( - 'A loader must be instance of Loader class', - ); + throw new ArgumentError('A loader must be instance of Loader class'); } await serverProxy.annotations.uploadAnnotations(sessionType, session.id, file, loader.name); } async function dumpAnnotations(session, name, dumper) { if (!(dumper instanceof Dumper)) { - throw new ArgumentError( - 'A dumper must be instance of Dumper class', - ); + throw new ArgumentError('A dumper must be instance of Dumper class'); } let result = null; const sessionType = session instanceof Task ? 'task' : 'job'; if (sessionType === 'job') { - result = await serverProxy.annotations - .dumpAnnotations(session.task.id, name, dumper.name); + result = await serverProxy.annotations.dumpAnnotations(session.task.id, name, dumper.name); } else { - result = await serverProxy.annotations - .dumpAnnotations(session.id, name, dumper.name); + result = await serverProxy.annotations.dumpAnnotations(session.id, name, dumper.name); } return result; @@ -284,19 +276,14 @@ async function exportDataset(session, format) { if (!(format instanceof String || typeof format === 'string')) { - throw new ArgumentError( - 'Format must be a string', - ); + throw new ArgumentError('Format must be a string'); } if (!(session instanceof Task)) { - throw new ArgumentError( - 'A dataset can only be created from a task', - ); + throw new ArgumentError('A dataset can only be created from a task'); } let result = null; - result = await serverProxy.tasks - .exportDataset(session.id, format); + result = await serverProxy.tasks.exportDataset(session.id, format); return result; } @@ -327,6 +314,19 @@ ); } + function freezeHistory(session, frozen) { + const sessionType = session instanceof Task ? 'task' : 'job'; + const cache = getCache(sessionType); + + if (cache.has(session)) { + return cache.get(session).history.freeze(frozen); + } + + throw new DataError( + 'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before', + ); + } + function clearActions(session) { const sessionType = session instanceof Task ? 'task' : 'job'; const cache = getCache(sessionType); @@ -360,6 +360,7 @@ hasUnsavedChanges, mergeAnnotations, searchAnnotations, + searchEmptyFrame, splitAnnotations, groupAnnotations, clearAnnotations, @@ -372,6 +373,7 @@ exportDataset, undoActions, redoActions, + freezeHistory, clearActions, getActions, closeSession, diff --git a/cvat-core/src/api-implementation.js b/cvat-core/src/api-implementation.js index 5fc7958c..f3e2aa26 100644 --- a/cvat-core/src/api-implementation.js +++ b/cvat-core/src/api-implementation.js @@ -1,52 +1,22 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ] */ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const PluginRegistry = require('./plugins'); const serverProxy = require('./server-proxy'); const lambdaManager = require('./lambda-manager'); const { - isBoolean, - isInteger, - isEnum, - isString, - checkFilter, + isBoolean, isInteger, isEnum, isString, checkFilter, } = require('./common'); const { TaskStatus, TaskMode } = require('./enums'); const User = require('./user'); - const { AnnotationFormats } = require('./annotation-formats.js'); + const { AnnotationFormats } = require('./annotation-formats'); const { ArgumentError } = require('./exceptions'); const { Task } = require('./session'); - - function attachUsers(task, users) { - if (task.assignee !== null) { - [task.assignee] = users.filter((user) => user.id === task.assignee); - } - - for (const segment of task.segments) { - for (const job of segment.jobs) { - if (job.assignee !== null) { - [job.assignee] = users.filter((user) => user.id === job.assignee); - } - } - } - - if (task.owner !== null) { - [task.owner] = users.filter((user) => user.id === task.owner); - } - - return task; - } + const { Project } = require('./project'); function implementAPI(cvat) { cvat.plugins.list.implementation = PluginRegistry.list; @@ -79,10 +49,24 @@ return result; }; - cvat.server.register.implementation = async (username, firstName, lastName, - email, password1, password2, userConfirmations) => { - const user = await serverProxy.server.register(username, firstName, - lastName, email, password1, password2, userConfirmations); + cvat.server.register.implementation = async ( + username, + firstName, + lastName, + email, + password1, + password2, + userConfirmations, + ) => { + const user = await serverProxy.server.register( + username, + firstName, + lastName, + email, + password1, + password2, + userConfirmations, + ); return new User(user); }; @@ -99,6 +83,14 @@ await serverProxy.server.changePassword(oldPassword, newPassword1, newPassword2); }; + cvat.server.requestPasswordReset.implementation = async (email) => { + await serverProxy.server.requestPasswordReset(email); + }; + + cvat.server.resetPassword.implementation = async (newPassword1, newPassword2, uid, token) => { + await serverProxy.server.resetPassword(newPassword1, newPassword2, uid, token); + }; + cvat.server.authorized.implementation = async () => { const result = await serverProxy.server.authorized(); return result; @@ -109,17 +101,31 @@ return result; }; + cvat.server.installedApps.implementation = async () => { + const result = await serverProxy.server.installedApps(); + return result; + }; + cvat.users.get.implementation = async (filter) => { checkFilter(filter, { + id: isInteger, self: isBoolean, + search: isString, + limit: isInteger, }); let users = null; if ('self' in filter && filter.self) { - users = await serverProxy.users.getSelf(); + users = await serverProxy.users.self(); users = [users]; } else { - users = await serverProxy.users.getUsers(); + const searchParams = {}; + for (const key in filter) { + if (filter[key] && key !== 'self') { + searchParams[key] = filter[key]; + } + } + users = await serverProxy.users.get(new URLSearchParams(searchParams).toString()); } users = users.map((user) => new User(user)); @@ -132,44 +138,37 @@ jobID: isInteger, }); - if (('taskID' in filter) && ('jobID' in filter)) { - throw new ArgumentError( - 'Only one of fields "taskID" and "jobID" allowed simultaneously', - ); + if ('taskID' in filter && 'jobID' in filter) { + throw new ArgumentError('Only one of fields "taskID" and "jobID" allowed simultaneously'); } if (!Object.keys(filter).length) { - throw new ArgumentError( - 'Job filter must not be empty', - ); + throw new ArgumentError('Job filter must not be empty'); } - let tasks = null; + let tasks = []; if ('taskID' in filter) { tasks = await serverProxy.tasks.getTasks(`id=${filter.taskID}`); } else { - const job = await serverProxy.jobs.getJob(filter.jobID); - if (typeof (job.task_id) !== 'undefined') { + const job = await serverProxy.jobs.get(filter.jobID); + if (typeof job.task_id !== 'undefined') { tasks = await serverProxy.tasks.getTasks(`id=${job.task_id}`); } } // If task was found by its id, then create task instance and get Job instance from it - if (tasks !== null && tasks.length) { - const users = (await serverProxy.users.getUsers()) - .map((userData) => new User(userData)); - const task = new Task(attachUsers(tasks[0], users)); - - return filter.jobID ? task.jobs - .filter((job) => job.id === filter.jobID) : task.jobs; + if (tasks.length) { + const task = new Task(tasks[0]); + return filter.jobID ? task.jobs.filter((job) => job.id === filter.jobID) : task.jobs; } - return []; + return tasks; }; cvat.tasks.get.implementation = async (filter) => { checkFilter(filter, { page: isInteger, + projectId: isInteger, name: isString, id: isInteger, owner: isString, @@ -181,40 +180,79 @@ if ('search' in filter && Object.keys(filter).length > 1) { if (!('page' in filter && Object.keys(filter).length === 2)) { - throw new ArgumentError( - 'Do not use the filter field "search" with others', - ); + throw new ArgumentError('Do not use the filter field "search" with others'); } } if ('id' in filter && Object.keys(filter).length > 1) { if (!('page' in filter && Object.keys(filter).length === 2)) { - throw new ArgumentError( - 'Do not use the filter field "id" with others', - ); + throw new ArgumentError('Do not use the filter field "id" with others'); } } + if ( + 'projectId' in filter + && (('page' in filter && Object.keys(filter).length > 2) || Object.keys(filter).length > 2) + ) { + throw new ArgumentError('Do not use the filter field "projectId" with other'); + } + const searchParams = new URLSearchParams(); - for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page']) { + for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page', 'projectId']) { if (Object.prototype.hasOwnProperty.call(filter, field)) { searchParams.set(field, filter[field]); } } - const users = (await serverProxy.users.getUsers()) - .map((userData) => new User(userData)); const tasksData = await serverProxy.tasks.getTasks(searchParams.toString()); - const tasks = tasksData - .map((task) => attachUsers(task, users)) - .map((task) => new Task(task)); - + const tasks = tasksData.map((task) => new Task(task)); tasks.count = tasksData.count; return tasks; }; + cvat.projects.get.implementation = async (filter) => { + checkFilter(filter, { + id: isInteger, + page: isInteger, + name: isString, + assignee: isString, + owner: isString, + search: isString, + status: isEnum.bind(TaskStatus), + }); + + if ('search' in filter && Object.keys(filter).length > 1) { + if (!('page' in filter && Object.keys(filter).length === 2)) { + throw new ArgumentError('Do not use the filter field "search" with others'); + } + } + + if ('id' in filter && Object.keys(filter).length > 1) { + if (!('page' in filter && Object.keys(filter).length === 2)) { + throw new ArgumentError('Do not use the filter field "id" with others'); + } + } + + const searchParams = new URLSearchParams(); + for (const field of ['name', 'assignee', 'owner', 'search', 'status', 'id', 'page']) { + if (Object.prototype.hasOwnProperty.call(filter, field)) { + searchParams.set(field, filter[field]); + } + } + + const projectsData = await serverProxy.projects.get(searchParams.toString()); + // prettier-ignore + const projects = projectsData.map((project) => new Project(project)); + + projects.count = projectsData.count; + + return projects; + }; + + cvat.projects.searchNames.implementation = async (search, limit) => serverProxy.projects.searchNames(search, limit); + return cvat; } diff --git a/cvat-core/src/api.js b/cvat-core/src/api.js index 9d040683..7002a3ab 100644 --- a/cvat-core/src/api.js +++ b/cvat-core/src/api.js @@ -1,16 +1,11 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT /** - * External API which should be used by for development - * @module API -*/ + * External API which should be used by for development + * @module API + */ function build() { const PluginRegistry = require('./plugins'); @@ -18,31 +13,18 @@ function build() { const Log = require('./log'); const ObjectState = require('./object-state'); const Statistics = require('./statistics'); + const Comment = require('./comment'); + const Issue = require('./issue'); + const Review = require('./review'); const { Job, Task } = require('./session'); + const { Project } = require('./project'); const { Attribute, Label } = require('./labels'); const MLModel = require('./ml-model'); - const { - ShareFileType, - TaskStatus, - TaskMode, - AttributeType, - ObjectType, - ObjectShape, - LogType, - HistoryActions, - RQStatus, - colors, - Source, - } = require('./enums'); + const enums = require('./enums'); const { - Exception, - ArgumentError, - DataError, - ScriptingError, - PluginError, - ServerError, + Exception, ArgumentError, DataError, ScriptingError, PluginError, ServerError, } = require('./exceptions'); const User = require('./user'); @@ -50,579 +32,670 @@ function build() { const config = require('./config'); /** - * API entrypoint - * @namespace cvat - * @memberof module:API - */ + * API entrypoint + * @namespace cvat + * @memberof module:API + */ const cvat = { /** - * Namespace is used for an interaction with a server - * @namespace server - * @package - * @memberof module:API.cvat - */ + * Namespace is used for an interaction with a server + * @namespace server + * @package + * @memberof module:API.cvat + */ server: { /** - * @typedef {Object} ServerInfo - * @property {string} name A name of the tool - * @property {string} description A description of the tool - * @property {string} version A version of the tool - * @global - */ + * @typedef {Object} ServerInfo + * @property {string} name A name of the tool + * @property {string} description A description of the tool + * @property {string} version A version of the tool + * @global + */ /** - * Method returns some information about the annotation tool - * @method about - * @async - * @memberof module:API.cvat.server - * @return {ServerInfo} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method returns some information about the annotation tool + * @method about + * @async + * @memberof module:API.cvat.server + * @return {ServerInfo} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async about() { - const result = await PluginRegistry - .apiWrapper(cvat.server.about); + const result = await PluginRegistry.apiWrapper(cvat.server.about); return result; }, /** - * @typedef {Object} FileInfo - * @property {string} name A name of a file - * @property {module:API.cvat.enums.ShareFileType} type - * A type of a file - * @global - */ + * @typedef {Object} FileInfo + * @property {string} name A name of a file + * @property {module:API.cvat.enums.ShareFileType} type + * A type of a file + * @global + */ /** - * Method returns a list of files in a specified directory on a share - * @method share - * @async - * @memberof module:API.cvat.server - * @param {string} [directory=/] - Share directory path - * @returns {FileInfo[]} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns a list of files in a specified directory on a share + * @method share + * @async + * @memberof module:API.cvat.server + * @param {string} [directory=/] - Share directory path + * @returns {FileInfo[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async share(directory = '/') { - const result = await PluginRegistry - .apiWrapper(cvat.server.share, directory); + const result = await PluginRegistry.apiWrapper(cvat.server.share, directory); return result; }, /** - * Method returns available annotation formats - * @method formats - * @async - * @memberof module:API.cvat.server - * @returns {module:API.cvat.classes.AnnotationFormats} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns available annotation formats + * @method formats + * @async + * @memberof module:API.cvat.server + * @returns {module:API.cvat.classes.AnnotationFormats} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async formats() { - const result = await PluginRegistry - .apiWrapper(cvat.server.formats); + const result = await PluginRegistry.apiWrapper(cvat.server.formats); return result; }, /** - * Method returns user agreements that the user must accept - * @method userAgreements - * @async - * @memberof module:API.cvat.server - * @returns {Object[]} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns user agreements that the user must accept + * @method userAgreements + * @async + * @memberof module:API.cvat.server + * @returns {Object[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async userAgreements() { - const result = await PluginRegistry - .apiWrapper(cvat.server.userAgreements); + const result = await PluginRegistry.apiWrapper(cvat.server.userAgreements); return result; }, /** - - * Method allows to register on a server - * @method register - * @async - * @memberof module:API.cvat.server - * @param {string} username An username for the new account - * @param {string} firstName A first name for the new account - * @param {string} lastName A last name for the new account - * @param {string} email A email address for the new account - * @param {string} password1 A password for the new account - * @param {string} password2 The confirmation password for the new account - * @param {Object} userConfirmations An user confirmations of terms of use if needed - * @returns {Object} response data - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ - async register( - username, - firstName, - lastName, - email, - password1, - password2, - userConfirmations, - ) { - const result = await PluginRegistry - .apiWrapper(cvat.server.register, username, firstName, - lastName, email, password1, password2, userConfirmations); + * Method allows to register on a server + * @method register + * @async + * @memberof module:API.cvat.server + * @param {string} username An username for the new account + * @param {string} firstName A first name for the new account + * @param {string} lastName A last name for the new account + * @param {string} email A email address for the new account + * @param {string} password1 A password for the new account + * @param {string} password2 The confirmation password for the new account + * @param {Object} userConfirmations An user confirmations of terms of use if needed + * @returns {Object} response data + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ + async register(username, firstName, lastName, email, password1, password2, userConfirmations) { + const result = await PluginRegistry.apiWrapper( + cvat.server.register, + username, + firstName, + lastName, + email, + password1, + password2, + userConfirmations, + ); return result; }, /** - * Method allows to login on a server - * @method login - * @async - * @memberof module:API.cvat.server - * @param {string} username An username of an account - * @param {string} password A password of an account - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method allows to login on a server + * @method login + * @async + * @memberof module:API.cvat.server + * @param {string} username An username of an account + * @param {string} password A password of an account + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async login(username, password) { - const result = await PluginRegistry - .apiWrapper(cvat.server.login, username, password); + const result = await PluginRegistry.apiWrapper(cvat.server.login, username, password); return result; }, /** - * Method allows to logout from the server - * @method logout - * @async - * @memberof module:API.cvat.server - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method allows to logout from the server + * @method logout + * @async + * @memberof module:API.cvat.server + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async logout() { - const result = await PluginRegistry - .apiWrapper(cvat.server.logout); + const result = await PluginRegistry.apiWrapper(cvat.server.logout); return result; }, /** - * Method allows to change user password - * @method changePassword - * @async - * @memberof module:API.cvat.server - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method allows to change user password + * @method changePassword + * @async + * @memberof module:API.cvat.server + * @param {string} oldPassword Current password for the account + * @param {string} newPassword1 New password for the account + * @param {string} newPassword2 Confirmation password for the account + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async changePassword(oldPassword, newPassword1, newPassword2) { - const result = await PluginRegistry - .apiWrapper(cvat.server.changePassword, oldPassword, newPassword1, newPassword2); + const result = await PluginRegistry.apiWrapper( + cvat.server.changePassword, + oldPassword, + newPassword1, + newPassword2, + ); + return result; + }, + /** + * Method allows to reset user password + * @method requestPasswordReset + * @async + * @memberof module:API.cvat.server + * @param {string} email A email address for the account + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ + async requestPasswordReset(email) { + const result = await PluginRegistry.apiWrapper(cvat.server.requestPasswordReset, email); + return result; + }, + /** + * Method allows to confirm reset user password + * @method resetPassword + * @async + * @memberof module:API.cvat.server + * @param {string} newPassword1 New password for the account + * @param {string} newPassword2 Confirmation password for the account + * @param {string} uid User id + * @param {string} token Request authentication token + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ + async resetPassword(newPassword1, newPassword2, uid, token) { + const result = await PluginRegistry.apiWrapper( + cvat.server.resetPassword, + newPassword1, + newPassword2, + uid, + token, + ); return result; }, /** - * Method allows to know whether you are authorized on the server - * @method authorized - * @async - * @memberof module:API.cvat.server - * @returns {boolean} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method allows to know whether you are authorized on the server + * @method authorized + * @async + * @memberof module:API.cvat.server + * @returns {boolean} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async authorized() { - const result = await PluginRegistry - .apiWrapper(cvat.server.authorized); + const result = await PluginRegistry.apiWrapper(cvat.server.authorized); return result; }, /** - * Method allows to do requests via cvat-core with authorization headers - * @method request - * @async - * @memberof module:API.cvat.server - * @param {string} url - * @param {Object} data request parameters: method, headers, data, etc. - * @returns {Object | undefined} response data if exist - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method allows to do requests via cvat-core with authorization headers + * @method request + * @async + * @memberof module:API.cvat.server + * @param {string} url + * @param {Object} data request parameters: method, headers, data, etc. + * @returns {Object | undefined} response data if exist + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async request(url, data) { - const result = await PluginRegistry - .apiWrapper(cvat.server.request, url, data); + const result = await PluginRegistry.apiWrapper(cvat.server.request, url, data); + return result; + }, + + /** + * Method returns apps that are installed on the server + * @method installedApps + * @async + * @memberof module:API.cvat.server + * @returns {Object} map {installedApp: boolean} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ + async installedApps() { + const result = await PluginRegistry.apiWrapper(cvat.server.installedApps); + return result; + }, + }, + /** + * Namespace is used for getting projects + * @namespace projects + * @memberof module:API.cvat + */ + projects: { + /** + * @typedef {Object} ProjectFilter + * @property {string} name Check if name contains this value + * @property {module:API.cvat.enums.ProjectStatus} status + * Check if status contains this value + * @property {integer} id Check if id equals this value + * @property {integer} page Get specific page + * (default REST API returns 20 projects per request. + * In order to get more, it is need to specify next page) + * @property {string} owner Check if owner user contains this value + * @property {string} search Combined search of contains among all fields + * @global + */ + + /** + * Method returns list of projects corresponding to a filter + * @method get + * @async + * @memberof module:API.cvat.projects + * @param {ProjectFilter} [filter={}] project filter + * @returns {module:API.cvat.classes.Project[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ + async get(filter = {}) { + const result = await PluginRegistry.apiWrapper(cvat.projects.get, filter); + return result; + }, + + /** + * Method returns list of project names with project ids + * corresponding to a search phrase + * used for autocomplete field + * @method searchNames + * @async + * @memberof module:API.cvat.projects + * @param {string} [search = ''] search phrase + * @param {number} [limit = 10] number of returning project names + * @returns {module:API.cvat.classes.Project[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * + */ + async searchNames(search = '', limit = 10) { + const result = await PluginRegistry.apiWrapper(cvat.projects.searchNames, search, limit); return result; }, }, /** - * Namespace is used for getting tasks - * @namespace tasks - * @memberof module:API.cvat - */ + * Namespace is used for getting tasks + * @namespace tasks + * @memberof module:API.cvat + */ tasks: { /** - * @typedef {Object} TaskFilter - * @property {string} name Check if name contains this value - * @property {module:API.cvat.enums.TaskStatus} status - * Check if status contains this value - * @property {module:API.cvat.enums.TaskMode} mode - * Check if mode contains this value - * @property {integer} id Check if id equals this value - * @property {integer} page Get specific page - * (default REST API returns 20 tasks per request. - * In order to get more, it is need to specify next page) - * @property {string} owner Check if owner user contains this value - * @property {string} assignee Check if assigneed contains this value - * @property {string} search Combined search of contains among all fields - * @global - */ + * @typedef {Object} TaskFilter + * @property {string} name Check if name contains this value + * @property {module:API.cvat.enums.TaskStatus} status + * Check if status contains this value + * @property {module:API.cvat.enums.TaskMode} mode + * Check if mode contains this value + * @property {integer} id Check if id equals this value + * @property {integer} page Get specific page + * (default REST API returns 20 tasks per request. + * In order to get more, it is need to specify next page) + * @property {integer} projectId Check if project_id field contains this value + * @property {string} owner Check if owner user contains this value + * @property {string} assignee Check if assigneed contains this value + * @property {string} search Combined search of contains among all fields + * @global + */ /** - * Method returns list of tasks corresponding to a filter - * @method get - * @async - * @memberof module:API.cvat.tasks - * @param {TaskFilter} [filter={}] task filter - * @returns {module:API.cvat.classes.Task[]} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns list of tasks corresponding to a filter + * @method get + * @async + * @memberof module:API.cvat.tasks + * @param {TaskFilter} [filter={}] task filter + * @returns {module:API.cvat.classes.Task[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async get(filter = {}) { - const result = await PluginRegistry - .apiWrapper(cvat.tasks.get, filter); + const result = await PluginRegistry.apiWrapper(cvat.tasks.get, filter); return result; }, }, /** - * Namespace is used for getting jobs - * @namespace jobs - * @memberof module:API.cvat - */ + * Namespace is used for getting jobs + * @namespace jobs + * @memberof module:API.cvat + */ jobs: { /** - * @typedef {Object} JobFilter - * Only one of fields is allowed simultaneously - * @property {integer} taskID filter all jobs of specific task - * @property {integer} jobID filter job with a specific id - * @global - */ + * @typedef {Object} JobFilter + * Only one of fields is allowed simultaneously + * @property {integer} taskID filter all jobs of specific task + * @property {integer} jobID filter job with a specific id + * @global + */ /** - * Method returns list of jobs corresponding to a filter - * @method get - * @async - * @memberof module:API.cvat.jobs - * @param {JobFilter} filter job filter - * @returns {module:API.cvat.classes.Job[]} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns list of jobs corresponding to a filter + * @method get + * @async + * @memberof module:API.cvat.jobs + * @param {JobFilter} filter job filter + * @returns {module:API.cvat.classes.Job[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async get(filter = {}) { - const result = await PluginRegistry - .apiWrapper(cvat.jobs.get, filter); + const result = await PluginRegistry.apiWrapper(cvat.jobs.get, filter); return result; }, }, /** - * Namespace is used for getting users - * @namespace users - * @memberof module:API.cvat - */ + * Namespace is used for getting users + * @namespace users + * @memberof module:API.cvat + */ users: { /** - * @typedef {Object} UserFilter - * @property {boolean} self get only self - * @global - */ + * @typedef {Object} UserFilter + * @property {boolean} self get only self + * @global + */ /** - * Method returns list of users corresponding to a filter - * @method get - * @async - * @memberof module:API.cvat.users - * @param {UserFilter} [filter={}] user filter - * @returns {module:API.cvat.classes.User[]} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - */ + * Method returns list of users corresponding to a filter + * @method get + * @async + * @memberof module:API.cvat.users + * @param {UserFilter} [filter={}] user filter + * @returns {module:API.cvat.classes.User[]} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + */ async get(filter = {}) { - const result = await PluginRegistry - .apiWrapper(cvat.users.get, filter); + const result = await PluginRegistry.apiWrapper(cvat.users.get, filter); return result; }, }, /** - * Namespace is used for plugin management - * @namespace plugins - * @memberof module:API.cvat - */ + * Namespace is used for plugin management + * @namespace plugins + * @memberof module:API.cvat + */ plugins: { /** - * @typedef {Object} Plugin - * A plugin is a Javascript object. It must have properties are listed below.
- * It also mustn't have property 'functions' which is used internally.
- * You can expand any API method including class methods.
- * In order to expand class method just use a class name - * in a cvat space (example is listed below). - * - * @property {string} name A name of a plugin - * @property {string} description A description of a plugin - * Example plugin implementation listed below: - * @example - * plugin = { - * name: 'Example Plugin', - * description: 'This example plugin demonstrates how plugin system in CVAT works', - * cvat: { - * server: { - * about: { - * // Plugin adds some actions after executing the cvat.server.about() - * // For example it adds a field with installed plugins to a result - * // An argument "self" is a plugin itself - * // An argument "result" is a return value of cvat.server.about() - * // All next arguments are arguments of a wrapped function - * // (in this case the wrapped function doesn't have any arguments) - * async leave(self, result) { - * result.plugins = await self.internal.getPlugins(); - * // Note that a method leave must return "result" (changed or not) - * // Otherwise API won't work as expected - * return result; - * }, - * }, - * }, - * // In this example plugin also wraps a class method - * classes: { - * Job: { - * prototype: { - * annotations: { - * put: { - * // The first argument "self" is a plugin, like in a case above - * // The second argument is an argument of the - * // Job.annotations.put() - * // It contains an array of objects to put - * // In this sample we round objects coordinates and save them - * enter(self, objects) { - * for (const obj of objects) { - * if (obj.type != 'tag') { - * const points = obj.position.map((point) => { - * const roundPoint = { - * x: Math.round(point.x), - * y: Math.round(point.y), - * }; - * return roundPoint; - * }); - * } - * } - * }, - * }, - * }, - * }, - * }, - * }, - * }, - * // In general you can add any others members to your plugin - * // Members below are only examples - * internal: { - * async getPlugins() { - * // Collect information about installed plugins - * const plugins = await cvat.plugins.list(); - * return plugins.map((el) => { - * return { - * name: el.name, - * description: el.description, - * }; - * }); - * }, - * }, - * }; - * @global - */ + * @typedef {Object} Plugin + * A plugin is a Javascript object. It must have properties are listed below.
+ * It also mustn't have property 'functions' which is used internally.
+ * You can expand any API method including class methods.
+ * In order to expand class method just use a class name + * in a cvat space (example is listed below). + * + * @property {string} name A name of a plugin + * @property {string} description A description of a plugin + * Example plugin implementation listed below: + * @example + * plugin = { + * name: 'Example Plugin', + * description: 'This example plugin demonstrates how plugin system in CVAT works', + * cvat: { + * server: { + * about: { + * // Plugin adds some actions after executing the cvat.server.about() + * // For example it adds a field with installed plugins to a result + * // An argument "self" is a plugin itself + * // An argument "result" is a return value of cvat.server.about() + * // All next arguments are arguments of a wrapped function + * // (in this case the wrapped function doesn't have any arguments) + * async leave(self, result) { + * result.plugins = await self.internal.getPlugins(); + * // Note that a method leave must return "result" (changed or not) + * // Otherwise API won't work as expected + * return result; + * }, + * }, + * }, + * // In this example plugin also wraps a class method + * classes: { + * Job: { + * prototype: { + * annotations: { + * put: { + * // The first argument "self" is a plugin, like in a case above + * // The second argument is an argument of the + * // Job.annotations.put() + * // It contains an array of objects to put + * // In this sample we round objects coordinates and save them + * enter(self, objects) { + * for (const obj of objects) { + * if (obj.type != 'tag') { + * const points = obj.position.map((point) => { + * const roundPoint = { + * x: Math.round(point.x), + * y: Math.round(point.y), + * }; + * return roundPoint; + * }); + * } + * } + * }, + * }, + * }, + * }, + * }, + * }, + * }, + * // In general you can add any others members to your plugin + * // Members below are only examples + * internal: { + * async getPlugins() { + * // Collect information about installed plugins + * const plugins = await cvat.plugins.list(); + * return plugins.map((el) => { + * return { + * name: el.name, + * description: el.description, + * }; + * }); + * }, + * }, + * }; + * @global + */ /** - * Method returns list of installed plugins - * @method list - * @async - * @memberof module:API.cvat.plugins - * @returns {Plugin[]} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method returns list of installed plugins + * @method list + * @async + * @memberof module:API.cvat.plugins + * @returns {Plugin[]} + * @throws {module:API.cvat.exceptions.PluginError} + */ async list() { - const result = await PluginRegistry - .apiWrapper(cvat.plugins.list); + const result = await PluginRegistry.apiWrapper(cvat.plugins.list); return result; }, /** - * Install plugin to CVAT - * @method register - * @async - * @memberof module:API.cvat.plugins - * @param {Plugin} [plugin] plugin for registration - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Install plugin to CVAT + * @method register + * @async + * @memberof module:API.cvat.plugins + * @param {Plugin} [plugin] plugin for registration + * @throws {module:API.cvat.exceptions.PluginError} + */ async register(plugin) { - const result = await PluginRegistry - .apiWrapper(cvat.plugins.register, plugin); + const result = await PluginRegistry.apiWrapper(cvat.plugins.register, plugin); return result; }, }, + /** - * Namespace is used for serverless functions management (mainly related with DL models) - * @namespace lambda - * @memberof module:API.cvat - */ + * Namespace is used for serverless functions management (mainly related with DL models) + * @namespace lambda + * @memberof module:API.cvat + */ lambda: { /** - * Method returns list of available serverless models - * @method list - * @async - * @memberof module:API.cvat.lambda - * @returns {module:API.cvat.classes.MLModel[]} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method returns list of available serverless models + * @method list + * @async + * @memberof module:API.cvat.lambda + * @returns {module:API.cvat.classes.MLModel[]} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async list() { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.list); + const result = await PluginRegistry.apiWrapper(cvat.lambda.list); return result; }, /** - * Run long-time request for a function on a specific task - * @method run - * @async - * @memberof module:API.cvat.lambda - * @param {module:API.cvat.classes.Task} task task to be annotated - * @param {module:API.cvat.classes.MLModel} model model used to get annotation - * @param {object} [args] extra arguments - * @returns {string} requestID - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Run long-time request for a function on a specific task + * @method run + * @async + * @memberof module:API.cvat.lambda + * @param {module:API.cvat.classes.Task} task task to be annotated + * @param {module:API.cvat.classes.MLModel} model model used to get annotation + * @param {object} [args] extra arguments + * @returns {string} requestID + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ async run(task, model, args) { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.run, task, model, args); + const result = await PluginRegistry.apiWrapper(cvat.lambda.run, task, model, args); return result; }, /** - * Run short-time request for a function on a specific task - * @method call - * @async - * @memberof module:API.cvat.lambda - * @param {module:API.cvat.classes.Task} task task to be annotated - * @param {module:API.cvat.classes.MLModel} model model used to get annotation - * @param {object} [args] extra arguments - * @returns {string} requestID - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Run short-time request for a function on a specific task + * @method call + * @async + * @memberof module:API.cvat.lambda + * @param {module:API.cvat.classes.Task} task task to be annotated + * @param {module:API.cvat.classes.MLModel} model model used to get annotation + * @param {object} [args] extra arguments + * @returns {string} requestID + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ async call(task, model, args) { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.call, task, model, args); + const result = await PluginRegistry.apiWrapper(cvat.lambda.call, task, model, args); return result; }, /** - * Cancel running of a serverless function for a specific task - * @method cancel - * @async - * @memberof module:API.cvat.lambda - * @param {string} requestID - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Cancel running of a serverless function for a specific task + * @method cancel + * @async + * @memberof module:API.cvat.lambda + * @param {string} requestID + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ async cancel(requestID) { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.cancel, requestID); + const result = await PluginRegistry.apiWrapper(cvat.lambda.cancel, requestID); return result; }, /** - * @callback onRequestStatusChange - * @param {string} status - * @param {number} progress - * @param {string} [message] - * @global - */ - /** - * Listen for a specific request - * @method listen - * @async - * @memberof module:API.cvat.lambda - * @param {string} requestID - * @param {onRequestStatusChange} onChange - * @throws {module:API.cvat.exceptions.ArgumentError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * @callback onRequestStatusChange + * @param {string} status + * @param {number} progress + * @param {string} [message] + * @global + */ + /** + * Listen for a specific request + * @method listen + * @async + * @memberof module:API.cvat.lambda + * @param {string} requestID + * @param {onRequestStatusChange} onChange + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async listen(requestID, onChange) { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.listen, requestID, onChange); + const result = await PluginRegistry.apiWrapper(cvat.lambda.listen, requestID, onChange); return result; }, /** - * Get active lambda requests - * @method requests - * @async - * @memberof module:API.cvat.lambda - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Get active lambda requests + * @method requests + * @async + * @memberof module:API.cvat.lambda + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async requests() { - const result = await PluginRegistry - .apiWrapper(cvat.lambda.requests); + const result = await PluginRegistry.apiWrapper(cvat.lambda.requests); return result; }, }, /** - * Namespace to working with logs - * @namespace logger - * @memberof module:API.cvat - */ + * Namespace to working with logs + * @namespace logger + * @memberof module:API.cvat + */ /** - * Method to logger configuration - * @method configure - * @memberof module:API.cvat.logger - * @param {function} isActiveChecker - callback to know if logger - * should increase working time or not - * @param {object} userActivityCallback - container for a callback
- * Logger put here a callback to update user activity timer
- * You can call it outside - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} + * Method to logger configuration + * @method configure + * @memberof module:API.cvat.logger + * @param {function} isActiveChecker - callback to know if logger + * should increase working time or not + * @param {object} userActivityCallback - container for a callback
+ * Logger put here a callback to update user activity timer
+ * You can call it outside + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} */ /** - * Append log to a log collection
- * Durable logs will have been added after "close" method is called for them
- * Ignore rules exist for some logs (e.g. zoomImage, changeAttribute)
- * Payload of ignored logs are shallowly combined to previous logs of the same type - * @method log - * @memberof module:API.cvat.logger - * @param {module:API.cvat.enums.LogType | string} type - log type - * @param {Object} [payload = {}] - any other data that will be appended to the log - * @param {boolean} [wait = false] - specifies if log is durable - * @returns {module:API.cvat.classes.Log} - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Append log to a log collection
+ * Durable logs will have been added after "close" method is called for them
+ * Ignore rules exist for some logs (e.g. zoomImage, changeAttribute)
+ * Payload of ignored logs are shallowly combined to previous logs of the same type + * @method log + * @memberof module:API.cvat.logger + * @param {module:API.cvat.enums.LogType | string} type - log type + * @param {Object} [payload = {}] - any other data that will be appended to the log + * @param {boolean} [wait = false] - specifies if log is durable + * @returns {module:API.cvat.classes.Log} + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ /** - * Save accumulated logs on a server - * @method save - * @memberof module:API.cvat.logger - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @instance - * @async - */ + * Save accumulated logs on a server + * @method save + * @memberof module:API.cvat.logger + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @instance + * @async + */ logger: loggerStorage, /** - * Namespace contains some changeable configurations - * @namespace config - * @memberof module:API.cvat - */ + * Namespace contains some changeable configurations + * @namespace config + * @memberof module:API.cvat + */ config: { /** - * @memberof module:API.cvat.config - * @property {string} backendAPI host with a backend api - * @memberof module:API.cvat.config - * @property {string} proxy Axios proxy settings. - * For more details please read here - * @memberof module:API.cvat.config - * @memberof module:API.cvat.config - */ + * @memberof module:API.cvat.config + * @property {string} backendAPI host with a backend api + * @memberof module:API.cvat.config + * @property {string} proxy Axios proxy settings. + * For more details please read here + * @memberof module:API.cvat.config + * @memberof module:API.cvat.config + */ get backendAPI() { return config.backendAPI; }, @@ -637,46 +710,34 @@ function build() { }, }, /** - * Namespace contains some library information e.g. api version - * @namespace client - * @memberof module:API.cvat - */ + * Namespace contains some library information e.g. api version + * @namespace client + * @memberof module:API.cvat + */ client: { /** - * @property {string} version Client version. - * Format: {major}.{minor}.{patch} - *
  • A major number is changed after an API becomes - * incompatible with a previous version - *
  • A minor number is changed after an API expands - *
  • A patch number is changed after an each build - * @memberof module:API.cvat.client - * @readonly - */ + * @property {string} version Client version. + * Format: {major}.{minor}.{patch} + *
  • A major number is changed after an API becomes + * incompatible with a previous version + *
  • A minor number is changed after an API expands + *
  • A patch number is changed after an each build + * @memberof module:API.cvat.client + * @readonly + */ version: `${pjson.version}`, }, /** - * Namespace is used for access to enums - * @namespace enums - * @memberof module:API.cvat - */ - enums: { - ShareFileType, - TaskStatus, - TaskMode, - AttributeType, - ObjectType, - ObjectShape, - LogType, - HistoryActions, - RQStatus, - colors, - Source, - }, + * Namespace is used for access to enums + * @namespace enums + * @memberof module:API.cvat + */ + enums, /** - * Namespace is used for access to exceptions - * @namespace exceptions - * @memberof module:API.cvat - */ + * Namespace is used for access to exceptions + * @namespace exceptions + * @memberof module:API.cvat + */ exceptions: { Exception, ArgumentError, @@ -686,13 +747,14 @@ function build() { ServerError, }, /** - * Namespace is used for access to classes - * @namespace classes - * @memberof module:API.cvat - */ + * Namespace is used for access to classes + * @namespace classes + * @memberof module:API.cvat + */ classes: { - Task, User, + Project, + Task, Job, Log, Attribute, @@ -700,10 +762,14 @@ function build() { Statistics, ObjectState, MLModel, + Comment, + Issue, + Review, }, }; cvat.server = Object.freeze(cvat.server); + cvat.projects = Object.freeze(cvat.projects); cvat.tasks = Object.freeze(cvat.tasks); cvat.jobs = Object.freeze(cvat.jobs); cvat.users = Object.freeze(cvat.users); diff --git a/cvat-core/src/comment.js b/cvat-core/src/comment.js new file mode 100644 index 00000000..e8e18cb4 --- /dev/null +++ b/cvat-core/src/comment.js @@ -0,0 +1,153 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +const User = require('./user'); +const { ArgumentError } = require('./exceptions'); +const { negativeIDGenerator } = require('./common'); + +/** + * Class representing a single comment + * @memberof module:API.cvat.classes + * @hideconstructor + */ +class Comment { + constructor(initialData) { + const data = { + id: undefined, + message: undefined, + created_date: undefined, + updated_date: undefined, + removed: false, + author: undefined, + }; + + for (const property in data) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { + data[property] = initialData[property]; + } + } + + if (data.author && !(data.author instanceof User)) data.author = new User(data.author); + + if (typeof id === 'undefined') { + data.id = negativeIDGenerator(); + } + if (typeof data.created_date === 'undefined') { + data.created_date = new Date().toISOString(); + } + + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Comment + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * @name message + * @type {string} + * @memberof module:API.cvat.classes.Comment + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + message: { + get: () => data.message, + set: (value) => { + if (!value.trim().length) { + throw new ArgumentError('Value must not be empty'); + } + data.message = value; + }, + }, + /** + * @name createdDate + * @type {string} + * @memberof module:API.cvat.classes.Comment + * @readonly + * @instance + */ + createdDate: { + get: () => data.created_date, + }, + /** + * @name updatedDate + * @type {string} + * @memberof module:API.cvat.classes.Comment + * @readonly + * @instance + */ + updatedDate: { + get: () => data.updated_date, + }, + /** + * Instance of a user who has created the comment + * @name author + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Comment + * @readonly + * @instance + */ + author: { + get: () => data.author, + }, + /** + * @name removed + * @type {boolean} + * @memberof module:API.cvat.classes.Comment + * @instance + */ + removed: { + get: () => data.removed, + set: (value) => { + if (typeof value !== 'boolean') { + throw new ArgumentError('Value must be a boolean value'); + } + data.removed = value; + }, + }, + __internal: { + get: () => data, + }, + }), + ); + } + + serialize() { + const data = { + message: this.message, + }; + + if (this.id > 0) { + data.id = this.id; + } + if (this.createdDate) { + data.created_date = this.createdDate; + } + if (this.updatedDate) { + data.updated_date = this.updatedDate; + } + if (this.author) { + data.author = this.author.serialize(); + } + + return data; + } + + toJSON() { + const data = this.serialize(); + const { author, ...updated } = data; + return { + ...updated, + author_id: author ? author.id : undefined, + }; + } +} + +module.exports = Comment; diff --git a/cvat-core/src/common.js b/cvat-core/src/common.js index 93165db9..d40312b4 100644 --- a/cvat-core/src/common.js +++ b/cvat-core/src/common.js @@ -1,21 +1,16 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const { ArgumentError } = require('./exceptions'); function isBoolean(value) { - return typeof (value) === 'boolean'; + return typeof value === 'boolean'; } function isInteger(value) { - return typeof (value) === 'number' && Number.isInteger(value); + return typeof value === 'number' && Number.isInteger(value); } // Called with specific Enum context @@ -32,20 +27,16 @@ } function isString(value) { - return typeof (value) === 'string'; + return typeof value === 'string'; } function checkFilter(filter, fields) { for (const prop in filter) { if (Object.prototype.hasOwnProperty.call(filter, prop)) { if (!(prop in fields)) { - throw new ArgumentError( - `Unsupported filter property has been recieved: "${prop}"`, - ); + throw new ArgumentError(`Unsupported filter property has been recieved: "${prop}"`); } else if (!fields[prop](filter[prop])) { - throw new ArgumentError( - `Received filter property "${prop}" is not satisfied for checker`, - ); + throw new ArgumentError(`Received filter property "${prop}" is not satisfied for checker`); } } } @@ -53,15 +44,13 @@ function checkObjectType(name, value, type, instance) { if (type) { - if (typeof (value) !== type) { + if (typeof value !== type) { // specific case for integers which aren't native type in JS if (type === 'integer' && Number.isInteger(value)) { return true; } - throw new ArgumentError( - `"${name}" is expected to be "${type}", but "${typeof (value)}" has been got.`, - ); + throw new ArgumentError(`"${name}" is expected to be "${type}", but "${typeof value}" has been got.`); } } else if (instance) { if (!(value instanceof instance)) { @@ -72,15 +61,20 @@ ); } - throw new ArgumentError( - `"${name}" is expected to be ${instance.name}, but "undefined" has been got.`, - ); + throw new ArgumentError(`"${name}" is expected to be ${instance.name}, but "undefined" has been got.`); } } return true; } + function negativeIDGenerator() { + const value = negativeIDGenerator.start; + negativeIDGenerator.start -= 1; + return value; + } + negativeIDGenerator.start = -1; + module.exports = { isBoolean, isInteger, @@ -88,5 +82,6 @@ isString, checkFilter, checkObjectType, + negativeIDGenerator, }; })(); diff --git a/cvat-core/src/config.js b/cvat-core/src/config.js index 3b9eade8..93d95779 100644 --- a/cvat-core/src/config.js +++ b/cvat-core/src/config.js @@ -1,7 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT module.exports = { backendAPI: 'http://localhost:7000/api/v1', diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index 0999361a..35d899d2 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const Axios = require('axios'); @@ -13,7 +8,6 @@ Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; - onmessage = (e) => { Axios.get(e.data.url, e.data.config) .then((response) => { @@ -26,7 +20,9 @@ onmessage = (e) => { .catch((error) => { postMessage({ id: e.data.id, - error, + error: error, + status: error.response.status, + responseData: error.response.data, isSuccess: false, }); }); diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index c7b6c595..107bc86f 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -1,33 +1,32 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { /** - * Share files types - * @enum {string} - * @name ShareFileType - * @memberof module:API.cvat.enums - * @property {string} DIR 'DIR' - * @property {string} REG 'REG' - * @readonly - */ + * Share files types + * @enum {string} + * @name ShareFileType + * @memberof module:API.cvat.enums + * @property {string} DIR 'DIR' + * @property {string} REG 'REG' + * @readonly + */ const ShareFileType = Object.freeze({ DIR: 'DIR', REG: 'REG', }); /** - * Task statuses - * @enum {string} - * @name TaskStatus - * @memberof module:API.cvat.enums - * @property {string} ANNOTATION 'annotation' - * @property {string} VALIDATION 'validation' - * @property {string} COMPLETED 'completed' - * @readonly - */ + * Task statuses + * @enum {string} + * @name TaskStatus + * @memberof module:API.cvat.enums + * @property {string} ANNOTATION 'annotation' + * @property {string} VALIDATION 'validation' + * @property {string} COMPLETED 'completed' + * @readonly + */ const TaskStatus = Object.freeze({ ANNOTATION: 'annotation', VALIDATION: 'validation', @@ -35,18 +34,34 @@ }); /** - * List of RQ statuses - * @enum {string} - * @name RQStatus - * @memberof module:API.cvat.enums - * @property {string} QUEUED 'queued' - * @property {string} STARTED 'started' - * @property {string} FINISHED 'finished' - * @property {string} FAILED 'failed' - * @property {string} UNKNOWN 'unknown' - * @readonly - */ - const RQStatus = Object.freeze({ + * Review statuses + * @enum {string} + * @name ReviewStatus + * @memberof module:API.cvat.enums + * @property {string} ACCEPTED 'accepted' + * @property {string} REJECTED 'rejected' + * @property {string} REVIEW_FURTHER 'review_further' + * @readonly + */ + const ReviewStatus = Object.freeze({ + ACCEPTED: 'accepted', + REJECTED: 'rejected', + REVIEW_FURTHER: 'review_further', + }); + + /** + * List of RQ statuses + * @enum {string} + * @name RQStatus + * @memberof module:API.cvat.enums + * @property {string} QUEUED 'queued' + * @property {string} STARTED 'started' + * @property {string} FINISHED 'finished' + * @property {string} FAILED 'failed' + * @property {string} UNKNOWN 'unknown' + * @readonly + */ + const RQStatus = Object.freeze({ QUEUED: 'queued', STARTED: 'started', FINISHED: 'finished', @@ -55,31 +70,31 @@ }); /** - * Task modes - * @enum {string} - * @name TaskMode - * @memberof module:API.cvat.enums - * @property {string} ANNOTATION 'annotation' - * @property {string} INTERPOLATION 'interpolation' - * @readonly - */ + * Task modes + * @enum {string} + * @name TaskMode + * @memberof module:API.cvat.enums + * @property {string} ANNOTATION 'annotation' + * @property {string} INTERPOLATION 'interpolation' + * @readonly + */ const TaskMode = Object.freeze({ ANNOTATION: 'annotation', INTERPOLATION: 'interpolation', }); /** - * Attribute types - * @enum {string} - * @name AttributeType - * @memberof module:API.cvat.enums - * @property {string} CHECKBOX 'checkbox' - * @property {string} SELECT 'select' - * @property {string} RADIO 'radio' - * @property {string} NUMBER 'number' - * @property {string} TEXT 'text' - * @readonly - */ + * Attribute types + * @enum {string} + * @name AttributeType + * @memberof module:API.cvat.enums + * @property {string} CHECKBOX 'checkbox' + * @property {string} SELECT 'select' + * @property {string} RADIO 'radio' + * @property {string} NUMBER 'number' + * @property {string} TEXT 'text' + * @readonly + */ const AttributeType = Object.freeze({ CHECKBOX: 'checkbox', RADIO: 'radio', @@ -89,15 +104,15 @@ }); /** - * Object types - * @enum {string} - * @name ObjectType - * @memberof module:API.cvat.enums - * @property {string} TAG 'tag' - * @property {string} SHAPE 'shape' - * @property {string} TRACK 'track' - * @readonly - */ + * Object types + * @enum {string} + * @name ObjectType + * @memberof module:API.cvat.enums + * @property {string} TAG 'tag' + * @property {string} SHAPE 'shape' + * @property {string} TRACK 'track' + * @readonly + */ const ObjectType = Object.freeze({ TAG: 'tag', SHAPE: 'shape', @@ -105,17 +120,17 @@ }); /** - * Object shapes - * @enum {string} - * @name ObjectShape - * @memberof module:API.cvat.enums - * @property {string} RECTANGLE 'rectangle' - * @property {string} POLYGON 'polygon' - * @property {string} POLYLINE 'polyline' - * @property {string} POINTS 'points' - * @property {string} CUBOID 'cuboid' - * @readonly - */ + * Object shapes + * @enum {string} + * @name ObjectShape + * @memberof module:API.cvat.enums + * @property {string} RECTANGLE 'rectangle' + * @property {string} POLYGON 'polygon' + * @property {string} POLYLINE 'polyline' + * @property {string} POINTS 'points' + * @property {string} CUBOID 'cuboid' + * @readonly + */ const ObjectShape = Object.freeze({ RECTANGLE: 'rectangle', POLYGON: 'polygon', @@ -125,17 +140,17 @@ }); /** - * Annotation type - * @enum {string} - * @name Source - * @memberof module:API.cvat.enums - * @property {string} MANUAL 'manual' - * @property {string} AUTO 'auto' - * @readonly - */ + * Annotation type + * @enum {string} + * @name Source + * @memberof module:API.cvat.enums + * @property {string} MANUAL 'manual' + * @property {string} AUTO 'auto' + * @readonly + */ const Source = Object.freeze({ - MANUAL:'manual', - AUTO:'auto', + MANUAL: 'manual', + AUTO: 'auto', }); /** @@ -211,27 +226,27 @@ }); /** - * Types of actions with annotations - * @enum {string} - * @name HistoryActions - * @memberof module:API.cvat.enums - * @property {string} CHANGED_LABEL Changed label - * @property {string} CHANGED_ATTRIBUTES Changed attributes - * @property {string} CHANGED_POINTS Changed points - * @property {string} CHANGED_OUTSIDE Changed outside - * @property {string} CHANGED_OCCLUDED Changed occluded - * @property {string} CHANGED_ZORDER Changed z-order - * @property {string} CHANGED_LOCK Changed lock - * @property {string} CHANGED_COLOR Changed color - * @property {string} CHANGED_HIDDEN Changed hidden - * @property {string} CHANGED_SOURCE Changed source - * @property {string} MERGED_OBJECTS Merged objects - * @property {string} SPLITTED_TRACK Splitted track - * @property {string} GROUPED_OBJECTS Grouped objects - * @property {string} CREATED_OBJECTS Created objects - * @property {string} REMOVED_OBJECT Removed object - * @readonly - */ + * Types of actions with annotations + * @enum {string} + * @name HistoryActions + * @memberof module:API.cvat.enums + * @property {string} CHANGED_LABEL Changed label + * @property {string} CHANGED_ATTRIBUTES Changed attributes + * @property {string} CHANGED_POINTS Changed points + * @property {string} CHANGED_OUTSIDE Changed outside + * @property {string} CHANGED_OCCLUDED Changed occluded + * @property {string} CHANGED_ZORDER Changed z-order + * @property {string} CHANGED_LOCK Changed lock + * @property {string} CHANGED_COLOR Changed color + * @property {string} CHANGED_HIDDEN Changed hidden + * @property {string} CHANGED_SOURCE Changed source + * @property {string} MERGED_OBJECTS Merged objects + * @property {string} SPLITTED_TRACK Splitted track + * @property {string} GROUPED_OBJECTS Grouped objects + * @property {string} CREATED_OBJECTS Created objects + * @property {string} REMOVED_OBJECT Removed object + * @readonly + */ const HistoryActions = Object.freeze({ CHANGED_LABEL: 'Changed label', CHANGED_ATTRIBUTES: 'Changed attributes', @@ -265,23 +280,49 @@ }; /** - * Array of hex colors - * @name colors - * @memberof module:API.cvat.enums - * @type {string[]} - * @readonly - */ + * Array of hex colors + * @name colors + * @memberof module:API.cvat.enums + * @type {string[]} + * @readonly + */ const colors = [ - '#33ddff', '#fa3253', '#34d1b7', '#ff007c', '#ff6037', '#ddff33', - '#24b353', '#b83df5', '#66ff66', '#32b7fa', '#ffcc33', '#83e070', - '#fafa37', '#5986b3', '#8c78f0', '#ff6a4d', '#f078f0', '#2a7dd1', - '#b25050', '#cc3366', '#cc9933', '#aaf0d1', '#ff00cc', '#3df53d', - '#fa32b7', '#fa7dbb', '#ff355e', '#f59331', '#3d3df5', '#733380', + '#33ddff', + '#fa3253', + '#34d1b7', + '#ff007c', + '#ff6037', + '#ddff33', + '#24b353', + '#b83df5', + '#66ff66', + '#32b7fa', + '#ffcc33', + '#83e070', + '#fafa37', + '#5986b3', + '#8c78f0', + '#ff6a4d', + '#f078f0', + '#2a7dd1', + '#b25050', + '#cc3366', + '#cc9933', + '#aaf0d1', + '#ff00cc', + '#3df53d', + '#fa32b7', + '#fa7dbb', + '#ff355e', + '#f59331', + '#3d3df5', + '#733380', ]; module.exports = { ShareFileType, TaskStatus, + ReviewStatus, TaskMode, AttributeType, ObjectType, diff --git a/cvat-core/src/exceptions.js b/cvat-core/src/exceptions.js index 97788cf6..8511b32d 100644 --- a/cvat-core/src/exceptions.js +++ b/cvat-core/src/exceptions.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const Platform = require('platform'); @@ -13,15 +8,15 @@ const config = require('./config'); /** - * Base exception class - * @memberof module:API.cvat.exceptions - * @extends Error - * @ignore - */ + * Base exception class + * @memberof module:API.cvat.exceptions + * @extends Error + * @ignore + */ class Exception extends Error { /** - * @param {string} message - Exception message - */ + * @param {string} message - Exception message + */ constructor(message) { super(message); @@ -32,126 +27,125 @@ const filename = `${info.fileName}`; const line = info.lineNumber; const column = info.columnNumber; - const { - jobID, - taskID, - clientID, - } = config; + const { jobID, taskID, clientID } = config; const projID = undefined; // wasn't implemented - Object.defineProperties(this, Object.freeze({ - system: { - /** - * @name system - * @type {string} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => system, - }, - client: { - /** - * @name client - * @type {string} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => client, - }, - time: { - /** - * @name time - * @type {string} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => time, - }, - jobID: { - /** - * @name jobID - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => jobID, - }, - taskID: { - /** - * @name taskID - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => taskID, - }, - projID: { - /** - * @name projID - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => projID, - }, - clientID: { - /** - * @name clientID - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => clientID, - }, - filename: { - /** - * @name filename - * @type {string} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => filename, - }, - line: { - /** - * @name line - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => line, - }, - column: { - /** - * @name column - * @type {integer} - * @memberof module:API.cvat.exceptions.Exception - * @readonly - * @instance - */ - get: () => column, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + system: { + /** + * @name system + * @type {string} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => system, + }, + client: { + /** + * @name client + * @type {string} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => client, + }, + time: { + /** + * @name time + * @type {string} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => time, + }, + jobID: { + /** + * @name jobID + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => jobID, + }, + taskID: { + /** + * @name taskID + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => taskID, + }, + projID: { + /** + * @name projID + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => projID, + }, + clientID: { + /** + * @name clientID + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => clientID, + }, + filename: { + /** + * @name filename + * @type {string} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => filename, + }, + line: { + /** + * @name line + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => line, + }, + column: { + /** + * @name column + * @type {integer} + * @memberof module:API.cvat.exceptions.Exception + * @readonly + * @instance + */ + get: () => column, + }, + }), + ); } /** - * Save an exception on a server - * @name save - * @method - * @memberof Exception - * @instance - * @async - */ + * Save an exception on a server + * @name save + * @method + * @memberof Exception + * @instance + * @async + */ async save() { const exceptionObject = { system: this.system, @@ -178,86 +172,89 @@ } /** - * Exceptions are referred with arguments data - * @memberof module:API.cvat.exceptions - * @extends module:API.cvat.exceptions.Exception - */ + * Exceptions are referred with arguments data + * @memberof module:API.cvat.exceptions + * @extends module:API.cvat.exceptions.Exception + */ class ArgumentError extends Exception { /** - * @param {string} message - Exception message - */ + * @param {string} message - Exception message + */ constructor(message) { super(message); } } /** - * Unexpected problems with data which are not connected with a user input - * @memberof module:API.cvat.exceptions - * @extends module:API.cvat.exceptions.Exception - */ + * Unexpected problems with data which are not connected with a user input + * @memberof module:API.cvat.exceptions + * @extends module:API.cvat.exceptions.Exception + */ class DataError extends Exception { - /** - * @param {string} message - Exception message - */ + /** + * @param {string} message - Exception message + */ constructor(message) { super(message); } } /** - * Unexpected situations in code - * @memberof module:API.cvat.exceptions - * @extends module:API.cvat.exceptions.Exception - */ + * Unexpected situations in code + * @memberof module:API.cvat.exceptions + * @extends module:API.cvat.exceptions.Exception + */ class ScriptingError extends Exception { /** - * @param {string} message - Exception message - */ + * @param {string} message - Exception message + */ constructor(message) { super(message); } } /** - * Plugin-referred exceptions - * @memberof module:API.cvat.exceptions - * @extends module:API.cvat.exceptions.Exception - */ + * Plugin-referred exceptions + * @memberof module:API.cvat.exceptions + * @extends module:API.cvat.exceptions.Exception + */ class PluginError extends Exception { /** - * @param {string} message - Exception message - */ + * @param {string} message - Exception message + */ constructor(message) { super(message); } } /** - * Exceptions in interaction with a server - * @memberof module:API.cvat.exceptions - * @extends module:API.cvat.exceptions.Exception - */ + * Exceptions in interaction with a server + * @memberof module:API.cvat.exceptions + * @extends module:API.cvat.exceptions.Exception + */ class ServerError extends Exception { /** - * @param {string} message - Exception message - * @param {(string|integer)} code - Response code - */ + * @param {string} message - Exception message + * @param {(string|integer)} code - Response code + */ constructor(message, code) { super(message); - Object.defineProperties(this, Object.freeze({ - /** - * @name code - * @type {(string|integer)} - * @memberof module:API.cvat.exceptions.ServerError - * @readonly - * @instance - */ - code: { - get: () => code, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + /** + * @name code + * @type {(string|integer)} + * @memberof module:API.cvat.exceptions.ServerError + * @readonly + * @instance + */ + code: { + get: () => code, + }, + }), + ); } } diff --git a/cvat-core/src/frames.js b/cvat-core/src/frames.js index 0e95d42d..add59ff6 100644 --- a/cvat-core/src/frames.js +++ b/cvat-core/src/frames.js @@ -1,12 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false - global:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const cvatData = require('cvat-data'); @@ -19,100 +13,95 @@ const frameDataCache = {}; /** - * Class provides meta information about specific frame and frame itself - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class provides meta information about specific frame and frame itself + * @memberof module:API.cvat.classes + * @hideconstructor + */ class FrameData { constructor({ - width, - height, - name, - taskID, - frameNumber, - startFrame, - stopFrame, - decodeForward, + width, height, name, taskID, frameNumber, startFrame, stopFrame, decodeForward, }) { - Object.defineProperties(this, Object.freeze({ - /** - * @name filename - * @type {string} - * @memberof module:API.cvat.classes.FrameData - * @readonly - * @instance - */ - filename: { - value: name, - writable: false, - }, - /** - * @name width - * @type {integer} - * @memberof module:API.cvat.classes.FrameData - * @readonly - * @instance - */ - width: { - value: width, - writable: false, - }, - /** - * @name height - * @type {integer} - * @memberof module:API.cvat.classes.FrameData - * @readonly - * @instance - */ - height: { - value: height, - writable: false, - }, - tid: { - value: taskID, - writable: false, - }, - /** - * @name number - * @type {integer} - * @memberof module:API.cvat.classes.FrameData - * @readonly - * @instance - */ - number: { - value: frameNumber, - writable: false, - }, - startFrame: { - value: startFrame, - writable: false, - }, - stopFrame: { - value: stopFrame, - writable: false, - }, - decodeForward: { - value: decodeForward, - writable: false, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + /** + * @name filename + * @type {string} + * @memberof module:API.cvat.classes.FrameData + * @readonly + * @instance + */ + filename: { + value: name, + writable: false, + }, + /** + * @name width + * @type {integer} + * @memberof module:API.cvat.classes.FrameData + * @readonly + * @instance + */ + width: { + value: width, + writable: false, + }, + /** + * @name height + * @type {integer} + * @memberof module:API.cvat.classes.FrameData + * @readonly + * @instance + */ + height: { + value: height, + writable: false, + }, + tid: { + value: taskID, + writable: false, + }, + /** + * @name number + * @type {integer} + * @memberof module:API.cvat.classes.FrameData + * @readonly + * @instance + */ + number: { + value: frameNumber, + writable: false, + }, + startFrame: { + value: startFrame, + writable: false, + }, + stopFrame: { + value: stopFrame, + writable: false, + }, + decodeForward: { + value: decodeForward, + writable: false, + }, + }), + ); } /** - * Method returns URL encoded image which can be placed in the img tag - * @method data - * @returns {string} - * @memberof module:API.cvat.classes.FrameData - * @instance - * @async - * @param {function} [onServerRequest = () => {}] - * callback which will be called if data absences local - * @throws {module:API.cvat.exception.ServerError} - * @throws {module:API.cvat.exception.PluginError} - */ + * Method returns URL encoded image which can be placed in the img tag + * @method data + * @returns {string} + * @memberof module:API.cvat.classes.FrameData + * @instance + * @async + * @param {function} [onServerRequest = () => {}] + * callback which will be called if data absences local + * @throws {module:API.cvat.exception.ServerError} + * @throws {module:API.cvat.exception.PluginError} + */ async data(onServerRequest = () => {}) { - const result = await PluginRegistry - .apiWrapper.call(this, FrameData.prototype.data, onServerRequest); + const result = await PluginRegistry.apiWrapper.call(this, FrameData.prototype.data, onServerRequest); return result; } } @@ -136,15 +125,14 @@ const { provider } = frameDataCache[this.tid]; const { chunkSize } = frameDataCache[this.tid]; const start = parseInt(this.number / chunkSize, 10) * chunkSize; - const stop = Math.min( - this.stopFrame, - (parseInt(this.number / chunkSize, 10) + 1) * chunkSize - 1, - ); + const stop = Math.min(this.stopFrame, (parseInt(this.number / chunkSize, 10) + 1) * chunkSize - 1); const chunkNumber = Math.floor(this.number / chunkSize); const onDecodeAll = async (frameNumber) => { - if (frameDataCache[this.tid].activeChunkRequest - && chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber) { + if ( + frameDataCache[this.tid].activeChunkRequest + && chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber + ) { const callbackArray = frameDataCache[this.tid].activeChunkRequest.callbacks; for (let i = callbackArray.length - 1; i >= 0; --i) { if (callbackArray[i].frameNumber === frameNumber) { @@ -160,8 +148,10 @@ }; const rejectRequestAll = () => { - if (frameDataCache[this.tid].activeChunkRequest - && chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber) { + if ( + frameDataCache[this.tid].activeChunkRequest + && chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber + ) { for (const r of frameDataCache[this.tid].activeChunkRequest.callbacks) { r.reject(r.frameNumber); } @@ -172,147 +162,160 @@ const makeActiveRequest = () => { const taskDataCache = frameDataCache[this.tid]; const activeChunk = taskDataCache.activeChunkRequest; - activeChunk.request = serverProxy.frames.getData(this.tid, - activeChunk.chunkNumber).then((chunk) => { - frameDataCache[this.tid].activeChunkRequest.completed = true; - if (!taskDataCache.nextChunkRequest) { - provider.requestDecodeBlock(chunk, - taskDataCache.activeChunkRequest.start, - taskDataCache.activeChunkRequest.stop, - taskDataCache.activeChunkRequest.onDecodeAll, - taskDataCache.activeChunkRequest.rejectRequestAll); - } - }).catch((exception) => { - if (exception instanceof Exception) { - reject(exception); - } else { - reject(new Exception(exception.message)); - } - }).finally(() => { - if (taskDataCache.nextChunkRequest) { - if (taskDataCache.activeChunkRequest) { - for (const r of taskDataCache.activeChunkRequest.callbacks) { - r.reject(r.frameNumber); + activeChunk.request = serverProxy.frames + .getData(this.tid, activeChunk.chunkNumber) + .then((chunk) => { + frameDataCache[this.tid].activeChunkRequest.completed = true; + if (!taskDataCache.nextChunkRequest) { + provider.requestDecodeBlock( + chunk, + taskDataCache.activeChunkRequest.start, + taskDataCache.activeChunkRequest.stop, + taskDataCache.activeChunkRequest.onDecodeAll, + taskDataCache.activeChunkRequest.rejectRequestAll, + ); + } + }) + .catch((exception) => { + if (exception instanceof Exception) { + reject(exception); + } else { + reject(new Exception(exception.message)); + } + }) + .finally(() => { + if (taskDataCache.nextChunkRequest) { + if (taskDataCache.activeChunkRequest) { + for (const r of taskDataCache.activeChunkRequest.callbacks) { + r.reject(r.frameNumber); + } } + taskDataCache.activeChunkRequest = taskDataCache.nextChunkRequest; + taskDataCache.nextChunkRequest = null; + makeActiveRequest(); } - taskDataCache.activeChunkRequest = taskDataCache.nextChunkRequest; - taskDataCache.nextChunkRequest = null; - makeActiveRequest(); - } - }); + }); }; if (isNode) { resolve('Dummy data'); } else if (isBrowser) { - provider.frame(this.number).then((frame) => { - if (frame === null) { - onServerRequest(); - const activeRequest = frameDataCache[this.tid].activeChunkRequest; - if (!provider.isChunkCached(start, stop)) { - if (!activeRequest - || (activeRequest - && activeRequest.completed - && activeRequest.chunkNumber !== chunkNumber)) { - if (activeRequest && activeRequest.rejectRequestAll) { - activeRequest.rejectRequestAll(); - } - frameDataCache[this.tid].activeChunkRequest = { - request: null, - chunkNumber, - start, - stop, - onDecodeAll, - rejectRequestAll, - completed: false, - callbacks: [{ + provider + .frame(this.number) + .then((frame) => { + if (frame === null) { + onServerRequest(); + const activeRequest = frameDataCache[this.tid].activeChunkRequest; + if (!provider.isChunkCached(start, stop)) { + if ( + !activeRequest + || (activeRequest + && activeRequest.completed + && activeRequest.chunkNumber !== chunkNumber) + ) { + if (activeRequest && activeRequest.rejectRequestAll) { + activeRequest.rejectRequestAll(); + } + frameDataCache[this.tid].activeChunkRequest = { + request: null, + chunkNumber, + start, + stop, + onDecodeAll, + rejectRequestAll, + completed: false, + callbacks: [ + { + resolve: resolveWrapper, + reject, + frameNumber: this.number, + }, + ], + }; + makeActiveRequest(); + } else if (activeRequest.chunkNumber === chunkNumber) { + if (!activeRequest.onDecodeAll && !activeRequest.rejectRequestAll) { + activeRequest.onDecodeAll = onDecodeAll; + activeRequest.rejectRequestAll = rejectRequestAll; + } + activeRequest.callbacks.push({ resolve: resolveWrapper, reject, frameNumber: this.number, - }], - }; - makeActiveRequest(); - } else if (activeRequest.chunkNumber === chunkNumber) { - if (!activeRequest.onDecodeAll - && !activeRequest.rejectRequestAll) { - activeRequest.onDecodeAll = onDecodeAll; - activeRequest.rejectRequestAll = rejectRequestAll; + }); + } else { + if (frameDataCache[this.tid].nextChunkRequest) { + const { callbacks } = frameDataCache[this.tid].nextChunkRequest; + for (const r of callbacks) { + r.reject(r.frameNumber); + } + } + frameDataCache[this.tid].nextChunkRequest = { + request: null, + chunkNumber, + start, + stop, + onDecodeAll, + rejectRequestAll, + completed: false, + callbacks: [ + { + resolve: resolveWrapper, + reject, + frameNumber: this.number, + }, + ], + }; } + } else { activeRequest.callbacks.push({ resolve: resolveWrapper, reject, frameNumber: this.number, }); - } else { - if (frameDataCache[this.tid].nextChunkRequest) { - const { callbacks } = frameDataCache[this.tid].nextChunkRequest; - for (const r of callbacks) { - r.reject(r.frameNumber); - } - } - frameDataCache[this.tid].nextChunkRequest = { - request: null, - chunkNumber, - start, - stop, - onDecodeAll, - rejectRequestAll, - completed: false, - callbacks: [{ - resolve: resolveWrapper, - reject, - frameNumber: this.number, - }], - }; + provider.requestDecodeBlock(null, start, stop, onDecodeAll, rejectRequestAll); } } else { - activeRequest.callbacks.push({ - resolve: resolveWrapper, - reject, - frameNumber: this.number, - }); - provider.requestDecodeBlock(null, start, stop, - onDecodeAll, rejectRequestAll); - } - } else { - if (this.number % chunkSize > chunkSize / 4 - && provider.decodedBlocksCacheSize > 1 - && this.decodeForward - && !provider.isNextChunkExists(this.number)) { - const nextChunkNumber = Math.floor(this.number / chunkSize) + 1; - if (nextChunkNumber * chunkSize < this.stopFrame) { - provider.setReadyToLoading(nextChunkNumber); - const nextStart = nextChunkNumber * chunkSize; - const nextStop = (nextChunkNumber + 1) * chunkSize - 1; - if (!provider.isChunkCached(nextStart, nextStop)) { - if (!frameDataCache[this.tid].activeChunkRequest) { - frameDataCache[this.tid].activeChunkRequest = { - request: null, - chunkNumber: nextChunkNumber, - start: nextStart, - stop: nextStop, - onDecodeAll: null, - rejectRequestAll: null, - completed: false, - callbacks: [], - }; - makeActiveRequest(); + if ( + this.number % chunkSize > chunkSize / 4 + && provider.decodedBlocksCacheSize > 1 + && this.decodeForward + && !provider.isNextChunkExists(this.number) + ) { + const nextChunkNumber = Math.floor(this.number / chunkSize) + 1; + if (nextChunkNumber * chunkSize < this.stopFrame) { + provider.setReadyToLoading(nextChunkNumber); + const nextStart = nextChunkNumber * chunkSize; + const nextStop = (nextChunkNumber + 1) * chunkSize - 1; + if (!provider.isChunkCached(nextStart, nextStop)) { + if (!frameDataCache[this.tid].activeChunkRequest) { + frameDataCache[this.tid].activeChunkRequest = { + request: null, + chunkNumber: nextChunkNumber, + start: nextStart, + stop: nextStop, + onDecodeAll: null, + rejectRequestAll: null, + completed: false, + callbacks: [], + }; + makeActiveRequest(); + } + } else { + provider.requestDecodeBlock(null, nextStart, nextStop, null, null); } - } else { - provider.requestDecodeBlock(null, nextStart, nextStop, - null, null); } } + resolveWrapper(frame); } - resolveWrapper(frame); - } - }).catch((exception) => { - if (exception instanceof Exception) { - reject(exception); - } else { - reject(new Exception(exception.message)); - } - }); + }) + .catch((exception) => { + if (exception instanceof Exception) { + reject(exception); + } else { + reject(new Exception(exception.message)); + } + }); } }); }; @@ -324,16 +327,12 @@ [size] = meta.frames; } else if (mode === 'annotation') { if (frame >= meta.size) { - throw new ArgumentError( - `Meta information about frame ${frame} can't be received from the server`, - ); + throw new ArgumentError(`Meta information about frame ${frame} can't be received from the server`); } else { size = meta.frames[frame]; } } else { - throw new DataError( - `Invalid mode is specified ${mode}`, - ); + throw new DataError(`Invalid mode is specified ${mode}`); } return size; } @@ -377,23 +376,28 @@ decodeForward: false, }); - frameData.data().then(() => { - if (!(chunkIdx in this._requestedChunks) - || !this._requestedChunks[chunkIdx].requestedFrames.has(requestedFrame)) { - reject(chunkIdx); - } else { - this._requestedChunks[chunkIdx].requestedFrames.delete(requestedFrame); - this._requestedChunks[chunkIdx].buffer[requestedFrame] = frameData; - if (this._requestedChunks[chunkIdx].requestedFrames.size === 0) { - const bufferedframes = Object.keys( - this._requestedChunks[chunkIdx].buffer, - ).map((f) => +f); - this._requestedChunks[chunkIdx].resolve(new Set(bufferedframes)); + frameData + .data() + .then(() => { + if ( + !(chunkIdx in this._requestedChunks) + || !this._requestedChunks[chunkIdx].requestedFrames.has(requestedFrame) + ) { + reject(chunkIdx); + } else { + this._requestedChunks[chunkIdx].requestedFrames.delete(requestedFrame); + this._requestedChunks[chunkIdx].buffer[requestedFrame] = frameData; + if (this._requestedChunks[chunkIdx].requestedFrames.size === 0) { + const bufferedframes = Object.keys(this._requestedChunks[chunkIdx].buffer).map( + (f) => +f, + ); + this._requestedChunks[chunkIdx].resolve(new Set(bufferedframes)); + } } - } - }).catch(() => { - reject(chunkIdx); - }); + }) + .catch(() => { + reject(chunkIdx); + }); } }); } @@ -455,7 +459,7 @@ await this.fillBuffer(start, step, count); this._activeFillBufferRequest = false; } catch (error) { - if (typeof (error) === 'number' && error in this._requestedChunks) { + if (typeof error === 'number' && error in this._requestedChunks) { this._activeFillBufferRequest = false; } throw error; @@ -465,8 +469,7 @@ async require(frameNumber, taskID, fillBuffer, frameStep) { for (const frame in this._buffer) { - if (frame < frameNumber - || frame >= frameNumber + this._size * frameStep) { + if (frame < frameNumber || frame >= frameNumber + this._size * frameStep) { delete this._buffer[frame]; } } @@ -486,9 +489,12 @@ frame = this._buffer[frameNumber]; delete this._buffer[frameNumber]; const cachedFrames = this.cachedFrames(); - if (fillBuffer && !this._activeFillBufferRequest + if ( + fillBuffer + && !this._activeFillBufferRequest && this._size > this._chunkSize - && cachedFrames.length < (this._size * 3) / 4) { + && cachedFrames.length < (this._size * 3) / 4 + ) { const maxFrame = cachedFrames ? Math.max(...cachedFrames) : frameNumber; if (maxFrame < this._stopFrame) { this.makeFillRequest(maxFrame + 1, frameStep).catch((e) => { @@ -512,8 +518,10 @@ clear() { for (const chunkIdx in this._requestedChunks) { - if (Object.prototype.hasOwnProperty.call(this._requestedChunks, chunkIdx) - && this._requestedChunks[chunkIdx].reject) { + if ( + Object.prototype.hasOwnProperty.call(this._requestedChunks, chunkIdx) + && this._requestedChunks[chunkIdx].reject + ) { this._requestedChunks[chunkIdx].reject('not needed'); } } @@ -530,38 +538,39 @@ async function getPreview(taskID) { return new Promise((resolve, reject) => { // Just go to server and get preview (no any cache) - serverProxy.frames.getPreview(taskID).then((result) => { - if (isNode) { - resolve(global.Buffer.from(result, 'binary').toString('base64')); - } else if (isBrowser) { - const reader = new FileReader(); - reader.onload = () => { - resolve(reader.result); - }; - reader.readAsDataURL(result); - } - }).catch((error) => { - reject(error); - }); + serverProxy.frames + .getPreview(taskID) + .then((result) => { + if (isNode) { + // eslint-disable-next-line no-undef + resolve(global.Buffer.from(result, 'binary').toString('base64')); + } else if (isBrowser) { + const reader = new FileReader(); + reader.onload = () => { + resolve(reader.result); + }; + reader.readAsDataURL(result); + } + }) + .catch((error) => { + reject(error); + }); }); } - async function getFrame(taskID, chunkSize, chunkType, mode, frame, - startFrame, stopFrame, isPlaying, step) { + async function getFrame(taskID, chunkSize, chunkType, mode, frame, startFrame, stopFrame, isPlaying, step) { if (!(taskID in frameDataCache)) { - const blockType = chunkType === 'video' ? cvatData.BlockType.MP4VIDEO - : cvatData.BlockType.ARCHIVE; + const blockType = chunkType === 'video' ? cvatData.BlockType.MP4VIDEO : cvatData.BlockType.ARCHIVE; const meta = await serverProxy.frames.getMeta(taskID); - const mean = meta.frames.reduce((a, b) => a + b.width * b.height, 0) - / meta.frames.length; - const stdDev = Math.sqrt(meta.frames.map( - (x) => Math.pow(x.width * x.height - mean, 2), - ).reduce((a, b) => a + b) / meta.frames.length); + const mean = meta.frames.reduce((a, b) => a + b.width * b.height, 0) / meta.frames.length; + const stdDev = Math.sqrt( + meta.frames.map((x) => Math.pow(x.width * x.height - mean, 2)).reduce((a, b) => a + b) + / meta.frames.length, + ); // limit of decoded frames cache by 2GB - const decodedBlocksCacheSize = Math.floor(2147483648 / (mean + stdDev) / 4 / chunkSize) - || 1; + const decodedBlocksCacheSize = Math.floor(2147483648 / (mean + stdDev) / 4 / chunkSize) || 1; frameDataCache[taskID] = { meta, @@ -570,8 +579,11 @@ startFrame, stopFrame, provider: new cvatData.FrameProvider( - blockType, chunkSize, Math.max(decodedBlocksCacheSize, 9), - decodedBlocksCacheSize, 1, + blockType, + chunkSize, + Math.max(decodedBlocksCacheSize, 9), + decodedBlocksCacheSize, + 1, ), frameBuffer: new FrameBuffer( Math.min(180, decodedBlocksCacheSize * chunkSize), diff --git a/cvat-core/src/issue.js b/cvat-core/src/issue.js new file mode 100644 index 00000000..e18ae3ed --- /dev/null +++ b/cvat-core/src/issue.js @@ -0,0 +1,335 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +const quickhull = require('quickhull'); + +const PluginRegistry = require('./plugins'); +const Comment = require('./comment'); +const User = require('./user'); +const { ArgumentError } = require('./exceptions'); +const { negativeIDGenerator } = require('./common'); +const serverProxy = require('./server-proxy'); + +/** + * Class representing a single issue + * @memberof module:API.cvat.classes + * @hideconstructor + */ +class Issue { + constructor(initialData) { + const data = { + id: undefined, + position: undefined, + comment_set: [], + frame: undefined, + created_date: undefined, + resolved_date: undefined, + owner: undefined, + resolver: undefined, + removed: false, + }; + + for (const property in data) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { + data[property] = initialData[property]; + } + } + + if (data.owner && !(data.owner instanceof User)) data.owner = new User(data.owner); + if (data.resolver && !(data.resolver instanceof User)) data.resolver = new User(data.resolver); + + if (data.comment_set) { + data.comment_set = data.comment_set.map((comment) => new Comment(comment)); + } + + if (typeof data.id === 'undefined') { + data.id = negativeIDGenerator(); + } + if (typeof data.created_date === 'undefined') { + data.created_date = new Date().toISOString(); + } + + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * Region of interests of the issue + * @name position + * @type {number[]} + * @memberof module:API.cvat.classes.Issue + * @instance + * @readonly + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + position: { + get: () => data.position, + set: (value) => { + if (Array.isArray(value) || value.some((coord) => typeof coord !== 'number')) { + throw new ArgumentError(`Array of numbers is expected. Got ${value}`); + } + data.position = value; + }, + }, + /** + * List of comments attached to the issue + * @name comments + * @type {module:API.cvat.classes.Comment[]} + * @memberof module:API.cvat.classes.Issue + * @instance + * @readonly + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + comments: { + get: () => data.comment_set.filter((comment) => !comment.removed), + }, + /** + * @name frame + * @type {integer} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + frame: { + get: () => data.frame, + }, + /** + * @name createdDate + * @type {string} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + createdDate: { + get: () => data.created_date, + }, + /** + * @name resolvedDate + * @type {string} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + resolvedDate: { + get: () => data.resolved_date, + }, + /** + * An instance of a user who has raised the issue + * @name owner + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + owner: { + get: () => data.owner, + }, + /** + * An instance of a user who has resolved the issue + * @name resolver + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + */ + resolver: { + get: () => data.resolver, + }, + /** + * @name removed + * @type {boolean} + * @memberof module:API.cvat.classes.Comment + * @instance + */ + removed: { + get: () => data.removed, + set: (value) => { + if (typeof value !== 'boolean') { + throw new ArgumentError('Value must be a boolean value'); + } + data.removed = value; + }, + }, + __internal: { + get: () => data, + }, + }), + ); + } + + static hull(coordinates) { + if (coordinates.length > 4) { + const points = coordinates.reduce((acc, coord, index, arr) => { + if (index % 2) acc.push({ x: arr[index - 1], y: coord }); + return acc; + }, []); + + return quickhull(points) + .map((point) => [point.x, point.y]) + .flat(); + } + + return coordinates; + } + + /** + * @typedef {Object} CommentData + * @property {number} [author] an ID of a user who has created the comment + * @property {string} message a comment message + * @global + */ + /** + * Method appends a comment to the issue + * For a new issue it saves comment locally, for a saved issue it saves comment on the server + * @method comment + * @memberof module:API.cvat.classes.Issue + * @param {CommentData} data + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + async comment(data) { + const result = await PluginRegistry.apiWrapper.call(this, Issue.prototype.comment, data); + return result; + } + + /** + * The method resolves the issue + * New issues are resolved locally, server-saved issues are resolved on the server + * @method resolve + * @memberof module:API.cvat.classes.Issue + * @param {module:API.cvat.classes.User} user + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + async resolve(user) { + const result = await PluginRegistry.apiWrapper.call(this, Issue.prototype.resolve, user); + return result; + } + + /** + * The method resolves the issue + * New issues are reopened locally, server-saved issues are reopened on the server + * @method reopen + * @memberof module:API.cvat.classes.Issue + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + async reopen() { + const result = await PluginRegistry.apiWrapper.call(this, Issue.prototype.reopen); + return result; + } + + serialize() { + const { comments } = this; + const data = { + position: this.position, + frame: this.frame, + comment_set: comments.map((comment) => comment.serialize()), + }; + + if (this.id > 0) { + data.id = this.id; + } + if (this.createdDate) { + data.created_date = this.createdDate; + } + if (this.resolvedDate) { + data.resolved_date = this.resolvedDate; + } + if (this.owner) { + data.owner = this.owner.toJSON(); + } + if (this.resolver) { + data.resolver = this.resolver.toJSON(); + } + + return data; + } + + toJSON() { + const data = this.serialize(); + const { owner, resolver, ...updated } = data; + return { + ...updated, + comment_set: this.comments.map((comment) => comment.toJSON()), + owner_id: owner ? owner.id : undefined, + resolver_id: resolver ? resolver.id : undefined, + }; + } +} + +Issue.prototype.comment.implementation = async function (data) { + if (typeof data !== 'object' || data === null) { + throw new ArgumentError(`The argument "data" must be a not null object. Got ${data}`); + } + if (typeof data.message !== 'string' || data.message.length < 1) { + throw new ArgumentError(`Comment message must be a not empty string. Got ${data.message}`); + } + if (!(data.author instanceof User)) { + throw new ArgumentError(`Author of the comment must a User instance. Got ${data.author}`); + } + + const comment = new Comment(data); + const { id } = this; + if (id >= 0) { + const jsonified = comment.toJSON(); + jsonified.issue = id; + const response = await serverProxy.comments.create(jsonified); + const savedComment = new Comment(response); + this.__internal.comment_set.push(savedComment); + } else { + this.__internal.comment_set.push(comment); + } +}; + +Issue.prototype.resolve.implementation = async function (user) { + if (!(user instanceof User)) { + throw new ArgumentError(`The argument "user" must be an instance of a User class. Got ${typeof user}`); + } + + const { id } = this; + if (id >= 0) { + const response = await serverProxy.issues.update(id, { resolver_id: user.id }); + this.__internal.resolved_date = response.resolved_date; + this.__internal.resolver = new User(response.resolver); + } else { + this.__internal.resolved_date = new Date().toISOString(); + this.__internal.resolver = user; + } +}; + +Issue.prototype.reopen.implementation = async function () { + const { id } = this; + if (id >= 0) { + const response = await serverProxy.issues.update(id, { resolver_id: null }); + this.__internal.resolved_date = response.resolved_date; + this.__internal.resolver = response.resolver; + } else { + this.__internal.resolved_date = null; + this.__internal.resolver = null; + } +}; + +module.exports = Issue; diff --git a/cvat-core/src/labels.js b/cvat-core/src/labels.js index ec2c0cbb..7daf84c6 100644 --- a/cvat-core/src/labels.js +++ b/cvat-core/src/labels.js @@ -1,23 +1,16 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { - const { - AttributeType, - } = require('./enums'); + const { AttributeType } = require('./enums'); const { ArgumentError } = require('./exceptions'); /** - * Class representing an attribute - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing an attribute + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Attribute { constructor(initialData) { const data = { @@ -42,73 +35,74 @@ } if (!Object.values(AttributeType).includes(data.input_type)) { - throw new ArgumentError( - `Got invalid attribute type ${data.input_type}`, - ); + throw new ArgumentError(`Got invalid attribute type ${data.input_type}`); } - Object.defineProperties(this, Object.freeze({ - /** - * @name id - * @type {integer} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - id: { - get: () => data.id, - }, - /** - * @name defaultValue - * @type {(string|integer|boolean)} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - defaultValue: { - get: () => data.default_value, - }, - /** - * @name inputType - * @type {module:API.cvat.enums.AttributeType} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - inputType: { - get: () => data.input_type, - }, - /** - * @name mutable - * @type {boolean} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - mutable: { - get: () => data.mutable, - }, - /** - * @name name - * @type {string} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - name: { - get: () => data.name, - }, - /** - * @name values - * @type {(string[]|integer[]|boolean[])} - * @memberof module:API.cvat.classes.Attribute - * @readonly - * @instance - */ - values: { - get: () => [...data.values], - }, - })); + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * @name defaultValue + * @type {(string|integer|boolean)} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + defaultValue: { + get: () => data.default_value, + }, + /** + * @name inputType + * @type {module:API.cvat.enums.AttributeType} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + inputType: { + get: () => data.input_type, + }, + /** + * @name mutable + * @type {boolean} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + mutable: { + get: () => data.mutable, + }, + /** + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + name: { + get: () => data.name, + }, + /** + * @name values + * @type {(string[]|integer[]|boolean[])} + * @memberof module:API.cvat.classes.Attribute + * @readonly + * @instance + */ + values: { + get: () => [...data.values], + }, + }), + ); } toJSON() { @@ -120,7 +114,7 @@ values: this.values, }; - if (typeof (this.id) !== 'undefined') { + if (typeof this.id !== 'undefined') { object.id = this.id; } @@ -129,10 +123,10 @@ } /** - * Class representing a label - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing a label + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Label { constructor(initialData) { const data = { @@ -151,62 +145,67 @@ data.attributes = []; - if (Object.prototype.hasOwnProperty.call(initialData, 'attributes') - && Array.isArray(initialData.attributes)) { + if ( + Object.prototype.hasOwnProperty.call(initialData, 'attributes') + && Array.isArray(initialData.attributes) + ) { for (const attrData of initialData.attributes) { data.attributes.push(new Attribute(attrData)); } } - Object.defineProperties(this, Object.freeze({ - /** - * @name id - * @type {integer} - * @memberof module:API.cvat.classes.Label - * @readonly - * @instance - */ - id: { - get: () => data.id, - }, - /** - * @name name - * @type {string} - * @memberof module:API.cvat.classes.Label - * @readonly - * @instance - */ - name: { - get: () => data.name, - }, - /** - * @name color - * @type {string} - * @memberof module:API.cvat.classes.Label - * @readonly - * @instance - */ - color: { - get: () => data.color, - set: (color) => { - if (typeof color === 'string' && color.match(/^#[0-9a-f]{6}$|^$/)) { - data.color = color; - } else { - throw new ArgumentError('Trying to set wrong color format'); - } + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Label + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Label + * @readonly + * @instance + */ + name: { + get: () => data.name, + }, + /** + * @name color + * @type {string} + * @memberof module:API.cvat.classes.Label + * @readonly + * @instance + */ + color: { + get: () => data.color, + set: (color) => { + if (typeof color === 'string' && color.match(/^#[0-9a-f]{6}$|^$/)) { + data.color = color; + } else { + throw new ArgumentError('Trying to set wrong color format'); + } + }, + }, + /** + * @name attributes + * @type {module:API.cvat.classes.Attribute[]} + * @memberof module:API.cvat.classes.Label + * @readonly + * @instance + */ + attributes: { + get: () => [...data.attributes], }, - }, - /** - * @name attributes - * @type {module:API.cvat.classes.Attribute[]} - * @memberof module:API.cvat.classes.Label - * @readonly - * @instance - */ - attributes: { - get: () => [...data.attributes], - }, - })); + }), + ); } toJSON() { @@ -216,7 +215,7 @@ color: this.color, }; - if (typeof (this.id) !== 'undefined') { + if (typeof this.id !== 'undefined') { object.id = this.id; } diff --git a/cvat-core/src/lambda-manager.js b/cvat-core/src/lambda-manager.js index 4b936cd2..921cd861 100644 --- a/cvat-core/src/lambda-manager.js +++ b/cvat-core/src/lambda-manager.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const serverProxy = require('./server-proxy'); const { ArgumentError } = require('./exceptions'); @@ -28,14 +23,12 @@ class LambdaManager { const models = []; for (const model of result) { - models.push(new MLModel({ - id: model.id, - name: model.name, - description: model.description, - framework: model.framework, - labels: [...model.labels], - type: model.kind, - })); + models.push( + new MLModel({ + ...model, + type: model.kind, + }), + ); } this.cachedList = models; @@ -45,20 +38,18 @@ class LambdaManager { async run(task, model, args) { if (!(task instanceof Task)) { throw new ArgumentError( - `Argument task is expected to be an instance of Task class, but got ${typeof (task)}`, + `Argument task is expected to be an instance of Task class, but got ${typeof task}`, ); } if (!(model instanceof MLModel)) { throw new ArgumentError( - `Argument model is expected to be an instance of MLModel class, but got ${typeof (model)}`, + `Argument model is expected to be an instance of MLModel class, but got ${typeof model}`, ); } - if (args && typeof (args) !== 'object') { - throw new ArgumentError( - `Argument args is expected to be an object, but got ${typeof (model)}`, - ); + if (args && typeof args !== 'object') { + throw new ArgumentError(`Argument args is expected to be an object, but got ${typeof model}`); } const body = args; @@ -82,7 +73,7 @@ class LambdaManager { } async cancel(requestID) { - if (typeof (requestID) !== 'string') { + if (typeof requestID !== 'string') { throw new ArgumentError(`Request id argument is required to be a string. But got ${requestID}`); } @@ -112,7 +103,11 @@ class LambdaManager { delete this.listening[requestID]; } } catch (error) { - onUpdate(RQStatus.UNKNOWN, 0, `Could not get a status of the request ${requestID}. ${error.toString()}`); + onUpdate( + RQStatus.UNKNOWN, + 0, + `Could not get a status of the request ${requestID}. ${error.toString()}`, + ); } }; diff --git a/cvat-core/src/log.js b/cvat-core/src/log.js index cf3df86d..372ab040 100644 --- a/cvat-core/src/log.js +++ b/cvat-core/src/log.js @@ -1,21 +1,17 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2019-2020 Intel Corporation // // SPDX-License-Identifier: MIT -/* global - require:false -*/ - const { detect } = require('detect-browser'); const PluginRegistry = require('./plugins'); const { ArgumentError } = require('./exceptions'); const { LogType } = require('./enums'); /** - * Class representing a single log - * @memberof module:API.cvat.classes - * @hideconstructor -*/ + * Class representing a single log + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Log { constructor(logType, payload) { this.onCloseCallback = null; @@ -30,7 +26,7 @@ class Log { } validatePayload() { - if (typeof (this.payload) !== 'object') { + if (typeof this.payload !== 'object') { throw new ArgumentError('Payload must be an object'); } @@ -63,22 +59,21 @@ class Log { } /** - * Method saves a durable log in a storage
    - * Note then you can call close() multiple times
    - * Log duration will be computed based on the latest call
    - * All payloads will be shallowly combined (all top level properties will exist) - * @method close - * @memberof module:API.cvat.classes.Log - * @param {object} [payload] part of payload can be added when close a log - * @readonly - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Method saves a durable log in a storage
    + * Note then you can call close() multiple times
    + * Log duration will be computed based on the latest call
    + * All payloads will be shallowly combined (all top level properties will exist) + * @method close + * @memberof module:API.cvat.classes.Log + * @param {object} [payload] part of payload can be added when close a log + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ async close(payload = {}) { - const result = await PluginRegistry - .apiWrapper.call(this, Log.prototype.close, payload); + const result = await PluginRegistry.apiWrapper.call(this, Log.prototype.close, payload); return result; } } @@ -96,8 +91,7 @@ class LogWithCount extends Log { validatePayload() { Log.prototype.validatePayload.call(this); if (!Number.isInteger(this.payload.count) || this.payload.count < 1) { - const message = `The field "count" is required for "${this.type}" log` - + 'It must be a positive integer'; + const message = `The field "count" is required for "${this.type}" log. It must be a positive integer`; throw new ArgumentError(message); } } @@ -148,12 +142,14 @@ class LogWithWorkingTime extends Log { validatePayload() { Log.prototype.validatePayload.call(this); - if (!('working_time' in this.payload) - || !typeof (this.payload.working_time) === 'number' + if ( + !('working_time' in this.payload) + || !typeof this.payload.working_time === 'number' || this.payload.working_time < 0 ) { - const message = `The field "working_time" is required for ${this.type} log. ` - + 'It must be a number not less than 0'; + const message = ` + The field "working_time" is required for ${this.type} log. It must be a number not less than 0 + `; throw new ArgumentError(message); } } @@ -163,40 +159,35 @@ class LogWithExceptionInfo extends Log { validatePayload() { Log.prototype.validatePayload.call(this); - if (typeof (this.payload.message) !== 'string') { - const message = `The field "message" is required for ${this.type} log. ` - + 'It must be a string'; + if (typeof this.payload.message !== 'string') { + const message = `The field "message" is required for ${this.type} log. It must be a string`; throw new ArgumentError(message); } - if (typeof (this.payload.filename) !== 'string') { - const message = `The field "filename" is required for ${this.type} log. ` - + 'It must be a string'; + if (typeof this.payload.filename !== 'string') { + const message = `The field "filename" is required for ${this.type} log. It must be a string`; throw new ArgumentError(message); } - if (typeof (this.payload.line) !== 'number') { - const message = `The field "line" is required for ${this.type} log. ` - + 'It must be a number'; + if (typeof this.payload.line !== 'number') { + const message = `The field "line" is required for ${this.type} log. It must be a number`; throw new ArgumentError(message); } - if (typeof (this.payload.column) !== 'number') { - const message = `The field "column" is required for ${this.type} log. ` - + 'It must be a number'; + if (typeof this.payload.column !== 'number') { + const message = `The field "column" is required for ${this.type} log. It must be a number`; throw new ArgumentError(message); } - if (typeof (this.payload.stack) !== 'string') { - const message = `The field "stack" is required for ${this.type} log. ` - + 'It must be a string'; + if (typeof this.payload.stack !== 'string') { + const message = `The field "stack" is required for ${this.type} log. It must be a string`; throw new ArgumentError(message); } } dump() { let body = super.dump(); - const payload = body.payload; + const { payload } = body; const client = detect(); body = { ...body, @@ -222,8 +213,11 @@ class LogWithExceptionInfo extends Log { function logFactory(logType, payload) { const logsWithCount = [ - LogType.deleteObject, LogType.mergeObjects, LogType.copyObject, - LogType.undoAction, LogType.redoAction, + LogType.deleteObject, + LogType.mergeObjects, + LogType.copyObject, + LogType.undoAction, + LogType.redoAction, ]; if (logsWithCount.includes(logType)) { diff --git a/cvat-core/src/logger-storage.js b/cvat-core/src/logger-storage.js index ca6860af..c922d6d8 100644 --- a/cvat-core/src/logger-storage.js +++ b/cvat-core/src/logger-storage.js @@ -1,11 +1,7 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2019-2020 Intel Corporation // // SPDX-License-Identifier: MIT -/* global - require:false -*/ - const PluginRegistry = require('./plugins'); const serverProxy = require('./server-proxy'); const logFactory = require('./log'); @@ -14,6 +10,12 @@ const { LogType } = require('./enums'); const WORKING_TIME_THRESHOLD = 100000; // ms, 1.66 min +function sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); +} + class LoggerStorage { constructor() { this.clientID = Date.now().toString().substr(-6); @@ -22,6 +24,7 @@ class LoggerStorage { this.collection = []; this.ignoreRules = {}; // by event this.isActiveChecker = null; + this.saving = false; this.ignoreRules[LogType.zoomImage] = { lastLog: null, @@ -34,8 +37,10 @@ class LoggerStorage { this.ignoreRules[LogType.changeAttribute] = { lastLog: null, ignore(previousLog, currentPayload) { - return currentPayload.object_id === previousLog.payload.object_id - && currentPayload.id === previousLog.payload.id; + return ( + currentPayload.object_id === previousLog.payload.object_id + && currentPayload.id === previousLog.payload.id + ); }, }; } @@ -50,32 +55,28 @@ class LoggerStorage { } async configure(isActiveChecker, activityHelper) { - const result = await PluginRegistry - .apiWrapper.call( - this, LoggerStorage.prototype.configure, - isActiveChecker, activityHelper, - ); + const result = await PluginRegistry.apiWrapper.call( + this, + LoggerStorage.prototype.configure, + isActiveChecker, + activityHelper, + ); return result; } async log(logType, payload = {}, wait = false) { - const result = await PluginRegistry - .apiWrapper.call(this, LoggerStorage.prototype.log, logType, payload, wait); + const result = await PluginRegistry.apiWrapper.call(this, LoggerStorage.prototype.log, logType, payload, wait); return result; } async save() { - const result = await PluginRegistry - .apiWrapper.call(this, LoggerStorage.prototype.save); + const result = await PluginRegistry.apiWrapper.call(this, LoggerStorage.prototype.save); return result; } } -LoggerStorage.prototype.configure.implementation = function ( - isActiveChecker, - userActivityCallback, -) { - if (typeof (isActiveChecker) !== 'function') { +LoggerStorage.prototype.configure.implementation = function (isActiveChecker, userActivityCallback) { + if (typeof isActiveChecker !== 'function') { throw new ArgumentError('isActiveChecker argument must be callable'); } @@ -88,11 +89,11 @@ LoggerStorage.prototype.configure.implementation = function ( }; LoggerStorage.prototype.log.implementation = function (logType, payload, wait) { - if (typeof (payload) !== 'object') { + if (typeof payload !== 'object') { throw new ArgumentError('Payload must be an object'); } - if (typeof (wait) !== 'boolean') { + if (typeof wait !== 'boolean') { throw new ArgumentError('Payload must be an object'); } @@ -146,6 +147,10 @@ LoggerStorage.prototype.log.implementation = function (logType, payload, wait) { }; LoggerStorage.prototype.save.implementation = async function () { + while (this.saving) { + await sleep(100); + } + const collectionToSend = [...this.collection]; const lastLog = this.collection[this.collection.length - 1]; @@ -164,14 +169,18 @@ LoggerStorage.prototype.save.implementation = async function () { const userActivityLog = logFactory(LogType.sendUserActivity, logPayload); collectionToSend.push(userActivityLog); - await serverProxy.logs.save(collectionToSend.map((log) => log.dump())); - - for (const rule of Object.values(this.ignoreRules)) { - rule.lastLog = null; + try { + this.saving = true; + await serverProxy.logs.save(collectionToSend.map((log) => log.dump())); + for (const rule of Object.values(this.ignoreRules)) { + rule.lastLog = null; + } + this.collection = []; + this.workingTime = 0; + this.lastLogTime = Date.now(); + } finally { + this.saving = false; } - this.collection = []; - this.workingTime = 0; - this.lastLogTime = Date.now(); }; module.exports = new LoggerStorage(); diff --git a/cvat-core/src/ml-model.js b/cvat-core/src/ml-model.js index 4169be8e..36016da8 100644 --- a/cvat-core/src/ml-model.js +++ b/cvat-core/src/ml-model.js @@ -1,12 +1,11 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT /** - * Class representing a machine learning model - * @memberof module:API.cvat.classes -*/ + * Class representing a machine learning model + * @memberof module:API.cvat.classes + */ class MLModel { constructor(data) { this._id = data.id; @@ -15,12 +14,17 @@ class MLModel { this._framework = data.framework; this._description = data.description; this._type = data.type; + this._params = { + canvas: { + minPosVertices: data.min_pos_points, + }, + }; } /** * @returns {string} * @readonly - */ + */ get id() { return this._id; } @@ -28,7 +32,7 @@ class MLModel { /** * @returns {string} * @readonly - */ + */ get name() { return this._name; } @@ -36,7 +40,7 @@ class MLModel { /** * @returns {string[]} * @readonly - */ + */ get labels() { if (Array.isArray(this._labels)) { return [...this._labels]; @@ -48,7 +52,7 @@ class MLModel { /** * @returns {string} * @readonly - */ + */ get framework() { return this._framework; } @@ -56,7 +60,7 @@ class MLModel { /** * @returns {string} * @readonly - */ + */ get description() { return this._description; } @@ -64,10 +68,20 @@ class MLModel { /** * @returns {module:API.cvat.enums.ModelType} * @readonly - */ + */ get type() { return this._type; } + + /** + * @returns {object} + * @readonly + */ + get params() { + return { + canvas: { ...this._params.canvas }, + }; + } } module.exports = MLModel; diff --git a/cvat-core/src/object-state.js b/cvat-core/src/object-state.js index 64cad384..8fb95292 100644 --- a/cvat-core/src/object-state.js +++ b/cvat-core/src/object-state.js @@ -1,31 +1,26 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const { Source } = require('./enums'); -/* global - require:false -*/ - (() => { const PluginRegistry = require('./plugins'); const { ArgumentError } = require('./exceptions'); /** - * Class representing a state of an object on a specific frame - * @memberof module:API.cvat.classes - */ + * Class representing a state of an object on a specific frame + * @memberof module:API.cvat.classes + */ class ObjectState { /** - * @param {Object} serialized - is an dictionary which contains - * initial information about an ObjectState; - *
    Necessary fields: objectType, shapeType, frame, updated, group - *
    Optional fields: keyframes, clientID, serverID - *
    Optional fields which can be set later: points, zOrder, outside, - * occluded, hidden, attributes, lock, label, color, keyframe, source - */ + * @param {Object} serialized - is an dictionary which contains + * initial information about an ObjectState; + *
    Necessary fields: objectType, shapeType, frame, updated, group + *
    Optional fields: keyframes, clientID, serverID + *
    Optional fields which can be set later: points, zOrder, outside, + * occluded, hidden, attributes, lock, label, color, keyframe, source + */ constructor(serialized) { const data = { label: null, @@ -77,282 +72,289 @@ const { Source } = require('./enums'); writable: false, }); - Object.defineProperties(this, Object.freeze({ - // Internal property. We don't need document it. - updateFlags: { - get: () => data.updateFlags, - }, - frame: { - /** - * @name frame - * @type {integer} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.frame, - }, - objectType: { - /** - * @name objectType - * @type {module:API.cvat.enums.ObjectType} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.objectType, - }, - shapeType: { - /** - * @name shapeType - * @type {module:API.cvat.enums.ObjectShape} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.shapeType, - }, - source: { - /** - * @name source - * @type {module:API.cvat.enums.Source} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.source, - }, - clientID: { - /** - * @name clientID - * @type {integer} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.clientID, - }, - serverID: { - /** - * @name serverID - * @type {integer} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => data.serverID, - }, - label: { - /** - * @name shape - * @type {module:API.cvat.classes.Label} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.label, - set: (labelInstance) => { - data.updateFlags.label = true; - data.label = labelInstance; + Object.defineProperties( + this, + Object.freeze({ + // Internal property. We don't need document it. + updateFlags: { + get: () => data.updateFlags, }, - }, - color: { - /** - * @name color - * @type {string} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.color, - set: (color) => { - data.updateFlags.color = true; - data.color = color; + frame: { + /** + * @name frame + * @type {integer} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.frame, }, - }, - hidden: { - /** - * @name hidden - * @type {boolean} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.hidden, - set: (hidden) => { - data.updateFlags.hidden = true; - data.hidden = hidden; + objectType: { + /** + * @name objectType + * @type {module:API.cvat.enums.ObjectType} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.objectType, }, - }, - points: { - /** - * @name points - * @type {number[]} - * @memberof module:API.cvat.classes.ObjectState - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - */ - get: () => data.points, - set: (points) => { - if (Array.isArray(points)) { - data.updateFlags.points = true; - data.points = [...points]; - } else { - throw new ArgumentError( - 'Points are expected to be an array ' - + `but got ${typeof (points) === 'object' - ? points.constructor.name : typeof (points)}`, - ); - } + shapeType: { + /** + * @name shapeType + * @type {module:API.cvat.enums.ObjectShape} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.shapeType, }, - }, - group: { - /** - * Object with short group info { color, id } - * @name group - * @type {object} - * @memberof module:API.cvat.classes.ObjectState - * @instance - * @readonly - */ - get: () => data.group, - }, - zOrder: { - /** - * @name zOrder - * @type {integer | null} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.zOrder, - set: (zOrder) => { - data.updateFlags.zOrder = true; - data.zOrder = zOrder; + source: { + /** + * @name source + * @type {module:API.cvat.enums.Source} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.source, }, - }, - outside: { - /** - * @name outside - * @type {boolean} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.outside, - set: (outside) => { - data.updateFlags.outside = true; - data.outside = outside; + clientID: { + /** + * @name clientID + * @type {integer} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.clientID, }, - }, - keyframe: { - /** - * @name keyframe - * @type {boolean} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.keyframe, - set: (keyframe) => { - data.updateFlags.keyframe = true; - data.keyframe = keyframe; + serverID: { + /** + * @name serverID + * @type {integer} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.serverID, }, - }, - keyframes: { - /** - * Object of keyframes { first, prev, next, last } - * @name keyframes - * @type {object | null} - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - */ - get: () => { - if (typeof (data.keyframes) === 'object') { - return { ...data.keyframes }; - } + label: { + /** + * @name shape + * @type {module:API.cvat.classes.Label} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.label, + set: (labelInstance) => { + data.updateFlags.label = true; + data.label = labelInstance; + }, + }, + color: { + /** + * @name color + * @type {string} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.color, + set: (color) => { + data.updateFlags.color = true; + data.color = color; + }, + }, + hidden: { + /** + * @name hidden + * @type {boolean} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.hidden, + set: (hidden) => { + data.updateFlags.hidden = true; + data.hidden = hidden; + }, + }, + points: { + /** + * @name points + * @type {number[]} + * @memberof module:API.cvat.classes.ObjectState + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + */ + get: () => data.points, + set: (points) => { + if (Array.isArray(points)) { + data.updateFlags.points = true; + data.points = [...points]; + } else { + throw new ArgumentError( + 'Points are expected to be an array ' + + `but got ${ + typeof points === 'object' ? points.constructor.name : typeof points + }`, + ); + } + }, + }, + group: { + /** + * Object with short group info { color, id } + * @name group + * @type {object} + * @memberof module:API.cvat.classes.ObjectState + * @instance + * @readonly + */ + get: () => data.group, + }, + zOrder: { + /** + * @name zOrder + * @type {integer | null} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.zOrder, + set: (zOrder) => { + data.updateFlags.zOrder = true; + data.zOrder = zOrder; + }, + }, + outside: { + /** + * @name outside + * @type {boolean} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.outside, + set: (outside) => { + data.updateFlags.outside = true; + data.outside = outside; + }, + }, + keyframe: { + /** + * @name keyframe + * @type {boolean} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.keyframe, + set: (keyframe) => { + data.updateFlags.keyframe = true; + data.keyframe = keyframe; + }, + }, + keyframes: { + /** + * Object of keyframes { first, prev, next, last } + * @name keyframes + * @type {object | null} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => { + if (typeof data.keyframes === 'object') { + return { ...data.keyframes }; + } - return null; + return null; + }, }, - }, - occluded: { - /** - * @name occluded - * @type {boolean} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.occluded, - set: (occluded) => { - data.updateFlags.occluded = true; - data.occluded = occluded; + occluded: { + /** + * @name occluded + * @type {boolean} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.occluded, + set: (occluded) => { + data.updateFlags.occluded = true; + data.occluded = occluded; + }, }, - }, - lock: { - /** - * @name lock - * @type {boolean} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => data.lock, - set: (lock) => { - data.updateFlags.lock = true; - data.lock = lock; + lock: { + /** + * @name lock + * @type {boolean} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => data.lock, + set: (lock) => { + data.updateFlags.lock = true; + data.lock = lock; + }, }, - }, - pinned: { - /** - * @name pinned - * @type {boolean | null} - * @memberof module:API.cvat.classes.ObjectState - * @instance - */ - get: () => { - if (typeof (data.pinned) === 'boolean') { - return data.pinned; - } + pinned: { + /** + * @name pinned + * @type {boolean | null} + * @memberof module:API.cvat.classes.ObjectState + * @instance + */ + get: () => { + if (typeof data.pinned === 'boolean') { + return data.pinned; + } - return null; + return null; + }, + set: (pinned) => { + data.updateFlags.pinned = true; + data.pinned = pinned; + }, }, - set: (pinned) => { - data.updateFlags.pinned = true; - data.pinned = pinned; + updated: { + /** + * Timestamp of the latest updated of the object + * @name updated + * @type {number} + * @memberof module:API.cvat.classes.ObjectState + * @instance + * @readonly + */ + get: () => data.updated, }, - }, - updated: { - /** - * Timestamp of the latest updated of the object - * @name updated - * @type {number} - * @memberof module:API.cvat.classes.ObjectState - * @instance - * @readonly - */ - get: () => data.updated, - }, - attributes: { - /** - * Object is id:value pairs where "id" is an integer - * attribute identifier and "value" is an attribute value - * @name attributes - * @type {Object} - * @memberof module:API.cvat.classes.ObjectState - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - */ - get: () => data.attributes, - set: (attributes) => { - if (typeof (attributes) !== 'object') { - throw new ArgumentError( - 'Attributes are expected to be an object ' - + `but got ${typeof (attributes) === 'object' - ? attributes.constructor.name : typeof (attributes)}`, - ); - } + attributes: { + /** + * Object is id:value pairs where "id" is an integer + * attribute identifier and "value" is an attribute value + * @name attributes + * @type {Object} + * @memberof module:API.cvat.classes.ObjectState + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + */ + get: () => data.attributes, + set: (attributes) => { + if (typeof attributes !== 'object') { + throw new ArgumentError( + 'Attributes are expected to be an object ' + + `but got ${ + typeof attributes === 'object' + ? attributes.constructor.name + : typeof attributes + }`, + ); + } - for (const attrID of Object.keys(attributes)) { - data.updateFlags.attributes = true; - data.attributes[attrID] = attributes[attrID]; - } + for (const attrID of Object.keys(attributes)) { + data.updateFlags.attributes = true; + data.attributes[attrID] = attributes[attrID]; + } + }, }, - }, - })); + }), + ); this.label = serialized.label; this.lock = serialized.lock; @@ -360,31 +362,31 @@ const { Source } = require('./enums'); if ([Source.MANUAL, Source.AUTO].includes(serialized.source)) { data.source = serialized.source; } - if (typeof (serialized.zOrder) === 'number') { + if (typeof serialized.zOrder === 'number') { this.zOrder = serialized.zOrder; } - if (typeof (serialized.occluded) === 'boolean') { + if (typeof serialized.occluded === 'boolean') { this.occluded = serialized.occluded; } - if (typeof (serialized.outside) === 'boolean') { + if (typeof serialized.outside === 'boolean') { this.outside = serialized.outside; } - if (typeof (serialized.keyframe) === 'boolean') { + if (typeof serialized.keyframe === 'boolean') { this.keyframe = serialized.keyframe; } - if (typeof (serialized.pinned) === 'boolean') { + if (typeof serialized.pinned === 'boolean') { this.pinned = serialized.pinned; } - if (typeof (serialized.hidden) === 'boolean') { + if (typeof serialized.hidden === 'boolean') { this.hidden = serialized.hidden; } - if (typeof (serialized.color) === 'string') { + if (typeof serialized.color === 'string') { this.color = serialized.color; } if (Array.isArray(serialized.points)) { this.points = serialized.points; } - if (typeof (serialized.attributes) === 'object') { + if (typeof serialized.attributes === 'object') { this.attributes = serialized.attributes; } @@ -392,38 +394,36 @@ const { Source } = require('./enums'); } /** - * Method saves/updates an object state in a collection - * @method save - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @returns {module:API.cvat.classes.ObjectState} updated state of an object - */ + * Method saves/updates an object state in a collection + * @method save + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @returns {module:API.cvat.classes.ObjectState} updated state of an object + */ async save() { - const result = await PluginRegistry - .apiWrapper.call(this, ObjectState.prototype.save); + const result = await PluginRegistry.apiWrapper.call(this, ObjectState.prototype.save); return result; } /** - * Method deletes an object from a collection - * @method delete - * @memberof module:API.cvat.classes.ObjectState - * @readonly - * @instance - * @param {integer} frame current frame number - * @param {boolean} [force=false] delete object even if it is locked - * @async - * @returns {boolean} true if object has been deleted - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Method deletes an object from a collection + * @method delete + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + * @param {integer} frame current frame number + * @param {boolean} [force=false] delete object even if it is locked + * @async + * @returns {boolean} true if object has been deleted + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ async delete(frame, force = false) { - const result = await PluginRegistry - .apiWrapper.call(this, ObjectState.prototype.delete, frame, force); + const result = await PluginRegistry.apiWrapper.call(this, ObjectState.prototype.delete, frame, force); return result; } } diff --git a/cvat-core/src/plugins.js b/cvat-core/src/plugins.js index eea06ee4..88d4ec83 100644 --- a/cvat-core/src/plugins.js +++ b/cvat-core/src/plugins.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const { PluginError } = require('./exceptions'); @@ -16,8 +11,7 @@ // I have to optimize the wrapper const pluginList = await PluginRegistry.list(); for (const plugin of pluginList) { - const pluginDecorators = plugin.functions - .filter((obj) => obj.callback === wrappedFunc)[0]; + const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0]; if (pluginDecorators && pluginDecorators.enter) { try { await pluginDecorators.enter.call(this, plugin, ...args); @@ -34,8 +28,7 @@ let result = await wrappedFunc.implementation.call(this, ...args); for (const plugin of pluginList) { - const pluginDecorators = plugin.functions - .filter((obj) => obj.callback === wrappedFunc)[0]; + const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0]; if (pluginDecorators && pluginDecorators.leave) { try { result = await pluginDecorators.leave.call(this, plugin, result, ...args); @@ -56,15 +49,15 @@ static async register(plug) { const functions = []; - if (typeof (plug) !== 'object') { - throw new PluginError(`Plugin should be an object, but got "${typeof (plug)}"`); + if (typeof plug !== 'object') { + throw new PluginError(`Plugin should be an object, but got "${typeof plug}"`); } - if (!('name' in plug) || typeof (plug.name) !== 'string') { + if (!('name' in plug) || typeof plug.name !== 'string') { throw new PluginError('Plugin must contain a "name" field and it must be a string'); } - if (!('description' in plug) || typeof (plug.description) !== 'string') { + if (!('description' in plug) || typeof plug.description !== 'string') { throw new PluginError('Plugin must contain a "description" field and it must be a string'); } @@ -72,17 +65,19 @@ throw new PluginError('Plugin must not contain a "functions" field'); } - (function traverse(plugin, api) { + function traverse(plugin, api) { const decorator = {}; for (const key in plugin) { if (Object.prototype.hasOwnProperty.call(plugin, key)) { - if (typeof (plugin[key]) === 'object') { + if (typeof plugin[key] === 'object') { if (Object.prototype.hasOwnProperty.call(api, key)) { traverse(plugin[key], api[key]); } - } else if (['enter', 'leave'].includes(key) - && typeof (api) === 'function' - && typeof (plugin[key] === 'function')) { + } else if ( + ['enter', 'leave'].includes(key) + && typeof api === 'function' + && typeof (plugin[key] === 'function') + ) { decorator.callback = api; decorator[key] = plugin[key]; } @@ -92,9 +87,9 @@ if (Object.keys(decorator).length) { functions.push(decorator); } - }(plug, { - cvat: this, - })); + } + + traverse(plug, { cvat: this }); Object.defineProperty(plug, 'functions', { value: functions, diff --git a/cvat-core/src/project.js b/cvat-core/src/project.js new file mode 100644 index 00000000..d53d5eec --- /dev/null +++ b/cvat-core/src/project.js @@ -0,0 +1,265 @@ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +(() => { + const PluginRegistry = require('./plugins'); + const serverProxy = require('./server-proxy'); + const { ArgumentError } = require('./exceptions'); + const { Task } = require('./session'); + const { Label } = require('./labels'); + const User = require('./user'); + + /** + * Class representing a project + * @memberof module:API.cvat.classes + */ + class Project { + /** + * In a fact you need use the constructor only if you want to create a project + * @param {object} initialData - Object which is used for initalization + *
    It can contain keys: + *
  • name + *
  • labels + */ + constructor(initialData) { + const data = { + id: undefined, + name: undefined, + status: undefined, + assignee: undefined, + owner: undefined, + bug_tracker: undefined, + created_date: undefined, + updated_date: undefined, + }; + + for (const property in data) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { + data[property] = initialData[property]; + } + } + + data.labels = []; + data.tasks = []; + + if (Array.isArray(initialData.labels)) { + for (const label of initialData.labels) { + const classInstance = new Label(label); + data.labels.push(classInstance); + } + } + + if (Array.isArray(initialData.tasks)) { + for (const task of initialData.tasks) { + const taskInstance = new Task(task); + data.tasks.push(taskInstance); + } + } + + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Project + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + name: { + get: () => data.name, + set: (value) => { + if (!value.trim().length) { + throw new ArgumentError('Value must not be empty'); + } + data.name = value; + }, + }, + /** + * @name status + * @type {module:API.cvat.enums.TaskStatus} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + */ + status: { + get: () => data.status, + }, + /** + * Instance of a user who was assigned for the project + * @name assignee + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + */ + assignee: { + get: () => data.assignee, + set: (assignee) => { + if (assignee !== null && !(assignee instanceof User)) { + throw new ArgumentError('Value must be a user instance'); + } + data.assignee = assignee; + }, + }, + /** + * Instance of a user who has created the project + * @name owner + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + */ + owner: { + get: () => data.owner, + }, + /** + * @name bugTracker + * @type {string} + * @memberof module:API.cvat.classes.Project + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + bugTracker: { + get: () => data.bug_tracker, + set: (tracker) => { + data.bug_tracker = tracker; + }, + }, + /** + * @name createdDate + * @type {string} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + createdDate: { + get: () => data.created_date, + }, + /** + * @name updatedDate + * @type {string} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + updatedDate: { + get: () => data.updated_date, + }, + /** + * After project has been created value can be appended only. + * @name labels + * @type {module:API.cvat.classes.Label[]} + * @memberof module:API.cvat.classes.Project + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + labels: { + get: () => [...data.labels], + set: (labels) => { + if (!Array.isArray(labels)) { + throw new ArgumentError('Value must be an array of Labels'); + } + + if (!Array.isArray(labels) || labels.some((label) => !(label instanceof Label))) { + throw new ArgumentError( + `Each array value must be an instance of Label. ${typeof label} was found`, + ); + } + + data.labels = [...labels]; + }, + }, + /** + * Tasks linked with the project + * @name tasks + * @type {module:API.cvat.classes.Task[]} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + */ + tasks: { + get: () => [...data.tasks], + }, + }), + ); + } + + /** + * Method updates data of a created project or creates new project from scratch + * @method save + * @returns {module:API.cvat.classes.Project} + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async save() { + const result = await PluginRegistry.apiWrapper.call(this, Project.prototype.save); + return result; + } + + /** + * Method deletes a task from a server + * @method delete + * @memberof module:API.cvat.classes.Project + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async delete() { + const result = await PluginRegistry.apiWrapper.call(this, Project.prototype.delete); + return result; + } + } + + module.exports = { + Project, + }; + + Project.prototype.save.implementation = async function () { + if (typeof this.id !== 'undefined') { + const projectData = { + name: this.name, + assignee_id: this.assignee ? this.assignee.id : null, + bug_tracker: this.bugTracker, + labels: [...this.labels.map((el) => el.toJSON())], + }; + + await serverProxy.projects.save(this.id, projectData); + return this; + } + + const projectSpec = { + name: this.name, + labels: [...this.labels.map((el) => el.toJSON())], + }; + + if (this.bugTracker) { + projectSpec.bug_tracker = this.bugTracker; + } + + const project = await serverProxy.projects.create(projectSpec); + return new Project(project); + }; + + Project.prototype.delete.implementation = async function () { + const result = await serverProxy.projects.delete(this.id); + return result; + }; +})(); diff --git a/cvat-core/src/review.js b/cvat-core/src/review.js new file mode 100644 index 00000000..db9491e4 --- /dev/null +++ b/cvat-core/src/review.js @@ -0,0 +1,397 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +const store = require('store'); + +const PluginRegistry = require('./plugins'); +const Issue = require('./issue'); +const User = require('./user'); +const { ArgumentError, DataError } = require('./exceptions'); +const { ReviewStatus } = require('./enums'); +const { negativeIDGenerator } = require('./common'); +const serverProxy = require('./server-proxy'); + +/** + * Class representing a single review + * @memberof module:API.cvat.classes + * @hideconstructor + */ +class Review { + constructor(initialData) { + const data = { + id: undefined, + job: undefined, + issue_set: [], + estimated_quality: undefined, + status: undefined, + reviewer: undefined, + assignee: undefined, + reviewed_frames: undefined, + reviewed_states: undefined, + }; + + for (const property in data) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { + data[property] = initialData[property]; + } + } + + if (data.reviewer && !(data.reviewer instanceof User)) data.reviewer = new User(data.reviewer); + if (data.assignee && !(data.assignee instanceof User)) data.assignee = new User(data.assignee); + + data.reviewed_frames = Array.isArray(data.reviewed_frames) ? new Set(data.reviewed_frames) : new Set(); + data.reviewed_states = Array.isArray(data.reviewed_states) ? new Set(data.reviewed_states) : new Set(); + if (data.issue_set) { + data.issue_set = data.issue_set.map((issue) => new Issue(issue)); + } + + if (typeof data.id === 'undefined') { + data.id = negativeIDGenerator(); + } + + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + */ + id: { + get: () => data.id, + }, + /** + * An identifier of a job the review is attached to + * @name job + * @type {integer} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + */ + job: { + get: () => data.job, + }, + /** + * List of attached issues + * @name issues + * @type {number[]} + * @memberof module:API.cvat.classes.Review + * @instance + * @readonly + */ + issues: { + get: () => data.issue_set.filter((issue) => !issue.removed), + }, + /** + * Estimated quality of the review + * @name estimatedQuality + * @type {number} + * @memberof module:API.cvat.classes.Review + * @instance + * @readonly + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + estimatedQuality: { + get: () => data.estimated_quality, + set: (value) => { + if (typeof value !== 'number' || value < 0 || value > 5) { + throw new ArgumentError(`Value must be a number in range [0, 5]. Got ${value}`); + } + data.estimated_quality = value; + }, + }, + /** + * @name status + * @type {module:API.cvat.enums.ReviewStatus} + * @memberof module:API.cvat.classes.Review + * @instance + * @readonly + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + status: { + get: () => data.status, + set: (status) => { + const type = ReviewStatus; + let valueInEnum = false; + for (const value in type) { + if (type[value] === status) { + valueInEnum = true; + break; + } + } + + if (!valueInEnum) { + throw new ArgumentError( + 'Value must be a value from the enumeration cvat.enums.ReviewStatus', + ); + } + + data.status = status; + }, + }, + /** + * An instance of a user who has done the review + * @name reviewer + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + reviewer: { + get: () => data.reviewer, + set: (reviewer) => { + if (!(reviewer instanceof User)) { + throw new ArgumentError(`Reviewer must be an instance of the User class. Got ${reviewer}`); + } + + data.reviewer = reviewer; + }, + }, + /** + * An instance of a user who was assigned for annotation before the review + * @name assignee + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + */ + assignee: { + get: () => data.assignee, + }, + /** + * A set of frames that have been visited during review + * @name reviewedFrames + * @type {number[]} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + */ + reviewedFrames: { + get: () => Array.from(data.reviewed_frames), + }, + /** + * A set of reviewed states (server IDs combined with frames) + * @name reviewedFrames + * @type {string[]} + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + */ + reviewedStates: { + get: () => Array.from(data.reviewed_states), + }, + __internal: { + get: () => data, + }, + }), + ); + } + + /** + * Method appends a frame to a set of reviewed frames + * Reviewed frames are saved only in local storage + * @method reviewFrame + * @memberof module:API.cvat.classes.Review + * @param {number} frame + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async reviewFrame(frame) { + const result = await PluginRegistry.apiWrapper.call(this, Review.prototype.reviewFrame, frame); + return result; + } + + /** + * Method appends a frame to a set of reviewed frames + * Reviewed states are saved only in local storage. They are used to automatic annotations quality assessment + * @method reviewStates + * @memberof module:API.cvat.classes.Review + * @param {string[]} stateIDs + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async reviewStates(stateIDs) { + const result = await PluginRegistry.apiWrapper.call(this, Review.prototype.reviewStates, stateIDs); + return result; + } + + /** + * @typedef {Object} IssueData + * @property {number} frame + * @property {number[]} position + * @property {number} owner + * @property {CommentData[]} comment_set + * @global + */ + /** + * Method adds a new issue to the review + * @method openIssue + * @memberof module:API.cvat.classes.Review + * @param {IssueData} data + * @returns {module:API.cvat.classes.Issue} + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async openIssue(data) { + const result = await PluginRegistry.apiWrapper.call(this, Review.prototype.openIssue, data); + return result; + } + + /** + * Method submits local review to the server + * @method submit + * @memberof module:API.cvat.classes.Review + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.DataError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async submit() { + const result = await PluginRegistry.apiWrapper.call(this, Review.prototype.submit); + return result; + } + + serialize() { + const { issues, reviewedFrames, reviewedStates } = this; + const data = { + job: this.job, + issue_set: issues.map((issue) => issue.serialize()), + reviewed_frames: Array.from(reviewedFrames), + reviewed_states: Array.from(reviewedStates), + }; + + if (this.id > 0) { + data.id = this.id; + } + if (typeof this.estimatedQuality !== 'undefined') { + data.estimated_quality = this.estimatedQuality; + } + if (typeof this.status !== 'undefined') { + data.status = this.status; + } + if (this.reviewer) { + data.reviewer = this.reviewer.toJSON(); + } + if (this.assignee) { + data.reviewer = this.assignee.toJSON(); + } + + return data; + } + + toJSON() { + const data = this.serialize(); + const { + reviewer, + assignee, + reviewed_frames: reviewedFrames, + reviewed_states: reviewedStates, + ...updated + } = data; + + return { + ...updated, + issue_set: this.issues.map((issue) => issue.toJSON()), + reviewer_id: reviewer ? reviewer.id : undefined, + assignee_id: assignee ? assignee.id : undefined, + }; + } + + async toLocalStorage() { + const data = this.serialize(); + store.set(`job-${this.job}-review`, JSON.stringify(data)); + } +} + +Review.prototype.reviewFrame.implementation = function (frame) { + if (!Number.isInteger(frame)) { + throw new ArgumentError(`The argument "frame" is expected to be an integer. Got ${frame}`); + } + this.__internal.reviewed_frames.add(frame); +}; + +Review.prototype.reviewStates.implementation = function (stateIDs) { + if (!Array.isArray(stateIDs) || stateIDs.some((stateID) => typeof stateID !== 'string')) { + throw new ArgumentError(`The argument "stateIDs" is expected to be an array of string. Got ${stateIDs}`); + } + + stateIDs.forEach((stateID) => this.__internal.reviewed_states.add(stateID)); +}; + +Review.prototype.openIssue.implementation = async function (data) { + if (typeof data !== 'object' || data === null) { + throw new ArgumentError(`The argument "data" must be a not null object. Got ${data}`); + } + + if (typeof data.frame !== 'number') { + throw new ArgumentError(`Issue frame must be a number. Got ${data.frame}`); + } + + if (!(data.owner instanceof User)) { + throw new ArgumentError(`Issue owner must be a User instance. Got ${data.owner}`); + } + + if (!Array.isArray(data.position) || data.position.some((coord) => typeof coord !== 'number')) { + throw new ArgumentError(`Issue position must be an array of numbers. Got ${data.position}`); + } + + if (!Array.isArray(data.comment_set)) { + throw new ArgumentError(`Issue comment set must be an array. Got ${data.comment_set}`); + } + + const copied = { + frame: data.frame, + position: Issue.hull(data.position), + owner: data.owner, + comment_set: [], + }; + + const issue = new Issue(copied); + + for (const comment of data.comment_set) { + await issue.comment.implementation.call(issue, comment); + } + + this.__internal.issue_set.push(issue); + return issue; +}; + +Review.prototype.submit.implementation = async function () { + if (typeof this.estimatedQuality === 'undefined') { + throw new DataError('Estimated quality is expected to be a number. Got "undefined"'); + } + + if (typeof this.status === 'undefined') { + throw new DataError('Review status is expected to be a string. Got "undefined"'); + } + + if (this.id < 0) { + const data = this.toJSON(); + + const response = await serverProxy.jobs.reviews.create(data); + store.remove(`job-${this.job}-review`); + this.__internal.id = response.id; + this.__internal.issue_set = response.issue_set.map((issue) => new Issue(issue)); + this.__internal.estimated_quality = response.estimated_quality; + this.__internal.status = response.status; + + if (response.reviewer) this.__internal.reviewer = new User(response.reviewer); + if (response.assignee) this.__internal.assignee = new User(response.assignee); + } +}; + +module.exports = Review; diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js index 4a0c9ebd..7865df66 100644 --- a/cvat-core/src/server-proxy.js +++ b/cvat-core/src/server-proxy.js @@ -1,17 +1,10 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { const FormData = require('form-data'); - const { - ServerError, - } = require('./exceptions'); + const { ServerError } = require('./exceptions'); const store = require('store'); const config = require('./config'); const DownloadWorker = require('./download.worker'); @@ -38,7 +31,13 @@ if (e.data.isSuccess) { requests[e.data.id].resolve(e.data.responseData); } else { - requests[e.data.id].reject(e.data.error); + requests[e.data.id].reject({ + error: e.data.error, + response: { + status: e.data.status, + data: e.data.responseData, + }, + }); } delete requests[e.data.id]; @@ -71,12 +70,15 @@ }); } - Object.defineProperties(this, Object.freeze({ - get: { - value: get, - writable: false, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + get: { + value: get, + writable: false, + }, + }), + ); } } @@ -154,7 +156,6 @@ return response.data; } - async function userAgreements() { const { backendAPI } = config; let response = null; @@ -169,15 +170,7 @@ return response.data; } - async function register( - username, - firstName, - lastName, - email, - password1, - password2, - confirmations, - ) { + async function register(username, firstName, lastName, email, password1, password2, confirmations) { let response = null; try { const data = JSON.stringify({ @@ -203,20 +196,19 @@ } async function login(username, password) { - const authenticationData = ([ + const authenticationData = [ `${encodeURIComponent('username')}=${encodeURIComponent(username)}`, `${encodeURIComponent('password')}=${encodeURIComponent(password)}`, - ]).join('&').replace(/%20/g, '+'); + ] + .join('&') + .replace(/%20/g, '+'); Axios.defaults.headers.common.Authorization = ''; let authenticationResponse = null; try { - authenticationResponse = await Axios.post( - `${config.backendAPI}/auth/login`, - authenticationData, { - proxy: config.proxy, - }, - ); + authenticationResponse = await Axios.post(`${config.backendAPI}/auth/login`, authenticationData, { + proxy: config.proxy, + }); } catch (errorData) { throw generateError(errorData); } @@ -251,7 +243,7 @@ const data = JSON.stringify({ old_password: oldPassword, new_password1: newPassword1, - new_password2:newPassword2, + new_password2: newPassword2, }); await Axios.post(`${config.backendAPI}/auth/password/change`, data, { proxy: config.proxy, @@ -264,9 +256,44 @@ } } + async function requestPasswordReset(email) { + try { + const data = JSON.stringify({ + email, + }); + await Axios.post(`${config.backendAPI}/auth/password/reset`, data, { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + } + + async function resetPassword(newPassword1, newPassword2, uid, _token) { + try { + const data = JSON.stringify({ + new_password1: newPassword1, + new_password2: newPassword2, + uid, + token: _token, + }); + await Axios.post(`${config.backendAPI}/auth/password/reset/confirm`, data, { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + } + async function authorized() { try { - await module.exports.users.getSelf(); + await module.exports.users.self(); } catch (serverError) { if (serverError.code === 401) { return false; @@ -280,10 +307,88 @@ async function serverRequest(url, data) { try { - return (await Axios({ - url, - ...data, - })).data; + return ( + await Axios({ + url, + ...data, + }) + ).data; + } catch (errorData) { + throw generateError(errorData); + } + } + + async function searchProjectNames(search, limit) { + const { backendAPI, proxy } = config; + + let response = null; + try { + response = await Axios.get( + `${backendAPI}/projects?names_only=true&page=1&page_size=${limit}&search=${search}`, + { + proxy, + }, + ); + } catch (errorData) { + throw generateError(errorData); + } + + response.data.results.count = response.data.count; + return response.data.results; + } + + async function getProjects(filter = '') { + const { backendAPI, proxy } = config; + + let response = null; + try { + response = await Axios.get(`${backendAPI}/projects?page_size=12&${filter}`, { + proxy, + }); + } catch (errorData) { + throw generateError(errorData); + } + + response.data.results.count = response.data.count; + return response.data.results; + } + + async function saveProject(id, projectData) { + const { backendAPI } = config; + + try { + await Axios.patch(`${backendAPI}/projects/${id}`, JSON.stringify(projectData), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + } + + async function deleteProject(id) { + const { backendAPI } = config; + + try { + await Axios.delete(`${backendAPI}/projects/${id}`); + } catch (errorData) { + throw generateError(errorData); + } + } + + async function createProject(projectSpec) { + const { backendAPI } = config; + + try { + const response = await Axios.post(`${backendAPI}/projects`, JSON.stringify(projectSpec), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + return response.data; } catch (errorData) { throw generateError(errorData); } @@ -324,7 +429,12 @@ const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/tasks/${id}`); + await Axios.delete(`${backendAPI}/tasks/${id}`, { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); } catch (errorData) { throw generateError(errorData); } @@ -337,10 +447,9 @@ return new Promise((resolve, reject) => { async function request() { try { - const response = await Axios - .get(`${url}`, { - proxy: config.proxy, - }); + const response = await Axios.get(`${url}`, { + proxy: config.proxy, + }); if (response.status === 202) { setTimeout(request, 3000); } else { @@ -374,21 +483,22 @@ } else if (response.data.state === 'Failed') { // If request has been successful, but task hasn't been created // Then passed data is wrong and we can pass code 400 - const message = 'Could not create the task on the server. ' - + `${response.data.message}.`; + const message = ` + Could not create the task on the server. ${response.data.message}. + `; reject(new ServerError(message, 400)); } else { // If server has another status, it is unexpected // Therefore it is server error and we can pass code 500 - reject(new ServerError( - `Unknown task state has been received: ${response.data.state}`, - 500, - )); + reject( + new ServerError( + `Unknown task state has been received: ${response.data.state}`, + 500, + ), + ); } } catch (errorData) { - reject( - generateError(errorData), - ); + reject(generateError(errorData)); } } @@ -421,7 +531,7 @@ throw generateError(errorData); } - onUpdate('The data is being uploaded to the server..'); + onUpdate('The data are being uploaded to the server..'); try { await Axios.post(`${backendAPI}/tasks/${response.data.id}/data`, taskData, { proxy: config.proxy, @@ -462,6 +572,90 @@ return response.data; } + async function getJobReviews(jobID) { + const { backendAPI } = config; + + let response = null; + try { + response = await Axios.get(`${backendAPI}/jobs/${jobID}/reviews`, { + proxy: config.proxy, + }); + } catch (errorData) { + throw generateError(errorData); + } + + return response.data; + } + + async function createReview(data) { + const { backendAPI } = config; + + let response = null; + try { + response = await Axios.post(`${backendAPI}/reviews`, JSON.stringify(data), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + + return response.data; + } + + async function getJobIssues(jobID) { + const { backendAPI } = config; + + let response = null; + try { + response = await Axios.get(`${backendAPI}/jobs/${jobID}/issues`, { + proxy: config.proxy, + }); + } catch (errorData) { + throw generateError(errorData); + } + + return response.data; + } + + async function createComment(data) { + const { backendAPI } = config; + + let response = null; + try { + response = await Axios.post(`${backendAPI}/comments`, JSON.stringify(data), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + + return response.data; + } + + async function updateIssue(issueID, data) { + const { backendAPI } = config; + + let response = null; + try { + response = await Axios.patch(`${backendAPI}/issues/${issueID}`, JSON.stringify(data), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (errorData) { + throw generateError(errorData); + } + + return response.data; + } + async function saveJob(id, jobData) { const { backendAPI } = config; @@ -477,20 +671,14 @@ } } - async function getUsers(id = null) { + async function getUsers(filter = 'page_size=all') { const { backendAPI } = config; let response = null; try { - if (id === null) { - response = await Axios.get(`${backendAPI}/users?page_size=all`, { - proxy: config.proxy, - }); - } else { - response = await Axios.get(`${backendAPI}/users/${id}`, { - proxy: config.proxy, - }); - } + response = await Axios.get(`${backendAPI}/users?${filter}`, { + proxy: config.proxy, + }); } catch (errorData) { throw generateError(errorData); } @@ -524,10 +712,7 @@ }); } catch (errorData) { const code = errorData.response ? errorData.response.status : errorData.code; - throw new ServerError( - `Could not get preview frame for the task ${tid} from the server`, - code, - ); + throw new ServerError(`Could not get preview frame for the task ${tid} from the server`, code); } return response.data; @@ -546,7 +731,14 @@ }, ); } catch (errorData) { - throw generateError(errorData); + throw generateError({ + ...errorData, + message: '', + response: { + ...errorData.response, + data: String.fromCharCode.apply(null, new Uint8Array(errorData.response.data)), + }, + }); } return response; @@ -621,10 +813,13 @@ return new Promise((resolve, reject) => { async function request() { try { - const response = await Axios - .put(`${backendAPI}/${session}s/${id}/annotations?format=${format}`, annotationData, { + const response = await Axios.put( + `${backendAPI}/${session}s/${id}/annotations?format=${format}`, + annotationData, + { proxy: config.proxy, - }); + }, + ); if (response.status === 202) { annotationData = new FormData(); setTimeout(request, 3000); @@ -655,17 +850,19 @@ async function request() { Axios.get(`${url}`, { proxy: config.proxy, - }).then((response) => { - if (response.status === 202) { - setTimeout(request, 3000); - } else { - query = `${query}&action=download`; - url = `${baseURL}?${query}`; - resolve(url); - } - }).catch((errorData) => { - reject(generateError(errorData)); - }); + }) + .then((response) => { + if (response.status === 202) { + setTimeout(request, 3000); + } else { + query = `${query}&action=download`; + url = `${baseURL}?${query}`; + resolve(url); + } + }) + .catch((errorData) => { + reject(generateError(errorData)); + }); } setTimeout(request); @@ -704,13 +901,12 @@ const { backendAPI } = config; try { - const response = await Axios.post(`${backendAPI}/lambda/requests`, - JSON.stringify(body), { - proxy: config.proxy, - headers: { - 'Content-Type': 'application/json', - }, - }); + const response = await Axios.post(`${backendAPI}/lambda/requests`, JSON.stringify(body), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); return response.data; } catch (errorData) { @@ -722,13 +918,12 @@ const { backendAPI } = config; try { - const response = await Axios.post(`${backendAPI}/lambda/functions/${funId}`, - JSON.stringify(body), { - proxy: config.proxy, - headers: { - 'Content-Type': 'application/json', - }, - }); + const response = await Axios.post(`${backendAPI}/lambda/functions/${funId}`, JSON.stringify(body), { + proxy: config.proxy, + headers: { + 'Content-Type': 'application/json', + }, + }); return response.data; } catch (errorData) { @@ -767,99 +962,145 @@ const { backendAPI } = config; try { - await Axios.delete( - `${backendAPI}/lambda/requests/${requestId}`, { - method: 'DELETE', - }, - ); + await Axios.delete(`${backendAPI}/lambda/requests/${requestId}`, { + method: 'DELETE', + }); + } catch (errorData) { + throw generateError(errorData); + } + } + + async function installedApps() { + const { backendAPI } = config; + try { + const response = await Axios.get(`${backendAPI}/server/plugins`, { + proxy: config.proxy, + }); + return response.data; } catch (errorData) { throw generateError(errorData); } } - Object.defineProperties(this, Object.freeze({ - server: { - value: Object.freeze({ - about, - share, - formats, - exception, - login, - logout, - changePassword, - authorized, - register, - request: serverRequest, - userAgreements, - }), - writable: false, - }, - - tasks: { - value: Object.freeze({ - getTasks, - saveTask, - createTask, - deleteTask, - exportDataset, - }), - writable: false, - }, - - jobs: { - value: Object.freeze({ - getJob, - saveJob, - }), - writable: false, - }, - - users: { - value: Object.freeze({ - getUsers, - getSelf, - }), - writable: false, - }, - - frames: { - value: Object.freeze({ - getData, - getMeta, - getPreview, - }), - writable: false, - }, - - annotations: { - value: Object.freeze({ - updateAnnotations, - getAnnotations, - dumpAnnotations, - uploadAnnotations, - }), - writable: false, - }, - - logs: { - value: Object.freeze({ - save: saveLogs, - }), - writable: false, - }, - - lambda: { - value: Object.freeze({ - list: getLambdaFunctions, - status: getRequestStatus, - requests: getLambdaRequests, - run: runLambdaRequest, - call: callLambdaFunction, - cancel: cancelLambdaRequest, - }), - writable: false, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + server: { + value: Object.freeze({ + about, + share, + formats, + exception, + login, + logout, + changePassword, + requestPasswordReset, + resetPassword, + authorized, + register, + request: serverRequest, + userAgreements, + installedApps, + }), + writable: false, + }, + + projects: { + value: Object.freeze({ + get: getProjects, + searchNames: searchProjectNames, + save: saveProject, + create: createProject, + delete: deleteProject, + }), + writable: false, + }, + + tasks: { + value: Object.freeze({ + getTasks, + saveTask, + createTask, + deleteTask, + exportDataset, + }), + writable: false, + }, + + jobs: { + value: Object.freeze({ + get: getJob, + save: saveJob, + issues: getJobIssues, + reviews: { + get: getJobReviews, + create: createReview, + }, + }), + writable: false, + }, + + users: { + value: Object.freeze({ + get: getUsers, + self: getSelf, + }), + writable: false, + }, + + frames: { + value: Object.freeze({ + getData, + getMeta, + getPreview, + }), + writable: false, + }, + + annotations: { + value: Object.freeze({ + updateAnnotations, + getAnnotations, + dumpAnnotations, + uploadAnnotations, + }), + writable: false, + }, + + logs: { + value: Object.freeze({ + save: saveLogs, + }), + writable: false, + }, + + lambda: { + value: Object.freeze({ + list: getLambdaFunctions, + status: getRequestStatus, + requests: getLambdaRequests, + run: runLambdaRequest, + call: callLambdaFunction, + cancel: cancelLambdaRequest, + }), + writable: false, + }, + + issues: { + value: Object.freeze({ + update: updateIssue, + }), + writable: false, + }, + + comments: { + value: Object.freeze({ + create: createComment, + }), + writable: false, + }, + }), + ); } } diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js index 6a994e0a..19bc32df 100644 --- a/cvat-core/src/session.js +++ b/cvat-core/src/session.js @@ -1,128 +1,163 @@ -/* -* Copyright (C) 2019-2020 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:false -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { + const store = require('store'); const PluginRegistry = require('./plugins'); const loggerStorage = require('./logger-storage'); const serverProxy = require('./server-proxy'); const { - getFrame, - getRanges, - getPreview, - clear: clearFrames, + getFrame, getRanges, getPreview, clear: clearFrames, } = require('./frames'); const { ArgumentError } = require('./exceptions'); const { TaskStatus } = require('./enums'); const { Label } = require('./labels'); const User = require('./user'); + const Issue = require('./issue'); + const Review = require('./review'); function buildDublicatedAPI(prototype) { Object.defineProperties(prototype, { annotations: Object.freeze({ value: { async upload(file, loader) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.upload, file, loader); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.upload, + file, + loader, + ); return result; }, async save(onUpdate) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.save, onUpdate); + const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.save, onUpdate); return result; }, async clear(reload = false) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.clear, reload); + const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.clear, reload); return result; }, async dump(dumper, name = null) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.dump, dumper, name); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.dump, + dumper, + name, + ); return result; }, async statistics() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.statistics); + const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.statistics); return result; }, async put(arrayOfObjects = []) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.put, arrayOfObjects); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.put, + arrayOfObjects, + ); return result; }, async get(frame, allTracks = false, filters = []) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.get, - frame, allTracks, filters); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.get, + frame, + allTracks, + filters, + ); return result; }, async search(filters, frameFrom, frameTo) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.search, - filters, frameFrom, frameTo); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.search, + filters, + frameFrom, + frameTo, + ); + return result; + }, + + async searchEmpty(frameFrom, frameTo) { + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.searchEmpty, + frameFrom, + frameTo, + ); return result; }, async select(objectStates, x, y) { - const result = await PluginRegistry - .apiWrapper.call(this, - prototype.annotations.select, objectStates, x, y); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.select, + objectStates, + x, + y, + ); return result; }, async merge(objectStates) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.merge, objectStates); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.merge, + objectStates, + ); return result; }, async split(objectState, frame) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.split, objectState, frame); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.split, + objectState, + frame, + ); return result; }, async group(objectStates, reset = false) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.group, - objectStates, reset); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.group, + objectStates, + reset, + ); return result; }, async import(data) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.import, data); + const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.import, data); return result; }, async export() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.export); + const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.export); return result; }, async exportDataset(format) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.annotations.exportDataset, format); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.annotations.exportDataset, + format, + ); return result; }, hasUnsavedChanges() { - const result = prototype.annotations - .hasUnsavedChanges.implementation.call(this); + const result = prototype.annotations.hasUnsavedChanges.implementation.call(this); return result; }, }, @@ -131,18 +166,21 @@ frames: Object.freeze({ value: { async get(frame, isPlaying = false, step = 1) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.frames.get, frame, isPlaying, step); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.frames.get, + frame, + isPlaying, + step, + ); return result; }, async ranges() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.frames.ranges); + const result = await PluginRegistry.apiWrapper.call(this, prototype.frames.ranges); return result; }, async preview() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.frames.preview); + const result = await PluginRegistry.apiWrapper.call(this, prototype.frames.preview); return result; }, }, @@ -151,8 +189,13 @@ logger: Object.freeze({ value: { async log(logType, payload = {}, wait = false) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.logger.log, logType, payload, wait); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.logger.log, + logType, + payload, + wait, + ); return result; }, }, @@ -161,23 +204,23 @@ actions: Object.freeze({ value: { async undo(count = 1) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.actions.undo, count); + const result = await PluginRegistry.apiWrapper.call(this, prototype.actions.undo, count); return result; }, async redo(count = 1) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.actions.redo, count); + const result = await PluginRegistry.apiWrapper.call(this, prototype.actions.redo, count); + return result; + }, + async freeze(frozen) { + const result = await PluginRegistry.apiWrapper.call(this, prototype.actions.freeze, frozen); return result; }, async clear() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.actions.clear); + const result = await PluginRegistry.apiWrapper.call(this, prototype.actions.clear); return result; }, async get() { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.actions.get); + const result = await PluginRegistry.apiWrapper.call(this, prototype.actions.get); return result; }, }, @@ -186,13 +229,21 @@ events: Object.freeze({ value: { async subscribe(evType, callback) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.events.subscribe, evType, callback); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.events.subscribe, + evType, + callback, + ); return result; }, async unsubscribe(evType, callback = null) { - const result = await PluginRegistry - .apiWrapper.call(this, prototype.events.unsubscribe, evType, callback); + const result = await PluginRegistry.apiWrapper.call( + this, + prototype.events.unsubscribe, + evType, + callback, + ); return result; }, }, @@ -202,420 +253,437 @@ } /** - * Base abstract class for Task and Job. It contains common members. - * @hideconstructor - * @virtual - */ + * Base abstract class for Task and Job. It contains common members. + * @hideconstructor + * @virtual + */ class Session { constructor() { /** - * An interaction with annotations - * @namespace annotations - * @memberof Session - */ + * An interaction with annotations + * @namespace annotations + * @memberof Session + */ /** - * Upload annotations from a dump file - * You need upload annotations from a server again after successful executing - * @method upload - * @memberof Session.annotations - * @param {File} annotations - a file with annotations - * @param {module:API.cvat.classes.Loader} loader - a loader - * which will be used to upload - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ + * Upload annotations from a dump file + * You need upload annotations from a server again after successful executing + * @method upload + * @memberof Session.annotations + * @param {File} annotations - a file with annotations + * @param {module:API.cvat.classes.Loader} loader - a loader + * which will be used to upload + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ /** - * Save all changes in annotations on a server - * Objects which hadn't been saved on a server before, - * get a serverID after saving. But received object states aren't updated. - * So, after successful saving it's recommended to update them manually - * (call the annotations.get() again) - * @method save - * @memberof Session.annotations - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @instance - * @async - * @param {function} [onUpdate] saving can be long. - * This callback can be used to notify a user about current progress - * Its argument is a text string - */ + * Save all changes in annotations on a server + * Objects which hadn't been saved on a server before, + * get a serverID after saving. But received object states aren't updated. + * So, after successful saving it's recommended to update them manually + * (call the annotations.get() again) + * @method save + * @memberof Session.annotations + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @instance + * @async + * @param {function} [onUpdate] saving can be long. + * This callback can be used to notify a user about current progress + * Its argument is a text string + */ /** - * Remove all annotations and optionally reinitialize it - * @method clear - * @memberof Session.annotations - * @param {boolean} [reload = false] reset all changes and - * reinitialize annotations by data from a server - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @throws {module:API.cvat.exceptions.ServerError} - * @instance - * @async - */ + * Remove all annotations and optionally reinitialize it + * @method clear + * @memberof Session.annotations + * @param {boolean} [reload = false] reset all changes and + * reinitialize annotations by data from a server + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.ServerError} + * @instance + * @async + */ /** - * Dump of annotations to a file. - * Method always dumps annotations for a whole task. - * @method dump - * @memberof Session.annotations - * @param {module:API.cvat.classes.Dumper} dumper - a dumper - * @param {string} [name = null] - a name of a file with annotations - * which will be used to dump - * @returns {string} URL which can be used in order to get a dump file - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Dump of annotations to a file. + * Method always dumps annotations for a whole task. + * @method dump + * @memberof Session.annotations + * @param {module:API.cvat.classes.Dumper} dumper - a dumper + * @param {string} [name = null] - a name of a file with annotations + * which will be used to dump + * @returns {string} URL which can be used in order to get a dump file + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Collect short statistics about a task or a job. - * @method statistics - * @memberof Session.annotations - * @returns {module:API.cvat.classes.Statistics} statistics object - * @throws {module:API.cvat.exceptions.PluginError} - * @instance - * @async - */ + * Collect short statistics about a task or a job. + * @method statistics + * @memberof Session.annotations + * @returns {module:API.cvat.classes.Statistics} statistics object + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + * @async + */ /** - * Create new objects from one-frame states - * After successful adding you need to update object states on a frame - * @method put - * @memberof Session.annotations - * @param {module:API.cvat.classes.ObjectState[]} data - * @returns {number[]} identificators of added objects - * array of objects on the specific frame - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.DataError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Create new objects from one-frame states + * After successful adding you need to update object states on a frame + * @method put + * @memberof Session.annotations + * @param {module:API.cvat.classes.ObjectState[]} data + * @returns {number[]} identificators of added objects + * array of objects on the specific frame + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.DataError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Get annotations for a specific frame - *
    Filter supports following operators: - * ==, !=, >, >=, <, <=, ~= and (), |, & for grouping. - *
    Filter supports properties: - * width, height, label, serverID, clientID, type, shape, occluded - *
    All prop values are case-sensitive. CVAT uses json queries for search. - *
    Examples: - *
      - *
    • label=="car" | label==["road sign"]
    • - *
    • width >= height
    • - *
    • attr["Attribute 1"] == attr["Attribute 2"]
    • - *
    • type=="track" & shape="rectangle"
    • - *
    • clientID == 50
    • - *
    • (label=="car" & attr["parked"]==true) - * | (label=="pedestrian" & width > 150)
    • - *
    • (( label==["car \"mazda\""]) & - * (attr["sunglass ( help ) es"]==true | - * (width > 150 | height > 150 & (clientID == serverID)))))
    • - *
    - * If you have double quotes in your query string, - * please escape them using back slash: \" - * @method get - * @param {integer} frame get objects from the frame - * @param {boolean} allTracks show all tracks - * even if they are outside and not keyframe - * @param {string[]} [filters = []] - * get only objects that satisfied to specific filters - * @returns {module:API.cvat.classes.ObjectState[]} - * @memberof Session.annotations - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Get annotations for a specific frame + *
    Filter supports following operators: + * ==, !=, >, >=, <, <=, ~= and (), |, & for grouping. + *
    Filter supports properties: + * width, height, label, serverID, clientID, type, shape, occluded + *
    All prop values are case-sensitive. CVAT uses json queries for search. + *
    Examples: + *
      + *
    • label=="car" | label==["road sign"]
    • + *
    • width >= height
    • + *
    • attr["Attribute 1"] == attr["Attribute 2"]
    • + *
    • type=="track" & shape="rectangle"
    • + *
    • clientID == 50
    • + *
    • (label=="car" & attr["parked"]==true) + * | (label=="pedestrian" & width > 150)
    • + *
    • (( label==["car \"mazda\""]) & + * (attr["sunglass ( help ) es"]==true | + * (width > 150 | height > 150 & (clientID == serverID)))))
    • + *
    + * If you have double quotes in your query string, + * please escape them using back slash: \" + * @method get + * @param {integer} frame get objects from the frame + * @param {boolean} allTracks show all tracks + * even if they are outside and not keyframe + * @param {string[]} [filters = []] + * get only objects that satisfied to specific filters + * @returns {module:API.cvat.classes.ObjectState[]} + * @memberof Session.annotations + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Find a frame in the range [from, to] - * that contains at least one object satisfied to a filter - * @method search - * @memberof Session.annotations - * @param {ObjectFilter} [filter = []] filter - * @param {integer} from lower bound of a search - * @param {integer} to upper bound of a search - * @returns {integer|null} a frame that contains objects according to the filter - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Find a frame in the range [from, to] + * that contains at least one object satisfied to a filter + * @method search + * @memberof Session.annotations + * @param {ObjectFilter} [filter = []] filter + * @param {integer} from lower bound of a search + * @param {integer} to upper bound of a search + * @returns {integer|null} a frame that contains objects according to the filter + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Select shape under a cursor by using minimal distance - * between a cursor and a shape edge or a shape point - * For closed shapes a cursor is placed inside a shape - * @method select - * @memberof Session.annotations - * @param {module:API.cvat.classes.ObjectState[]} objectStates - * objects which can be selected - * @param {float} x horizontal coordinate - * @param {float} y vertical coordinate - * @returns {Object} - * a pair of {state: ObjectState, distance: number} for selected object. - * Pair values can be null if there aren't any sutisfied objects - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Find the nearest empty frame without any annotations + * @method searchEmpty + * @memberof Session.annotations + * @param {integer} from lower bound of a search + * @param {integer} to upper bound of a search + * @returns {integer|null} a frame that contains objects according to the filter + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Method unites several shapes and tracks into the one - * All shapes must be the same (rectangle, polygon, etc) - * All labels must be the same - * After successful merge you need to update object states on a frame - * @method merge - * @memberof Session.annotations - * @param {module:API.cvat.classes.ObjectState[]} objectStates - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Select shape under a cursor by using minimal distance + * between a cursor and a shape edge or a shape point + * For closed shapes a cursor is placed inside a shape + * @method select + * @memberof Session.annotations + * @param {module:API.cvat.classes.ObjectState[]} objectStates + * objects which can be selected + * @param {float} x horizontal coordinate + * @param {float} y vertical coordinate + * @returns {Object} + * a pair of {state: ObjectState, distance: number} for selected object. + * Pair values can be null if there aren't any sutisfied objects + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Method splits a track into two parts - * (start frame: previous frame), (frame, last frame) - * After successful split you need to update object states on a frame - * @method split - * @memberof Session.annotations - * @param {module:API.cvat.classes.ObjectState} objectState - * @param {integer} frame - * @throws {module:API.cvat.exceptions.ArgumentError} - * @throws {module:API.cvat.exceptions.PluginError} - * @instance - * @async - */ + * Method unites several shapes and tracks into the one + * All shapes must be the same (rectangle, polygon, etc) + * All labels must be the same + * After successful merge you need to update object states on a frame + * @method merge + * @memberof Session.annotations + * @param {module:API.cvat.classes.ObjectState[]} objectStates + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Method creates a new group and put all passed objects into it - * After successful split you need to update object states on a frame - * @method group - * @memberof Session.annotations - * @param {module:API.cvat.classes.ObjectState[]} objectStates - * @param {boolean} reset pass "true" to reset group value (set it to 0) - * @returns {integer} an ID of created group - * @throws {module:API.cvat.exceptions.ArgumentError} - * @throws {module:API.cvat.exceptions.PluginError} - * @instance - * @async - */ + * Method splits a track into two parts + * (start frame: previous frame), (frame, last frame) + * After successful split you need to update object states on a frame + * @method split + * @memberof Session.annotations + * @param {module:API.cvat.classes.ObjectState} objectState + * @param {integer} frame + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + * @async + */ /** - * Method indicates if there are any changes in - * annotations which haven't been saved on a server - *
    This function cannot be wrapped with a plugin - * @method hasUnsavedChanges - * @memberof Session.annotations - * @returns {boolean} - * @throws {module:API.cvat.exceptions.PluginError} - * @instance - */ + * Method creates a new group and put all passed objects into it + * After successful split you need to update object states on a frame + * @method group + * @memberof Session.annotations + * @param {module:API.cvat.classes.ObjectState[]} objectStates + * @param {boolean} reset pass "true" to reset group value (set it to 0) + * @returns {integer} an ID of created group + * @throws {module:API.cvat.exceptions.ArgumentError} + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + * @async + */ /** - * - * Import raw data in a collection - * @method import - * @memberof Session.annotations - * @param {Object} data - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Method indicates if there are any changes in + * annotations which haven't been saved on a server + *
    This function cannot be wrapped with a plugin + * @method hasUnsavedChanges + * @memberof Session.annotations + * @returns {boolean} + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + */ /** - * - * Export a collection as a row data - * @method export - * @memberof Session.annotations - * @returns {Object} data - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * + * Import raw data in a collection + * @method import + * @memberof Session.annotations + * @param {Object} data + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Export as a dataset. - * Method builds a dataset in the specified format. - * @method exportDataset - * @memberof Session.annotations - * @param {module:String} format - a format - * @returns {string} An URL to the dataset file - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ - - + * + * Export a collection as a row data + * @method export + * @memberof Session.annotations + * @returns {Object} data + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Namespace is used for an interaction with frames - * @namespace frames - * @memberof Session - */ + * Export as a dataset. + * Method builds a dataset in the specified format. + * @method exportDataset + * @memberof Session.annotations + * @param {module:String} format - a format + * @returns {string} An URL to the dataset file + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Get frame by its number - * @method get - * @memberof Session.frames - * @param {integer} frame number of frame which you want to get - * @returns {module:API.cvat.classes.FrameData} - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.DataError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - + * Namespace is used for an interaction with frames + * @namespace frames + * @memberof Session + */ /** - * Get the first frame of a task for preview - * @method preview - * @memberof Session.frames - * @returns {string} - jpeg encoded image - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - + * Get frame by its number + * @method get + * @memberof Session.frames + * @param {integer} frame number of frame which you want to get + * @returns {module:API.cvat.classes.FrameData} + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.DataError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ /** - * Returns the ranges of cached frames - * @method ranges - * @memberof Session.frames - * @returns {Array.} - * @instance - * @async - */ - + * Get the first frame of a task for preview + * @method preview + * @memberof Session.frames + * @returns {string} - jpeg encoded image + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ /** - * Namespace is used for an interaction with logs - * @namespace logger - * @memberof Session - */ - + * Returns the ranges of cached frames + * @method ranges + * @memberof Session.frames + * @returns {Array.} + * @instance + * @async + */ /** - * Create a log and add it to a log collection
    - * Durable logs will be added after "close" method is called for them
    - * The fields "task_id" and "job_id" automatically added when add logs - * throught a task or a job
    - * Ignore rules exist for some logs (e.g. zoomImage, changeAttribute)
    - * Payload of ignored logs are shallowly combined to previous logs of the same type - * @method log - * @memberof Session.logger - * @param {module:API.cvat.enums.LogType | string} type - log type - * @param {Object} [payload = {}] - any other data that will be appended to the log - * @param {boolean} [wait = false] - specifies if log is durable - * @returns {module:API.cvat.classes.Log} - * @instance - * @async - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - + * Namespace is used for an interaction with logs + * @namespace logger + * @memberof Session + */ /** - * Namespace is used for an interaction with actions - * @namespace actions - * @memberof Session - */ - + * Create a log and add it to a log collection
    + * Durable logs will be added after "close" method is called for them
    + * The fields "task_id" and "job_id" automatically added when add logs + * throught a task or a job
    + * Ignore rules exist for some logs (e.g. zoomImage, changeAttribute)
    + * Payload of ignored logs are shallowly combined to previous logs of the same type + * @method log + * @memberof Session.logger + * @param {module:API.cvat.enums.LogType | string} type - log type + * @param {Object} [payload = {}] - any other data that will be appended to the log + * @param {boolean} [wait = false] - specifies if log is durable + * @returns {module:API.cvat.classes.Log} + * @instance + * @async + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + */ /** - * @typedef {Object} HistoryActions - * @property {string[]} [undo] - array of possible actions to undo - * @property {string[]} [redo] - array of possible actions to redo - * @global - */ + * Namespace is used for an interaction with actions + * @namespace actions + * @memberof Session + */ /** - * Make undo - * @method undo - * @memberof Session.actions - * @param {number} [count=1] number of actions to undo - * @returns {number[]} Array of affected objects - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * @typedef {Object} HistoryActions + * @property {string[]} [undo] - array of possible actions to undo + * @property {string[]} [redo] - array of possible actions to redo + * @global + */ /** - * Make redo - * @method redo - * @memberof Session.actions - * @param {number} [count=1] number of actions to redo - * @returns {number[]} Array of affected objects - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Make undo + * @method undo + * @memberof Session.actions + * @param {number} [count=1] number of actions to undo + * @returns {number[]} Array of affected objects + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Remove all actions from history - * @method clear - * @memberof Session.actions - * @throws {module:API.cvat.exceptions.PluginError} - * @instance - * @async - */ + * Make redo + * @method redo + * @memberof Session.actions + * @param {number} [count=1] number of actions to redo + * @returns {number[]} Array of affected objects + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ /** - * Get actions - * @method get - * @memberof Session.actions - * @returns {HistoryActions} - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @returns {Array.>} - * array of pairs [action name, frame number] - * @instance - * @async - */ - - + * Freeze history (do not save new actions) + * @method freeze + * @memberof Session.actions + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + * @async + */ + /** + * Remove all actions from history + * @method clear + * @memberof Session.actions + * @throws {module:API.cvat.exceptions.PluginError} + * @instance + * @async + */ /** - * Namespace is used for an interaction with events - * @namespace events - * @memberof Session - */ + * Get actions + * @method get + * @memberof Session.actions + * @returns {HistoryActions} + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @returns {Array.>} + * array of pairs [action name, frame number] + * @instance + * @async + */ /** - * Subscribe on an event - * @method subscribe - * @memberof Session.events - * @param {module:API.cvat.enums.EventType} type - event type - * @param {functions} callback - function which will be called on event - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Namespace is used for an interaction with events + * @namespace events + * @memberof Session + */ /** - * Unsubscribe from an event. If callback is not provided, - * all callbacks will be removed from subscribers for the event - * @method unsubscribe - * @memberof Session.events - * @param {module:API.cvat.enums.EventType} type - event type - * @param {functions} [callback = null] - function which is called on event - * @throws {module:API.cvat.exceptions.PluginError} - * @throws {module:API.cvat.exceptions.ArgumentError} - * @instance - * @async - */ + * Subscribe on an event + * @method subscribe + * @memberof Session.events + * @param {module:API.cvat.enums.EventType} type - event type + * @param {functions} callback - function which will be called on event + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ + /** + * Unsubscribe from an event. If callback is not provided, + * all callbacks will be removed from subscribers for the event + * @method unsubscribe + * @memberof Session.events + * @param {module:API.cvat.enums.EventType} type - event type + * @param {functions} [callback = null] - function which is called on event + * @throws {module:API.cvat.exceptions.PluginError} + * @throws {module:API.cvat.exceptions.ArgumentError} + * @instance + * @async + */ } } /** - * Class representing a job. - * @memberof module:API.cvat.classes - * @hideconstructor - * @extends Session - */ + * Class representing a job. + * @memberof module:API.cvat.classes + * @hideconstructor + * @extends Session + */ class Job extends Session { constructor(initialData) { super(); const data = { id: undefined, - assignee: undefined, + assignee: null, + reviewer: null, status: undefined, start_frame: undefined, stop_frame: undefined, task: undefined, }; + let updatedFields = { + assignee: false, + reviewer: false, + status: false, + }; + for (const property in data) { if (Object.prototype.hasOwnProperty.call(data, property)) { if (property in initialData) { @@ -623,102 +691,130 @@ } if (data[property] === undefined) { - throw new ArgumentError( - `Job field "${property}" was not initialized`, - ); + throw new ArgumentError(`Job field "${property}" was not initialized`); } } } - Object.defineProperties(this, Object.freeze({ - /** - * @name id - * @type {integer} - * @memberof module:API.cvat.classes.Job - * @readonly - * @instance - */ - id: { - get: () => data.id, - }, - /** - * Instance of a user who is responsible for the job - * @name assignee - * @type {module:API.cvat.classes.User} - * @memberof module:API.cvat.classes.Job - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - assignee: { - get: () => data.assignee, - set: (assignee) => { - if (assignee !== null && !(assignee instanceof User)) { - throw new ArgumentError( - 'Value must be a user instance', - ); - } - data.assignee = assignee; + if (data.assignee) data.assignee = new User(data.assignee); + if (data.reviewer) data.reviewer = new User(data.reviewer); + + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + */ + id: { + get: () => data.id, }, - }, - /** - * @name status - * @type {module:API.cvat.enums.TaskStatus} - * @memberof module:API.cvat.classes.Job - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - status: { - get: () => data.status, - set: (status) => { - const type = TaskStatus; - let valueInEnum = false; - for (const value in type) { - if (type[value] === status) { - valueInEnum = true; - break; + /** + * Instance of a user who is responsible for the job annotations + * @name assignee + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Job + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + assignee: { + get: () => data.assignee, + set: (assignee) => { + if (assignee !== null && !(assignee instanceof User)) { + throw new ArgumentError('Value must be a user instance'); + } + updatedFields.assignee = true; + data.assignee = assignee; + }, + }, + /** + * Instance of a user who is responsible for review + * @name reviewer + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Job + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + reviewer: { + get: () => data.reviewer, + set: (reviewer) => { + if (reviewer !== null && !(reviewer instanceof User)) { + throw new ArgumentError('Value must be a user instance'); + } + updatedFields.reviewer = true; + data.reviewer = reviewer; + }, + }, + /** + * @name status + * @type {module:API.cvat.enums.TaskStatus} + * @memberof module:API.cvat.classes.Job + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + status: { + get: () => data.status, + set: (status) => { + const type = TaskStatus; + let valueInEnum = false; + for (const value in type) { + if (type[value] === status) { + valueInEnum = true; + break; + } } - } - if (!valueInEnum) { - throw new ArgumentError( - 'Value must be a value from the enumeration cvat.enums.TaskStatus', - ); - } + if (!valueInEnum) { + throw new ArgumentError( + 'Value must be a value from the enumeration cvat.enums.TaskStatus', + ); + } - data.status = status; + updatedFields.status = true; + data.status = status; + }, }, - }, - /** - * @name startFrame - * @type {integer} - * @memberof module:API.cvat.classes.Job - * @readonly - * @instance - */ - startFrame: { - get: () => data.start_frame, - }, - /** - * @name stopFrame - * @type {integer} - * @memberof module:API.cvat.classes.Job - * @readonly - * @instance - */ - stopFrame: { - get: () => data.stop_frame, - }, - /** - * @name task - * @type {module:API.cvat.classes.Task} - * @memberof module:API.cvat.classes.Job - * @readonly - * @instance - */ - task: { - get: () => data.task, - }, - })); + /** + * @name startFrame + * @type {integer} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + */ + startFrame: { + get: () => data.start_frame, + }, + /** + * @name stopFrame + * @type {integer} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + */ + stopFrame: { + get: () => data.stop_frame, + }, + /** + * @name task + * @type {module:API.cvat.classes.Task} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + */ + task: { + get: () => data.task, + }, + __updatedFields: { + get: () => updatedFields, + set: (fields) => { + updatedFields = fields; + }, + }, + }), + ); // When we call a function, for example: task.annotations.get() // In the method get we lose the task context @@ -733,18 +829,19 @@ group: Object.getPrototypeOf(this).annotations.group.bind(this), clear: Object.getPrototypeOf(this).annotations.clear.bind(this), search: Object.getPrototypeOf(this).annotations.search.bind(this), + searchEmpty: Object.getPrototypeOf(this).annotations.searchEmpty.bind(this), upload: Object.getPrototypeOf(this).annotations.upload.bind(this), select: Object.getPrototypeOf(this).annotations.select.bind(this), import: Object.getPrototypeOf(this).annotations.import.bind(this), export: Object.getPrototypeOf(this).annotations.export.bind(this), statistics: Object.getPrototypeOf(this).annotations.statistics.bind(this), - hasUnsavedChanges: Object.getPrototypeOf(this) - .annotations.hasUnsavedChanges.bind(this), + hasUnsavedChanges: Object.getPrototypeOf(this).annotations.hasUnsavedChanges.bind(this), }; this.actions = { undo: Object.getPrototypeOf(this).actions.undo.bind(this), redo: Object.getPrototypeOf(this).actions.redo.bind(this), + freeze: Object.getPrototypeOf(this).actions.freeze.bind(this), clear: Object.getPrototypeOf(this).actions.clear.bind(this), get: Object.getPrototypeOf(this).actions.get.bind(this), }; @@ -761,56 +858,112 @@ } /** - * Method updates job data like status or assignee - * @method save - * @memberof module:API.cvat.classes.Job - * @readonly - * @instance - * @async - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method updates job data like status or assignee + * @method save + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async save() { - const result = await PluginRegistry - .apiWrapper.call(this, Job.prototype.save); + const result = await PluginRegistry.apiWrapper.call(this, Job.prototype.save); + return result; + } + + /** + * Method returns a list of issues for a job + * @method issues + * @memberof module:API.cvat.classes.Job + * @type {module:API.cvat.classes.Issue[]} + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async issues() { + const result = await PluginRegistry.apiWrapper.call(this, Job.prototype.issues); + return result; + } + + /** + * Method returns a list of reviews for a job + * @method reviews + * @type {module:API.cvat.classes.Review[]} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async reviews() { + const result = await PluginRegistry.apiWrapper.call(this, Job.prototype.reviews); + return result; + } + + /** + * /** + * @typedef {Object} ReviewSummary + * @property {number} reviews Number of done reviews + * @property {number} average_estimated_quality + * @property {number} issues_unsolved + * @property {number} issues_resolved + * @property {string[]} assignees + * @property {string[]} reviewers + */ + /** + * Method returns brief summary of within all reviews + * @method reviewsSummary + * @type {ReviewSummary} + * @memberof module:API.cvat.classes.Job + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ + async reviewsSummary() { + const result = await PluginRegistry.apiWrapper.call(this, Job.prototype.reviewsSummary); return result; } } /** - * Class representing a task - * @memberof module:API.cvat.classes - * @extends Session - */ + * Class representing a task + * @memberof module:API.cvat.classes + * @extends Session + */ class Task extends Session { - /** - * In a fact you need use the constructor only if you want to create a task - * @param {object} initialData - Object which is used for initalization - *
    It can contain keys: - *
  • name - *
  • assignee - *
  • bug_tracker - *
  • z_order - *
  • labels - *
  • segment_size - *
  • overlap - */ + /** + * In a fact you need use the constructor only if you want to create a task + * @param {object} initialData - Object which is used for initalization + *
    It can contain keys: + *
  • name + *
  • assignee + *
  • bug_tracker + *
  • labels + *
  • segment_size + *
  • overlap + */ constructor(initialData) { super(); const data = { id: undefined, name: undefined, + project_id: undefined, status: undefined, size: undefined, mode: undefined, - owner: undefined, - assignee: undefined, + owner: null, + assignee: null, created_date: undefined, updated_date: undefined, bug_tracker: undefined, overlap: undefined, segment_size: undefined, - z_order: undefined, image_quality: undefined, start_frame: undefined, stop_frame: undefined, @@ -819,15 +972,26 @@ data_compressed_chunk_type: undefined, data_original_chunk_type: undefined, use_zip_chunks: undefined, + use_cache: undefined, + copy_data: undefined, + }; + + let updatedFields = { + name: false, + assignee: false, + bug_tracker: false, + labels: false, }; for (const property in data) { - if (Object.prototype.hasOwnProperty.call(data, property) - && property in initialData) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { data[property] = initialData[property]; } } + if (data.assignee) data.assignee = new User(data.assignee); + if (data.owner) data.owner = new User(data.owner); + data.labels = []; data.jobs = []; data.files = Object.freeze({ @@ -844,6 +1008,7 @@ url: job.url, id: job.id, assignee: job.assignee, + reviewer: job.reviewer, status: job.status, start_frame: segment.start_frame, stop_frame: segment.stop_frame, @@ -862,415 +1027,433 @@ } } - Object.defineProperties(this, Object.freeze({ - /** - * @name id - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - id: { - get: () => data.id, - }, - /** - * @name name - * @type {string} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - name: { - get: () => data.name, - set: (value) => { - if (!value.trim().length) { - throw new ArgumentError( - 'Value must not be empty', - ); - } - data.name = value; + Object.defineProperties( + this, + Object.freeze({ + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + id: { + get: () => data.id, }, - }, - /** - * @name status - * @type {module:API.cvat.enums.TaskStatus} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - status: { - get: () => data.status, - }, - /** - * @name size - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - size: { - get: () => data.size, - }, - /** - * @name mode - * @type {TaskMode} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - mode: { - get: () => data.mode, - }, - /** - * Instance of a user who has created the task - * @name owner - * @type {module:API.cvat.classes.User} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - owner: { - get: () => data.owner, - }, - /** - * Instance of a user who is responsible for the task - * @name assignee - * @type {module:API.cvat.classes.User} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - assignee: { - get: () => data.assignee, - set: (assignee) => { - if (assignee !== null && !(assignee instanceof User)) { - throw new ArgumentError( - 'Value must be a user instance', - ); - } - data.assignee = assignee; + /** + * @name name + * @type {string} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + name: { + get: () => data.name, + set: (value) => { + if (!value.trim().length) { + throw new ArgumentError('Value must not be empty'); + } + updatedFields.name = true; + data.name = value; + }, }, - }, - /** - * @name createdDate - * @type {string} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - createdDate: { - get: () => data.created_date, - }, - /** - * @name updatedDate - * @type {string} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - updatedDate: { - get: () => data.updated_date, - }, - /** - * @name bugTracker - * @type {string} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - bugTracker: { - get: () => data.bug_tracker, - set: (tracker) => { - data.bug_tracker = tracker; + /** + * @name projectId + * @type {integer|null} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + projectId: { + get: () => data.project_id, }, - }, - /** - * @name overlap - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - overlap: { - get: () => data.overlap, - set: (overlap) => { - if (!Number.isInteger(overlap) || overlap < 0) { - throw new ArgumentError( - 'Value must be a non negative integer', - ); - } - data.overlap = overlap; + /** + * @name status + * @type {module:API.cvat.enums.TaskStatus} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + status: { + get: () => data.status, }, - }, - /** - * @name segmentSize - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - segmentSize: { - get: () => data.segment_size, - set: (segment) => { - if (!Number.isInteger(segment) || segment < 0) { - throw new ArgumentError( - 'Value must be a positive integer', - ); - } - data.segment_size = segment; + /** + * @name size + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + size: { + get: () => data.size, }, - }, - /** - * @name zOrder - * @type {boolean} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - zOrder: { - get: () => data.z_order, - set: (zOrder) => { - if (typeof (zOrder) !== 'boolean') { - throw new ArgumentError( - 'Value must be a boolean', - ); - } - data.z_order = zOrder; + /** + * @name mode + * @type {TaskMode} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + mode: { + get: () => data.mode, }, - }, - /** - * @name imageQuality - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - imageQuality: { - get: () => data.image_quality, - set: (quality) => { - if (!Number.isInteger(quality) || quality < 0) { - throw new ArgumentError( - 'Value must be a positive integer', - ); - } - data.image_quality = quality; + /** + * Instance of a user who has created the task + * @name owner + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + owner: { + get: () => data.owner, }, - }, - /** - * @name useZipChunks - * @type {boolean} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - useZipChunks: { - get: () => data.use_zip_chunks, - set: (useZipChunks) => { - if (typeof (useZipChunks) !== 'boolean') { - throw new ArgumentError( - 'Value must be a boolean', - ); - } - data.use_zip_chunks = useZipChunks; + /** + * Instance of a user who is responsible for the task + * @name assignee + * @type {module:API.cvat.classes.User} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + assignee: { + get: () => data.assignee, + set: (assignee) => { + if (assignee !== null && !(assignee instanceof User)) { + throw new ArgumentError('Value must be a user instance'); + } + updatedFields.assignee = true; + data.assignee = assignee; + }, }, - }, - /** - * After task has been created value can be appended only. - * @name labels - * @type {module:API.cvat.classes.Label[]} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - labels: { - get: () => [...data.labels], - set: (labels) => { - if (!Array.isArray(labels)) { - throw new ArgumentError( - 'Value must be an array of Labels', - ); - } + /** + * @name createdDate + * @type {string} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + createdDate: { + get: () => data.created_date, + }, + /** + * @name updatedDate + * @type {string} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + updatedDate: { + get: () => data.updated_date, + }, + /** + * @name bugTracker + * @type {string} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + bugTracker: { + get: () => data.bug_tracker, + set: (tracker) => { + updatedFields.bug_tracker = true; + data.bug_tracker = tracker; + }, + }, + /** + * @name overlap + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + overlap: { + get: () => data.overlap, + set: (overlap) => { + if (!Number.isInteger(overlap) || overlap < 0) { + throw new ArgumentError('Value must be a non negative integer'); + } + data.overlap = overlap; + }, + }, + /** + * @name segmentSize + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + segmentSize: { + get: () => data.segment_size, + set: (segment) => { + if (!Number.isInteger(segment) || segment < 0) { + throw new ArgumentError('Value must be a positive integer'); + } + data.segment_size = segment; + }, + }, + /** + * @name imageQuality + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + imageQuality: { + get: () => data.image_quality, + set: (quality) => { + if (!Number.isInteger(quality) || quality < 0) { + throw new ArgumentError('Value must be a positive integer'); + } + data.image_quality = quality; + }, + }, + /** + * @name useZipChunks + * @type {boolean} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + useZipChunks: { + get: () => data.use_zip_chunks, + set: (useZipChunks) => { + if (typeof useZipChunks !== 'boolean') { + throw new ArgumentError('Value must be a boolean'); + } + data.use_zip_chunks = useZipChunks; + }, + }, + /** + * @name useCache + * @type {boolean} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + useCache: { + get: () => data.use_cache, + set: (useCache) => { + if (typeof useCache !== 'boolean') { + throw new ArgumentError('Value must be a boolean'); + } + data.use_cache = useCache; + }, + }, + /** + * @name copyData + * @type {boolean} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + copyData: { + get: () => data.copy_data, + set: (copyData) => { + if (typeof copyData !== 'boolean') { + throw new ArgumentError('Value must be a boolean'); + } + data.copy_data = copyData; + }, + }, + /** + * After task has been created value can be appended only. + * @name labels + * @type {module:API.cvat.classes.Label[]} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + labels: { + get: () => [...data.labels], + set: (labels) => { + if (!Array.isArray(labels)) { + throw new ArgumentError('Value must be an array of Labels'); + } - for (const label of labels) { - if (!(label instanceof Label)) { - throw new ArgumentError( - 'Each array value must be an instance of Label. ' - + `${typeof (label)} was found`, - ); + for (const label of labels) { + if (!(label instanceof Label)) { + throw new ArgumentError( + `Each array value must be an instance of Label. ${typeof label} was found`, + ); + } } - } - data.labels = [...labels]; + updatedFields.labels = true; + data.labels = [...labels]; + }, }, - }, - /** - * @name jobs - * @type {module:API.cvat.classes.Job[]} - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - */ - jobs: { - get: () => [...data.jobs], - }, - /** - * List of files from shared resource - * @name serverFiles - * @type {string[]} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - serverFiles: { - get: () => [...data.files.server_files], - set: (serverFiles) => { - if (!Array.isArray(serverFiles)) { - throw new ArgumentError( - `Value must be an array. But ${typeof (serverFiles)} has been got.`, - ); - } - - for (const value of serverFiles) { - if (typeof (value) !== 'string') { + /** + * @name jobs + * @type {module:API.cvat.classes.Job[]} + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + */ + jobs: { + get: () => [...data.jobs], + }, + /** + * List of files from shared resource + * @name serverFiles + * @type {string[]} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + serverFiles: { + get: () => [...data.files.server_files], + set: (serverFiles) => { + if (!Array.isArray(serverFiles)) { throw new ArgumentError( - `Array values must be a string. But ${typeof (value)} has been got.`, + `Value must be an array. But ${typeof serverFiles} has been got.`, ); } - } - Array.prototype.push.apply(data.files.server_files, serverFiles); - }, - }, - /** - * List of files from client host - * @name clientFiles - * @type {File[]} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - clientFiles: { - get: () => [...data.files.client_files], - set: (clientFiles) => { - if (!Array.isArray(clientFiles)) { - throw new ArgumentError( - `Value must be an array. But ${typeof (clientFiles)} has been got.`, - ); - } + for (const value of serverFiles) { + if (typeof value !== 'string') { + throw new ArgumentError( + `Array values must be a string. But ${typeof value} has been got.`, + ); + } + } - for (const value of clientFiles) { - if (!(value instanceof File)) { + Array.prototype.push.apply(data.files.server_files, serverFiles); + }, + }, + /** + * List of files from client host + * @name clientFiles + * @type {File[]} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + clientFiles: { + get: () => [...data.files.client_files], + set: (clientFiles) => { + if (!Array.isArray(clientFiles)) { throw new ArgumentError( - `Array values must be a File. But ${value.constructor.name} has been got.`, + `Value must be an array. But ${typeof clientFiles} has been got.`, ); } - } - Array.prototype.push.apply(data.files.client_files, clientFiles); - }, - }, - /** - * List of files from remote host - * @name remoteFiles - * @type {File[]} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - remoteFiles: { - get: () => [...data.files.remote_files], - set: (remoteFiles) => { - if (!Array.isArray(remoteFiles)) { - throw new ArgumentError( - `Value must be an array. But ${typeof (remoteFiles)} has been got.`, - ); - } + for (const value of clientFiles) { + if (!(value instanceof File)) { + throw new ArgumentError( + `Array values must be a File. But ${value.constructor.name} has been got.`, + ); + } + } - for (const value of remoteFiles) { - if (typeof (value) !== 'string') { + Array.prototype.push.apply(data.files.client_files, clientFiles); + }, + }, + /** + * List of files from remote host + * @name remoteFiles + * @type {File[]} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + remoteFiles: { + get: () => [...data.files.remote_files], + set: (remoteFiles) => { + if (!Array.isArray(remoteFiles)) { throw new ArgumentError( - `Array values must be a string. But ${typeof (value)} has been got.`, + `Value must be an array. But ${typeof remoteFiles} has been got.`, ); } - } - Array.prototype.push.apply(data.files.remote_files, remoteFiles); + for (const value of remoteFiles) { + if (typeof value !== 'string') { + throw new ArgumentError( + `Array values must be a string. But ${typeof value} has been got.`, + ); + } + } + + Array.prototype.push.apply(data.files.remote_files, remoteFiles); + }, }, - }, - /** - * The first frame of a video to annotation - * @name startFrame - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - startFrame: { - get: () => data.start_frame, - set: (frame) => { - if (!Number.isInteger(frame) || frame < 0) { - throw new ArgumentError( - 'Value must be a not negative integer', - ); - } - data.start_frame = frame; + /** + * The first frame of a video to annotation + * @name startFrame + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + startFrame: { + get: () => data.start_frame, + set: (frame) => { + if (!Number.isInteger(frame) || frame < 0) { + throw new ArgumentError('Value must be a not negative integer'); + } + data.start_frame = frame; + }, }, - }, - /** - * The last frame of a video to annotation - * @name stopFrame - * @type {integer} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - stopFrame: { - get: () => data.stop_frame, - set: (frame) => { - if (!Number.isInteger(frame) || frame < 0) { - throw new ArgumentError( - 'Value must be a not negative integer', - ); - } - data.stop_frame = frame; + /** + * The last frame of a video to annotation + * @name stopFrame + * @type {integer} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + stopFrame: { + get: () => data.stop_frame, + set: (frame) => { + if (!Number.isInteger(frame) || frame < 0) { + throw new ArgumentError('Value must be a not negative integer'); + } + data.stop_frame = frame; + }, }, - }, - /** - * Filter to ignore some frames during task creation - * @name frameFilter - * @type {string} - * @memberof module:API.cvat.classes.Task - * @instance - * @throws {module:API.cvat.exceptions.ArgumentError} - */ - frameFilter: { - get: () => data.frame_filter, - set: (filter) => { - if (typeof (filter) !== 'string') { - throw new ArgumentError( - `Filter value must be a string. But ${typeof (filter)} has been got.`, - ); - } + /** + * Filter to ignore some frames during task creation + * @name frameFilter + * @type {string} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + frameFilter: { + get: () => data.frame_filter, + set: (filter) => { + if (typeof filter !== 'string') { + throw new ArgumentError( + `Filter value must be a string. But ${typeof filter} has been got.`, + ); + } - data.frame_filter = filter; + data.frame_filter = filter; + }, }, - }, - dataChunkSize: { - get: () => data.data_chunk_size, - set: (chunkSize) => { - if (typeof (chunkSize) !== 'number' || chunkSize < 1) { - throw new ArgumentError( - `Chunk size value must be a positive number. But value ${chunkSize} has been got.`, - ); - } + dataChunkSize: { + get: () => data.data_chunk_size, + set: (chunkSize) => { + if (typeof chunkSize !== 'number' || chunkSize < 1) { + throw new ArgumentError( + `Chunk size value must be a positive number. But value ${chunkSize} has been got.`, + ); + } - data.data_chunk_size = chunkSize; + data.data_chunk_size = chunkSize; + }, }, - }, - dataChunkType: { - get: () => data.data_compressed_chunk_type, - }, - })); + dataChunkType: { + get: () => data.data_compressed_chunk_type, + }, + __updatedFields: { + get: () => updatedFields, + set: (fields) => { + updatedFields = fields; + }, + }, + }), + ); // When we call a function, for example: task.annotations.get() // In the method get we lose the task context @@ -1285,20 +1468,20 @@ group: Object.getPrototypeOf(this).annotations.group.bind(this), clear: Object.getPrototypeOf(this).annotations.clear.bind(this), search: Object.getPrototypeOf(this).annotations.search.bind(this), + searchEmpty: Object.getPrototypeOf(this).annotations.searchEmpty.bind(this), upload: Object.getPrototypeOf(this).annotations.upload.bind(this), select: Object.getPrototypeOf(this).annotations.select.bind(this), import: Object.getPrototypeOf(this).annotations.import.bind(this), export: Object.getPrototypeOf(this).annotations.export.bind(this), statistics: Object.getPrototypeOf(this).annotations.statistics.bind(this), - hasUnsavedChanges: Object.getPrototypeOf(this) - .annotations.hasUnsavedChanges.bind(this), - exportDataset: Object.getPrototypeOf(this) - .annotations.exportDataset.bind(this), + hasUnsavedChanges: Object.getPrototypeOf(this).annotations.hasUnsavedChanges.bind(this), + exportDataset: Object.getPrototypeOf(this).annotations.exportDataset.bind(this), }; this.actions = { undo: Object.getPrototypeOf(this).actions.undo.bind(this), redo: Object.getPrototypeOf(this).actions.redo.bind(this), + freeze: Object.getPrototypeOf(this).actions.freeze.bind(this), clear: Object.getPrototypeOf(this).actions.clear.bind(this), get: Object.getPrototypeOf(this).actions.get.bind(this), }; @@ -1315,53 +1498,51 @@ } /** - * Method removes all task related data from the client (annotations, history, etc.) - * @method close - * @returns {module:API.cvat.classes.Task} - * @memberof module:API.cvat.classes.Task - * @readonly - * @async - * @instance - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method removes all task related data from the client (annotations, history, etc.) + * @method close + * @returns {module:API.cvat.classes.Task} + * @memberof module:API.cvat.classes.Task + * @readonly + * @async + * @instance + * @throws {module:API.cvat.exceptions.PluginError} + */ async close() { const result = await PluginRegistry.apiWrapper.call(this, Task.prototype.close); return result; } /** - * Method updates data of a created task or creates new task from scratch - * @method save - * @returns {module:API.cvat.classes.Task} - * @memberof module:API.cvat.classes.Task - * @param {function} [onUpdate] - the function which is used only if task hasn't - * been created yet. It called in order to notify about creation status. - * It receives the string parameter which is a status message - * @readonly - * @instance - * @async - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method updates data of a created task or creates new task from scratch + * @method save + * @returns {module:API.cvat.classes.Task} + * @memberof module:API.cvat.classes.Task + * @param {function} [onUpdate] - the function which is used only if task hasn't + * been created yet. It called in order to notify about creation status. + * It receives the string parameter which is a status message + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async save(onUpdate = () => {}) { - const result = await PluginRegistry - .apiWrapper.call(this, Task.prototype.save, onUpdate); + const result = await PluginRegistry.apiWrapper.call(this, Task.prototype.save, onUpdate); return result; } /** - * Method deletes a task from a server - * @method delete - * @memberof module:API.cvat.classes.Task - * @readonly - * @instance - * @async - * @throws {module:API.cvat.exceptions.ServerError} - * @throws {module:API.cvat.exceptions.PluginError} - */ + * Method deletes a task from a server + * @method delete + * @memberof module:API.cvat.classes.Task + * @readonly + * @instance + * @async + * @throws {module:API.cvat.exceptions.ServerError} + * @throws {module:API.cvat.exceptions.PluginError} + */ async delete() { - const result = await PluginRegistry - .apiWrapper.call(this, Task.prototype.delete); + const result = await PluginRegistry.apiWrapper.call(this, Task.prototype.delete); return result; } } @@ -1377,6 +1558,7 @@ saveAnnotations, hasUnsavedChanges, searchAnnotations, + searchEmptyFrame, mergeAnnotations, splitAnnotations, groupAnnotations, @@ -1390,6 +1572,7 @@ exportDataset, undoActions, redoActions, + freezeHistory, clearActions, getActions, closeSession, @@ -1399,33 +1582,84 @@ buildDublicatedAPI(Task.prototype); Job.prototype.save.implementation = async function () { - // TODO: Add ability to change an assignee if (this.id) { - const jobData = { - status: this.status, - assignee: this.assignee ? this.assignee.id : null, + const jobData = {}; + + for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { + if (isUpdated) { + switch (field) { + case 'status': + jobData.status = this.status; + break; + case 'assignee': + jobData.assignee_id = this.assignee ? this.assignee.id : null; + break; + case 'reviewer': + jobData.reviewer_id = this.reviewer ? this.reviewer.id : null; + break; + default: + break; + } + } + } + + await serverProxy.jobs.save(this.id, jobData); + + this.__updatedFields = { + status: false, + assignee: false, + reviewer: false, }; - await serverProxy.jobs.saveJob(this.id, jobData); return this; } - throw new ArgumentError( - 'Can not save job without and id', - ); + throw new ArgumentError('Can not save job without and id'); + }; + + Job.prototype.issues.implementation = async function () { + const result = await serverProxy.jobs.issues(this.id); + return result.map((issue) => new Issue(issue)); + }; + + Job.prototype.reviews.implementation = async function () { + const result = await serverProxy.jobs.reviews.get(this.id); + const reviews = result.map((review) => new Review(review)); + + // try to get not finished review from the local storage + const data = store.get(`job-${this.id}-review`); + if (data) { + reviews.push(new Review(JSON.parse(data))); + } + + return reviews; + }; + + Job.prototype.reviewsSummary.implementation = async function () { + const reviews = await serverProxy.jobs.reviews.get(this.id); + const issues = await serverProxy.jobs.issues(this.id); + + const qualities = reviews.map((review) => review.estimated_quality); + const reviewers = reviews.filter((review) => review.reviewer).map((review) => review.reviewer.username); + const assignees = reviews.filter((review) => review.assignee).map((review) => review.assignee.username); + + return { + reviews: reviews.length, + average_estimated_quality: qualities.reduce((acc, quality) => acc + quality, 0) / (qualities.length || 1), + issues_unsolved: issues.filter((issue) => !issue.resolved_date).length, + issues_resolved: issues.filter((issue) => issue.resolved_date).length, + assignees: Array.from(new Set(assignees.filter((assignee) => assignee !== null))), + reviewers: Array.from(new Set(reviewers.filter((reviewer) => reviewer !== null))), + }; }; Job.prototype.frames.get.implementation = async function (frame, isPlaying, step) { if (!Number.isInteger(frame) || frame < 0) { - throw new ArgumentError( - `Frame must be a positive integer. Got: "${frame}"`, - ); + throw new ArgumentError(`Frame must be a positive integer. Got: "${frame}"`); } if (frame < this.startFrame || frame > this.stopFrame) { - throw new ArgumentError( - `The frame with number ${frame} is out of the job`, - ); + throw new ArgumentError(`The frame with number ${frame} is out of the job`); } const frameData = await getFrame( @@ -1443,30 +1677,22 @@ }; Job.prototype.frames.ranges.implementation = async function () { - const rangesData = await getRanges( - this.task.id, - ); + const rangesData = await getRanges(this.task.id); return rangesData; }; // TODO: Check filter for annotations Job.prototype.annotations.get.implementation = async function (frame, allTracks, filters) { - if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) { - throw new ArgumentError( - 'The filters argument must be an array of strings', - ); + if (!Array.isArray(filters) || filters.some((filter) => typeof filter !== 'string')) { + throw new ArgumentError('The filters argument must be an array of strings'); } if (!Number.isInteger(frame)) { - throw new ArgumentError( - 'The frame argument must be an integer', - ); + throw new ArgumentError('The frame argument must be an integer'); } if (frame < this.startFrame || frame > this.stopFrame) { - throw new ArgumentError( - `Frame ${frame} does not exist in the job`, - ); + throw new ArgumentError(`Frame ${frame} does not exist in the job`); } const annotationsData = await getAnnotations(this, frame, allTracks, filters); @@ -1474,34 +1700,43 @@ }; Job.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) { - if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) { - throw new ArgumentError( - 'The filters argument must be an array of strings', - ); + if (!Array.isArray(filters) || filters.some((filter) => typeof filter !== 'string')) { + throw new ArgumentError('The filters argument must be an array of strings'); } if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) { - throw new ArgumentError( - 'The start and end frames both must be an integer', - ); + throw new ArgumentError('The start and end frames both must be an integer'); } if (frameFrom < this.startFrame || frameFrom > this.stopFrame) { - throw new ArgumentError( - 'The start frame is out of the job', - ); + throw new ArgumentError('The start frame is out of the job'); } if (frameTo < this.startFrame || frameTo > this.stopFrame) { - throw new ArgumentError( - 'The stop frame is out of the job', - ); + throw new ArgumentError('The stop frame is out of the job'); } const result = searchAnnotations(this, filters, frameFrom, frameTo); return result; }; + Job.prototype.annotations.searchEmpty.implementation = function (frameFrom, frameTo) { + if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) { + throw new ArgumentError('The start and end frames both must be an integer'); + } + + if (frameFrom < this.startFrame || frameFrom > this.stopFrame) { + throw new ArgumentError('The start frame is out of the job'); + } + + if (frameTo < this.startFrame || frameTo > this.stopFrame) { + throw new ArgumentError('The stop frame is out of the job'); + } + + const result = searchEmptyFrame(this, frameFrom, frameTo); + return result; + }; + Job.prototype.annotations.save.implementation = async function (onUpdate) { const result = await saveAnnotations(this, onUpdate); return result; @@ -1582,6 +1817,11 @@ return result; }; + Job.prototype.actions.freeze.implementation = function (frozen) { + const result = freezeHistory(this, frozen); + return result; + }; + Job.prototype.actions.clear.implementation = function () { const result = clearActions(this); return result; @@ -1607,37 +1847,62 @@ return this; }; - Task.prototype.save.implementation = async function saveTaskImplementation(onUpdate) { + Task.prototype.save.implementation = async function (onUpdate) { // TODO: Add ability to change an owner and an assignee - if (typeof (this.id) !== 'undefined') { + if (typeof this.id !== 'undefined') { // If the task has been already created, we update it - const taskData = { - assignee: this.assignee ? this.assignee.id : null, - name: this.name, - bug_tracker: this.bugTracker, - z_order: this.zOrder, - labels: [...this.labels.map((el) => el.toJSON())], - }; + const taskData = {}; + + for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { + if (isUpdated) { + switch (field) { + case 'assignee': + taskData.assignee_id = this.assignee ? this.assignee.id : null; + break; + case 'name': + taskData.name = this.name; + break; + case 'bug_tracker': + taskData.bug_tracker = this.bugTracker; + break; + case 'labels': + taskData.labels = [...this.labels.map((el) => el.toJSON())]; + break; + default: + break; + } + } + } await serverProxy.tasks.saveTask(this.id, taskData); + + this.updatedFields = { + assignee: false, + name: false, + bugTracker: false, + labels: false, + }; + return this; } const taskSpec = { name: this.name, labels: this.labels.map((el) => el.toJSON()), - z_order: Boolean(this.zOrder), }; - if (typeof (this.bugTracker) !== 'undefined') { + if (typeof this.bugTracker !== 'undefined') { taskSpec.bug_tracker = this.bugTracker; } - if (typeof (this.segmentSize) !== 'undefined') { + if (typeof this.segmentSize !== 'undefined') { taskSpec.segment_size = this.segmentSize; } - if (typeof (this.overlap) !== 'undefined') { + if (typeof this.overlap !== 'undefined') { taskSpec.overlap = this.overlap; } + if (typeof this.projectId !== 'undefined') { + taskSpec.project_id = this.projectId; + } const taskDataSpec = { client_files: this.clientFiles, @@ -1645,20 +1910,24 @@ remote_files: this.remoteFiles, image_quality: this.imageQuality, use_zip_chunks: this.useZipChunks, + use_cache: this.useCache, }; - if (typeof (this.startFrame) !== 'undefined') { + if (typeof this.startFrame !== 'undefined') { taskDataSpec.start_frame = this.startFrame; } - if (typeof (this.stopFrame) !== 'undefined') { + if (typeof this.stopFrame !== 'undefined') { taskDataSpec.stop_frame = this.stopFrame; } - if (typeof (this.frameFilter) !== 'undefined') { + if (typeof this.frameFilter !== 'undefined') { taskDataSpec.frame_filter = this.frameFilter; } - if (typeof (this.dataChunkSize) !== 'undefined') { + if (typeof this.dataChunkSize !== 'undefined') { taskDataSpec.chunk_size = this.dataChunkSize; } + if (typeof this.copyData !== 'undefined') { + taskDataSpec.copy_data = this.copyData; + } const task = await serverProxy.tasks.createTask(taskSpec, taskDataSpec, onUpdate); return new Task(task); @@ -1671,15 +1940,11 @@ Task.prototype.frames.get.implementation = async function (frame, isPlaying, step) { if (!Number.isInteger(frame) || frame < 0) { - throw new ArgumentError( - `Frame must be a positive integer. Got: "${frame}"`, - ); + throw new ArgumentError(`Frame must be a positive integer. Got: "${frame}"`); } if (frame >= this.size) { - throw new ArgumentError( - `The frame with number ${frame} is out of the task`, - ); + throw new ArgumentError(`The frame with number ${frame} is out of the task`); } const result = await getFrame( @@ -1702,9 +1967,7 @@ }; Task.prototype.frames.ranges.implementation = async function () { - const rangesData = await getRanges( - this.id, - ); + const rangesData = await getRanges(this.id); return rangesData; }; @@ -1715,22 +1978,16 @@ // TODO: Check filter for annotations Task.prototype.annotations.get.implementation = async function (frame, allTracks, filters) { - if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) { - throw new ArgumentError( - 'The filters argument must be an array of strings', - ); + if (!Array.isArray(filters) || filters.some((filter) => typeof filter !== 'string')) { + throw new ArgumentError('The filters argument must be an array of strings'); } if (!Number.isInteger(frame) || frame < 0) { - throw new ArgumentError( - `Frame must be a positive integer. Got: "${frame}"`, - ); + throw new ArgumentError(`Frame must be a positive integer. Got: "${frame}"`); } if (frame >= this.size) { - throw new ArgumentError( - `Frame ${frame} does not exist in the task`, - ); + throw new ArgumentError(`Frame ${frame} does not exist in the task`); } const result = await getAnnotations(this, frame, allTracks, filters); @@ -1738,34 +1995,43 @@ }; Task.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) { - if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) { - throw new ArgumentError( - 'The filters argument must be an array of strings', - ); + if (!Array.isArray(filters) || filters.some((filter) => typeof filter !== 'string')) { + throw new ArgumentError('The filters argument must be an array of strings'); } if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) { - throw new ArgumentError( - 'The start and end frames both must be an integer', - ); + throw new ArgumentError('The start and end frames both must be an integer'); } if (frameFrom < 0 || frameFrom >= this.size) { - throw new ArgumentError( - 'The start frame is out of the task', - ); + throw new ArgumentError('The start frame is out of the task'); } if (frameTo < 0 || frameTo >= this.size) { - throw new ArgumentError( - 'The stop frame is out of the task', - ); + throw new ArgumentError('The stop frame is out of the task'); } const result = searchAnnotations(this, filters, frameFrom, frameTo); return result; }; + Task.prototype.annotations.searchEmpty.implementation = function (frameFrom, frameTo) { + if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) { + throw new ArgumentError('The start and end frames both must be an integer'); + } + + if (frameFrom < 0 || frameFrom >= this.size) { + throw new ArgumentError('The start frame is out of the task'); + } + + if (frameTo < 0 || frameTo >= this.size) { + throw new ArgumentError('The stop frame is out of the task'); + } + + const result = searchEmptyFrame(this, frameFrom, frameTo); + return result; + }; + Task.prototype.annotations.save.implementation = async function (onUpdate) { const result = await saveAnnotations(this, onUpdate); return result; @@ -1846,6 +2112,11 @@ return result; }; + Task.prototype.actions.freeze.implementation = function (frozen) { + const result = freezeHistory(this, frozen); + return result; + }; + Task.prototype.actions.clear.implementation = function () { const result = clearActions(this); return result; diff --git a/cvat-core/src/statistics.js b/cvat-core/src/statistics.js index 8e997446..b6ac87d1 100644 --- a/cvat-core/src/statistics.js +++ b/cvat-core/src/statistics.js @@ -1,97 +1,98 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { /** - * Class representing collection statistics - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing collection statistics + * @memberof module:API.cvat.classes + * @hideconstructor + */ class Statistics { constructor(label, total) { - Object.defineProperties(this, Object.freeze({ - /** - * Statistics by labels with a structure: - * @example - * { - * label: { - * boxes: { - * tracks: 10, - * shapes: 11, - * }, - * polygons: { - * tracks: 13, - * shapes: 14, - * }, - * polylines: { - * tracks: 16, - * shapes: 17, - * }, - * points: { - * tracks: 19, - * shapes: 20, - * }, - * cuboids: { - * tracks: 21, - * shapes: 22, - * }, - * tags: 66, - * manually: 186, - * interpolated: 500, - * total: 608, - * } - * } - * @name label - * @type {Object} - * @memberof module:API.cvat.classes.Statistics - * @readonly - * @instance - */ - label: { - get: () => JSON.parse(JSON.stringify(label)), - }, - /** - * Total statistics (covers all labels) with a structure: - * @example - * { - * boxes: { - * tracks: 10, - * shapes: 11, - * }, - * polygons: { - * tracks: 13, - * shapes: 14, - * }, - * polylines: { - * tracks: 16, - * shapes: 17, - * }, - * points: { - * tracks: 19, - * shapes: 20, - * }, - * cuboids: { - * tracks: 21, - * shapes: 22, - * }, - * tags: 66, - * manually: 186, - * interpolated: 500, - * total: 608, - * } - * @name total - * @type {Object} - * @memberof module:API.cvat.classes.Statistics - * @readonly - * @instance - */ - total: { - get: () => JSON.parse(JSON.stringify(total)), - }, - })); + Object.defineProperties( + this, + Object.freeze({ + /** + * Statistics by labels with a structure: + * @example + * { + * label: { + * boxes: { + * tracks: 10, + * shapes: 11, + * }, + * polygons: { + * tracks: 13, + * shapes: 14, + * }, + * polylines: { + * tracks: 16, + * shapes: 17, + * }, + * points: { + * tracks: 19, + * shapes: 20, + * }, + * cuboids: { + * tracks: 21, + * shapes: 22, + * }, + * tags: 66, + * manually: 186, + * interpolated: 500, + * total: 608, + * } + * } + * @name label + * @type {Object} + * @memberof module:API.cvat.classes.Statistics + * @readonly + * @instance + */ + label: { + get: () => JSON.parse(JSON.stringify(label)), + }, + /** + * Total statistics (covers all labels) with a structure: + * @example + * { + * boxes: { + * tracks: 10, + * shapes: 11, + * }, + * polygons: { + * tracks: 13, + * shapes: 14, + * }, + * polylines: { + * tracks: 16, + * shapes: 17, + * }, + * points: { + * tracks: 19, + * shapes: 20, + * }, + * cuboids: { + * tracks: 21, + * shapes: 22, + * }, + * tags: 66, + * manually: 186, + * interpolated: 500, + * total: 608, + * } + * @name total + * @type {Object} + * @memberof module:API.cvat.classes.Statistics + * @readonly + * @instance + */ + total: { + get: () => JSON.parse(JSON.stringify(total)), + }, + }), + ); } } diff --git a/cvat-core/src/user.js b/cvat-core/src/user.js index 555ea83d..d826c822 100644 --- a/cvat-core/src/user.js +++ b/cvat-core/src/user.js @@ -1,14 +1,13 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT (() => { /** - * Class representing a user - * @memberof module:API.cvat.classes - * @hideconstructor - */ + * Class representing a user + * @memberof module:API.cvat.classes + * @hideconstructor + */ class User { constructor(initialData) { const data = { @@ -27,134 +26,157 @@ }; for (const property in data) { - if (Object.prototype.hasOwnProperty.call(data, property) - && property in initialData) { + if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { data[property] = initialData[property]; } } - Object.defineProperties(this, Object.freeze({ - id: { - /** - * @name id - * @type {integer} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.id, - }, - username: { - /** - * @name username - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.username, - }, - email: { - /** - * @name email - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.email, - }, - firstName: { - /** - * @name firstName - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.first_name, - }, - lastName: { - /** - * @name lastName - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.last_name, - }, - groups: { - /** - * @name groups - * @type {string[]} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => JSON.parse(JSON.stringify(data.groups)), - }, - lastLogin: { - /** - * @name lastLogin - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.last_login, - }, - dateJoined: { - /** - * @name dateJoined - * @type {string} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.date_joined, - }, - isStaff: { - /** - * @name isStaff - * @type {boolean} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.is_staff, - }, - isSuperuser: { - /** - * @name isSuperuser - * @type {boolean} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.is_superuser, - }, - isActive: { - /** - * @name isActive - * @type {boolean} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => data.is_active, - }, - isVerified: { - /** - * @name isVerified - * @type {boolean} - * @memberof module:API.cvat.classes.User - * @readonly - * @instance - */ - get: () => !data.email_verification_required, - }, - })); + Object.defineProperties( + this, + Object.freeze({ + id: { + /** + * @name id + * @type {integer} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.id, + }, + username: { + /** + * @name username + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.username, + }, + email: { + /** + * @name email + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.email, + }, + firstName: { + /** + * @name firstName + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.first_name, + }, + lastName: { + /** + * @name lastName + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.last_name, + }, + groups: { + /** + * @name groups + * @type {string[]} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => JSON.parse(JSON.stringify(data.groups)), + }, + lastLogin: { + /** + * @name lastLogin + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.last_login, + }, + dateJoined: { + /** + * @name dateJoined + * @type {string} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.date_joined, + }, + isStaff: { + /** + * @name isStaff + * @type {boolean} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.is_staff, + }, + isSuperuser: { + /** + * @name isSuperuser + * @type {boolean} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.is_superuser, + }, + isActive: { + /** + * @name isActive + * @type {boolean} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => data.is_active, + }, + isVerified: { + /** + * @name isVerified + * @type {boolean} + * @memberof module:API.cvat.classes.User + * @readonly + * @instance + */ + get: () => !data.email_verification_required, + }, + }), + ); + } + + serialize() { + return { + id: this.id, + username: this.username, + email: this.email, + first_name: this.firstName, + last_name: this.lastName, + groups: this.groups, + last_login: this.lastLogin, + date_joined: this.dateJoined, + is_staff: this.isStaff, + is_superuser: this.isSuperuser, + is_active: this.isActive, + email_verification_required: this.isVerified, + }; + } + + toJSON() { + return this.serialize(); } } diff --git a/cvat-core/tests/api/annotations.js b/cvat-core/tests/api/annotations.js index fca42dd3..b7a44a43 100644 --- a/cvat-core/tests/api/annotations.js +++ b/cvat-core/tests/api/annotations.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018-2020 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -48,30 +41,25 @@ describe('Feature: get annotations', () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; // Out of task - expect(task.annotations.get(500)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.get(500)).rejects.toThrow(window.cvat.exceptions.ArgumentError); // Out of task - expect(task.annotations.get(-1)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.get(-1)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get annotations for frame out of job', async () => { const job = (await window.cvat.jobs.get({ jobID: 101 }))[0]; // Out of segment - expect(job.annotations.get(500)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(job.annotations.get(500)).rejects.toThrow(window.cvat.exceptions.ArgumentError); // Out of segment - expect(job.annotations.get(-1)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(job.annotations.get(-1)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); // TODO: Test filter (hasn't been implemented yet) }); - describe('Feature: put annotations', () => { test('put a shape to a task', async () => { const task = (await window.cvat.tasks.get({ id: 101 }))[0]; @@ -173,8 +161,7 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape with bad attributes to a task', async () => { @@ -191,8 +178,7 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape with bad zOrder to a task', async () => { @@ -209,8 +195,7 @@ describe('Feature: put annotations', () => { zOrder: 'bad value', }); - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); const state1 = new window.cvat.classes.ObjectState({ frame: 1, @@ -223,8 +208,7 @@ describe('Feature: put annotations', () => { zOrder: NaN, }); - expect(task.annotations.put([state1])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state1])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape without points and with invalud points to a task', async () => { @@ -240,16 +224,13 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - await expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.DataError); + await expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.DataError); delete state.points; - await expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.DataError); + await expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.DataError); state.points = ['150,50 250,30']; - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape without type to a task', async () => { @@ -264,8 +245,7 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape without label and with bad label to a task', async () => { @@ -280,16 +260,13 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - await expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.label = 'bad label'; - await expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.label = {}; - await expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('put shape with bad frame to a task', async () => { @@ -305,8 +282,7 @@ describe('Feature: put annotations', () => { zOrder: 0, }); - expect(task.annotations.put([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.put([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); @@ -436,8 +412,7 @@ describe('Feature: save annotations', () => { // have been sent to a server const oldImplementation = serverProxy.annotations.updateAnnotations; serverProxy.annotations.updateAnnotations = async (session, id, data, action) => { - const result = await oldImplementation - .call(serverProxy.annotations, session, id, data, action); + const result = await oldImplementation.call(serverProxy.annotations, session, id, data, action); if (action === 'delete') { okay = okay || (action === 'delete' && !!(data.shapes.length || data.tracks.length)); } @@ -459,10 +434,12 @@ describe('Feature: merge annotations', () => { const annotations1 = await task.annotations.get(1); const states = [annotations0[0], annotations1[0]]; await task.annotations.merge(states); - const merged0 = (await task.annotations.get(0)) - .filter((state) => state.objectType === window.cvat.enums.ObjectType.TRACK); - const merged1 = (await task.annotations.get(1)) - .filter((state) => state.objectType === window.cvat.enums.ObjectType.TRACK); + const merged0 = (await task.annotations.get(0)).filter( + (state) => state.objectType === window.cvat.enums.ObjectType.TRACK, + ); + const merged1 = (await task.annotations.get(1)).filter( + (state) => state.objectType === window.cvat.enums.ObjectType.TRACK, + ); expect(merged0).toHaveLength(1); expect(merged1).toHaveLength(1); @@ -476,10 +453,12 @@ describe('Feature: merge annotations', () => { const annotations1 = await job.annotations.get(1); const states = [annotations0[0], annotations1[0]]; await job.annotations.merge(states); - const merged0 = (await job.annotations.get(0)) - .filter((state) => state.objectType === window.cvat.enums.ObjectType.TRACK); - const merged1 = (await job.annotations.get(1)) - .filter((state) => state.objectType === window.cvat.enums.ObjectType.TRACK); + const merged0 = (await job.annotations.get(0)).filter( + (state) => state.objectType === window.cvat.enums.ObjectType.TRACK, + ); + const merged1 = (await job.annotations.get(1)).filter( + (state) => state.objectType === window.cvat.enums.ObjectType.TRACK, + ); expect(merged0).toHaveLength(1); expect(merged1).toHaveLength(1); @@ -492,8 +471,7 @@ describe('Feature: merge annotations', () => { const annotations0 = await task.annotations.get(0); const states = [annotations0[0], {}]; - expect(task.annotations.merge(states)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.merge(states)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to merge object state which is not saved in a collection', async () => { @@ -510,8 +488,7 @@ describe('Feature: merge annotations', () => { }); const states = [annotations0[0], state]; - expect(task.annotations.merge(states)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.merge(states)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to merge with bad label', async () => { @@ -525,19 +502,18 @@ describe('Feature: merge annotations', () => { attributes: [], }); - expect(task.annotations.merge(states)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.merge(states)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to merge with different shape types', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const annotations0 = await task.annotations.get(0); - const annotations1 = (await task.annotations.get(1)) - .filter((state) => state.shapeType === window.cvat.enums.ObjectShape.POLYGON); + const annotations1 = (await task.annotations.get(1)).filter( + (state) => state.shapeType === window.cvat.enums.ObjectShape.POLYGON, + ); const states = [annotations0[0], annotations1[0]]; - expect(task.annotations.merge(states)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.merge(states)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to merge with different labels', async () => { @@ -551,8 +527,7 @@ describe('Feature: merge annotations', () => { attributes: [], }); - expect(task.annotations.merge(states)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.merge(states)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); @@ -587,8 +562,9 @@ describe('Feature: split annotations', () => { const annotations5 = await task.annotations.get(5); expect(annotations4[0].clientID).toBe(annotations5[0].clientID); - expect(task.annotations.split(annotations5[0], 'bad frame')) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.split(annotations5[0], 'bad frame')).rejects.toThrow( + window.cvat.exceptions.ArgumentError, + ); }); }); @@ -597,7 +573,7 @@ describe('Feature: group annotations', () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; let annotations = await task.annotations.get(0); const groupID = await task.annotations.group(annotations); - expect(typeof (groupID)).toBe('number'); + expect(typeof groupID).toBe('number'); annotations = await task.annotations.get(0); for (const state of annotations) { expect(state.group.id).toBe(groupID); @@ -608,7 +584,7 @@ describe('Feature: group annotations', () => { const job = (await window.cvat.jobs.get({ jobID: 100 }))[0]; let annotations = await job.annotations.get(0); const groupID = await job.annotations.group(annotations); - expect(typeof (groupID)).toBe('number'); + expect(typeof groupID).toBe('number'); annotations = await job.annotations.get(0); for (const state of annotations) { expect(state.group.id).toBe(groupID); @@ -629,15 +605,13 @@ describe('Feature: group annotations', () => { zOrder: 0, }); - expect(task.annotations.group([state])) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.group([state])).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to group not object state', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const annotations = await task.annotations.get(0); - expect(task.annotations.group(annotations.concat({}))) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.group(annotations.concat({}))).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); @@ -689,8 +663,7 @@ describe('Feature: clear annotations', () => { test('clear annotations with bad reload parameter', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; await task.annotations.clear(true); - expect(task.annotations.clear('reload')) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.clear('reload')).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); @@ -752,18 +725,16 @@ describe('Feature: select object', () => { test('trying to select from not object states', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const annotations = await task.annotations.get(0); - expect(task.annotations.select(annotations.concat({}), 500, 500)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.select(annotations.concat({}), 500, 500)).rejects.toThrow( + window.cvat.exceptions.ArgumentError, + ); }); test('trying to select with invalid coordinates', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const annotations = await task.annotations.get(0); - expect(task.annotations.select(annotations, null, null)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); - expect(task.annotations.select(annotations, null, null)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); - expect(task.annotations.select(annotations, '5', '10')) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.select(annotations, null, null)).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.select(annotations, null, null)).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.annotations.select(annotations, '5', '10')).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); diff --git a/cvat-core/tests/api/frames.js b/cvat-core/tests/api/frames.js index 6e778b22..b70e3e83 100644 --- a/cvat-core/tests/api/frames.js +++ b/cvat-core/tests/api/frames.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -35,22 +28,18 @@ describe('Feature: get frame meta', () => { test('pass frame number out of a task', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; - expect(task.frames.get(100)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); - expect(task.frames.get(-1)) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.frames.get(100)).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.frames.get(-1)).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('pass bad frame number', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; - expect(task.frames.get('5')) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.frames.get('5')).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('do not pass any frame number', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; - expect(task.frames.get()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect(task.frames.get()).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); @@ -59,14 +48,14 @@ describe('Feature: get frame data', () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const frame = await task.frames.get(0); const frameData = await frame.data(); - expect(typeof (frameData)).toBe('string'); + expect(typeof frameData).toBe('string'); }); test('get frame data for a job', async () => { const job = (await window.cvat.jobs.get({ jobID: 100 }))[0]; const frame = await job.frames.get(0); const frameData = await frame.data(); - expect(typeof (frameData)).toBe('string'); + expect(typeof frameData).toBe('string'); }); }); @@ -74,12 +63,12 @@ describe('Feature: get frame preview', () => { test('get frame preview for a task', async () => { const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const frame = await task.frames.preview(); - expect(typeof (frame)).toBe('string'); + expect(typeof frame).toBe('string'); }); test('get frame preview for a job', async () => { const job = (await window.cvat.jobs.get({ jobID: 100 }))[0]; const frame = await job.frames.preview(); - expect(typeof (frame)).toBe('string'); + expect(typeof frame).toBe('string'); }); }); diff --git a/cvat-core/tests/api/jobs.js b/cvat-core/tests/api/jobs.js index 2a68c415..5cbe97ff 100644 --- a/cvat-core/tests/api/jobs.js +++ b/cvat-core/tests/api/jobs.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -20,7 +13,6 @@ window.cvat = require('../../src/api'); const { Job } = require('../../src/session'); - // Test cases describe('Feature: get a list of jobs', () => { test('get jobs by a task id', async () => { @@ -45,7 +37,6 @@ describe('Feature: get a list of jobs', () => { expect(result).toHaveLength(0); }); - test('get jobs by a job id', async () => { const result = await window.cvat.jobs.get({ jobID: 1, @@ -64,32 +55,39 @@ describe('Feature: get a list of jobs', () => { }); test('get jobs by invalid filter with both taskID and jobID', async () => { - expect(window.cvat.jobs.get({ - taskID: 1, - jobID: 1, - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.jobs.get({ + taskID: 1, + jobID: 1, + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get jobs by invalid job id', async () => { - expect(window.cvat.jobs.get({ - jobID: '1', - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.jobs.get({ + jobID: '1', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get jobs by invalid task id', async () => { - expect(window.cvat.jobs.get({ - taskID: '1', - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.jobs.get({ + taskID: '1', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get jobs by unknown filter', async () => { - expect(window.cvat.jobs.get({ - unknown: 50, - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.jobs.get({ + unknown: 50, + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); - describe('Feature: save job', () => { test('save status of a job', async () => { let result = await window.cvat.jobs.get({ diff --git a/cvat-core/tests/api/object-state.js b/cvat-core/tests/api/object-state.js index 92a6c815..ef6e1f5f 100644 --- a/cvat-core/tests/api/object-state.js +++ b/cvat-core/tests/api/object-state.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -168,30 +161,25 @@ describe('Feature: save object from its state', () => { const state = annotations[0]; state.occluded = 'false'; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); const oldPoints = state.points; state.occluded = false; state.points = ['100', '50', '100', {}]; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.points = oldPoints; state.lock = 'true'; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); const oldLabel = state.label; state.lock = false; state.label = 1; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.label = oldLabel; state.attributes = { 1: {}, 2: false, 3: () => {} }; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('save bad values for a track', async () => { @@ -200,40 +188,33 @@ describe('Feature: save object from its state', () => { const state = annotations[0]; state.occluded = 'false'; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); const oldPoints = state.points; state.occluded = false; state.points = ['100', '50', '100', {}]; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.points = oldPoints; state.lock = 'true'; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); const oldLabel = state.label; state.lock = false; state.label = 1; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.label = oldLabel; state.outside = 5; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.outside = false; state.keyframe = '10'; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); state.keyframe = true; state.attributes = { 1: {}, 2: false, 3: () => {} }; - await expect(state.save()) - .rejects.toThrow(window.cvat.exceptions.ArgumentError); + await expect(state.save()).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('trying to change locked shape', async () => { diff --git a/cvat-core/tests/api/plugins.js b/cvat-core/tests/api/plugins.js index 2db3cdd5..7540bef0 100644 --- a/cvat-core/tests/api/plugins.js +++ b/cvat-core/tests/api/plugins.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { diff --git a/cvat-core/tests/api/projects.js b/cvat-core/tests/api/projects.js new file mode 100644 index 00000000..5c137430 --- /dev/null +++ b/cvat-core/tests/api/projects.js @@ -0,0 +1,170 @@ +// Copyright (C) 2019-2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +// Setup mock for a server +jest.mock('../../src/server-proxy', () => { + const mock = require('../mocks/server-proxy.mock'); + return mock; +}); + +// Initialize api +window.cvat = require('../../src/api'); + +const { Task } = require('../../src/session'); +const { Project } = require('../../src/project'); + +describe('Feature: get projects', () => { + test('get all projects', async () => { + const result = await window.cvat.projects.get(); + expect(Array.isArray(result)).toBeTruthy(); + expect(result).toHaveLength(2); + for (const el of result) { + expect(el).toBeInstanceOf(Project); + } + }); + + test('get project by id', async () => { + const result = await window.cvat.projects.get({ + id: 2, + }); + + expect(Array.isArray(result)).toBeTruthy(); + expect(result).toHaveLength(1); + expect(result[0]).toBeInstanceOf(Project); + expect(result[0].id).toBe(2); + expect(result[0].tasks).toHaveLength(1); + expect(result[0].tasks[0]).toBeInstanceOf(Task); + }); + + test('get a project by an unknown id', async () => { + const result = await window.cvat.projects.get({ + id: 1, + }); + expect(Array.isArray(result)).toBeTruthy(); + expect(result).toHaveLength(0); + }); + + test('get a project by an invalid id', async () => { + expect( + window.cvat.projects.get({ + id: '1', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); + }); + + test('get projects by filters', async () => { + const result = await window.cvat.projects.get({ + status: 'completed', + }); + expect(Array.isArray(result)).toBeTruthy(); + expect(result).toHaveLength(1); + expect(result[0]).toBeInstanceOf(Project); + expect(result[0].id).toBe(2); + expect(result[0].status).toBe('completed'); + }); + + test('get projects by invalid filters', async () => { + expect( + window.cvat.projects.get({ + unknown: '5', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); + }); +}); + +describe('Feature: save a project', () => { + test('save some changed fields in a project', async () => { + let result = await window.cvat.tasks.get({ + id: 2, + }); + + result[0].bugTracker = 'newBugTracker'; + result[0].name = 'New Project Name'; + + result[0].save(); + + result = await window.cvat.tasks.get({ + id: 2, + }); + + expect(result[0].bugTracker).toBe('newBugTracker'); + expect(result[0].name).toBe('New Project Name'); + }); + + test('save some new labels in a project', async () => { + let result = await window.cvat.projects.get({ + id: 6, + }); + + const labelsLength = result[0].labels.length; + const newLabel = new window.cvat.classes.Label({ + name: "My boss's car", + attributes: [ + { + default_value: 'false', + input_type: 'checkbox', + mutable: true, + name: 'parked', + values: ['false'], + }, + ], + }); + + result[0].labels = [...result[0].labels, newLabel]; + result[0].save(); + + result = await window.cvat.projects.get({ + id: 6, + }); + + expect(result[0].labels).toHaveLength(labelsLength + 1); + const appendedLabel = result[0].labels.filter((el) => el.name === "My boss's car"); + expect(appendedLabel).toHaveLength(1); + expect(appendedLabel[0].attributes).toHaveLength(1); + expect(appendedLabel[0].attributes[0].name).toBe('parked'); + expect(appendedLabel[0].attributes[0].defaultValue).toBe('false'); + expect(appendedLabel[0].attributes[0].mutable).toBe(true); + expect(appendedLabel[0].attributes[0].inputType).toBe('checkbox'); + }); + + test('save new project without an id', async () => { + const project = new window.cvat.classes.Project({ + name: 'New Empty Project', + labels: [ + { + name: 'car', + attributes: [ + { + default_value: 'false', + input_type: 'checkbox', + mutable: true, + name: 'parked', + values: ['false'], + }, + ], + }, + ], + bug_tracker: 'bug tracker value', + }); + + const result = await project.save(); + expect(typeof result.id).toBe('number'); + }); +}); + +describe('Feature: delete a project', () => { + test('delete a project', async () => { + let result = await window.cvat.projects.get({ + id: 6, + }); + + await result[0].delete(); + result = await window.cvat.projects.get({ + id: 6, + }); + + expect(Array.isArray(result)).toBeTruthy(); + expect(result).toHaveLength(0); + }); +}); diff --git a/cvat-core/tests/api/server.js b/cvat-core/tests/api/server.js index 80fb8868..1fa607b0 100644 --- a/cvat-core/tests/api/server.js +++ b/cvat-core/tests/api/server.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -17,11 +10,7 @@ jest.mock('../../src/server-proxy', () => { // Initialize api window.cvat = require('../../src/api'); -const { - AnnotationFormats, - Loader, - Dumper, -} = require('../../src/annotation-formats'); +const { AnnotationFormats, Loader, Dumper } = require('../../src/annotation-formats'); // Test cases describe('Feature: get info about cvat', () => { @@ -34,7 +23,6 @@ describe('Feature: get info about cvat', () => { }); }); - describe('Feature: get share storage info', () => { test('get files in a root of a share storage', async () => { const result = await window.cvat.server.share(); @@ -49,9 +37,7 @@ describe('Feature: get share storage info', () => { }); test('get files in a some unknown dir of a share storage', async () => { - expect(window.cvat.server.share( - 'Unknown Directory', - )).rejects.toThrow(window.cvat.exceptions.ServerError); + expect(window.cvat.server.share('Unknown Directory')).rejects.toThrow(window.cvat.exceptions.ServerError); }); }); @@ -84,4 +70,4 @@ describe('Feature: get annotation dumpers', () => { expect(dumper).toBeInstanceOf(Dumper); } }); -}); \ No newline at end of file +}); diff --git a/cvat-core/tests/api/tasks.js b/cvat-core/tests/api/tasks.js index 627bf7e8..c309b415 100644 --- a/cvat-core/tests/api/tasks.js +++ b/cvat-core/tests/api/tasks.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -20,7 +13,6 @@ window.cvat = require('../../src/api'); const { Task } = require('../../src/session'); - // Test cases describe('Feature: get a list of tasks', () => { test('get all tasks', async () => { @@ -51,9 +43,11 @@ describe('Feature: get a list of tasks', () => { }); test('get a task by an invalid id', async () => { - expect(window.cvat.tasks.get({ - id: '50', - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.tasks.get({ + id: '50', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get tasks by filters', async () => { @@ -69,9 +63,11 @@ describe('Feature: get a list of tasks', () => { }); test('get tasks by invalid filters', async () => { - expect(window.cvat.tasks.get({ - unknown: '5', - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.tasks.get({ + unknown: '5', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get task by name, status and mode', async () => { @@ -98,7 +94,6 @@ describe('Feature: save a task', () => { }); result[0].bugTracker = 'newBugTracker'; - result[0].zOrder = true; result[0].name = 'New Task Name'; result[0].save(); @@ -108,7 +103,6 @@ describe('Feature: save a task', () => { }); expect(result[0].bugTracker).toBe('newBugTracker'); - expect(result[0].zOrder).toBe(true); expect(result[0].name).toBe('New Task Name'); }); @@ -119,14 +113,16 @@ describe('Feature: save a task', () => { const labelsLength = result[0].labels.length; const newLabel = new window.cvat.classes.Label({ - name: 'My boss\'s car', - attributes: [{ - default_value: 'false', - input_type: 'checkbox', - mutable: true, - name: 'parked', - values: ['false'], - }], + name: "My boss's car", + attributes: [ + { + default_value: 'false', + input_type: 'checkbox', + mutable: true, + name: 'parked', + values: ['false'], + }, + ], }); result[0].labels = [...result[0].labels, newLabel]; @@ -137,7 +133,7 @@ describe('Feature: save a task', () => { }); expect(result[0].labels).toHaveLength(labelsLength + 1); - const appendedLabel = result[0].labels.filter((el) => el.name === 'My boss\'s car'); + const appendedLabel = result[0].labels.filter((el) => el.name === "My boss's car"); expect(appendedLabel).toHaveLength(1); expect(appendedLabel[0].attributes).toHaveLength(1); expect(appendedLabel[0].attributes[0].name).toBe('parked'); @@ -149,23 +145,39 @@ describe('Feature: save a task', () => { test('save new task without an id', async () => { const task = new window.cvat.classes.Task({ name: 'New Task', - labels: [{ - name: 'My boss\'s car', - attributes: [{ - default_value: 'false', - input_type: 'checkbox', - mutable: true, - name: 'parked', - values: ['false'], - }], - }], + labels: [ + { + name: "My boss's car", + attributes: [ + { + default_value: 'false', + input_type: 'checkbox', + mutable: true, + name: 'parked', + values: ['false'], + }, + ], + }, + ], + bug_tracker: 'bug tracker value', + image_quality: 50, + }); + + const result = await task.save(); + expect(typeof result.id).toBe('number'); + }); + + test('save new task in project', async () => { + const task = new window.cvat.classes.Task({ + name: 'New Task', + project_id: 2, bug_tracker: 'bug tracker value', image_quality: 50, z_order: true, }); const result = await task.save(); - expect(typeof (result.id)).toBe('number'); + expect(result.projectId).toBe(2); }); }); diff --git a/cvat-core/tests/api/user.js b/cvat-core/tests/api/user.js index 9d6765dc..27fe5814 100644 --- a/cvat-core/tests/api/user.js +++ b/cvat-core/tests/api/user.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -41,14 +34,18 @@ describe('Feature: get a list of users', () => { }); test('get users with unknown filter key', async () => { - expect(window.cvat.users.get({ - unknown: '50', - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.users.get({ + unknown: '50', + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); test('get users with invalid filter key', async () => { - expect(window.cvat.users.get({ - self: 1, - })).rejects.toThrow(window.cvat.exceptions.ArgumentError); + expect( + window.cvat.users.get({ + self: 1, + }), + ).rejects.toThrow(window.cvat.exceptions.ArgumentError); }); }); diff --git a/cvat-core/tests/internal/filter.js b/cvat-core/tests/internal/filter.js index 97336c43..d292f2a2 100644 --- a/cvat-core/tests/internal/filter.js +++ b/cvat-core/tests/internal/filter.js @@ -1,13 +1,6 @@ -/* - * Copyright (C) 2018-2020 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* global - require:false - jest:false - describe:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT // Setup mock for a server jest.mock('../../src/server-proxy', () => { @@ -25,7 +18,7 @@ describe('Feature: toJSONQuery', () => { const annotationsFilter = new AnnotationsFilter(); const [groups, query] = annotationsFilter.toJSONQuery([]); expect(Array.isArray(groups)).toBeTruthy(); - expect(typeof (query)).toBe('string'); + expect(typeof query).toBe('string'); }); test('convert empty fitlers to a json query', () => { @@ -64,61 +57,65 @@ describe('Feature: toJSONQuery', () => { test('convert filters to a json query', () => { const annotationsFilter = new AnnotationsFilter(); - const [groups, query] = annotationsFilter - .toJSONQuery(['clientID==5 & shape=="rectangle" & label==["car"]']); - expect(groups).toEqual([ - ['clientID==5', '&', 'shape=="rectangle"', '&', 'label==["car"]'], - ]); + const [groups, query] = annotationsFilter.toJSONQuery(['clientID==5 & shape=="rectangle" & label==["car"]']); + expect(groups).toEqual([['clientID==5', '&', 'shape=="rectangle"', '&', 'label==["car"]']]); expect(query).toBe('$.objects[?((@.clientID==5&@.shape=="rectangle"&@.label==["car"]))].clientID'); }); test('convert filters to a json query', () => { const annotationsFilter = new AnnotationsFilter(); - const [groups, query] = annotationsFilter - .toJSONQuery(['label=="car" | width >= height & type=="track"']); - expect(groups).toEqual([ - ['label=="car"', '|', 'width >= height', '&', 'type=="track"'], - ]); + const [groups, query] = annotationsFilter.toJSONQuery(['label=="car" | width >= height & type=="track"']); + expect(groups).toEqual([['label=="car"', '|', 'width >= height', '&', 'type=="track"']]); expect(query).toBe('$.objects[?((@.label=="car"|@.width>=@.height&@.type=="track"))].clientID'); }); test('convert filters to a json query', () => { const annotationsFilter = new AnnotationsFilter(); - const [groups, query] = annotationsFilter - .toJSONQuery(['label=="person" & attr["Attribute 1"] ==attr["Attribute 2"]']); - expect(groups).toEqual([ - ['label=="person"', '&', 'attr["Attribute 1"] ==attr["Attribute 2"]'], + const [groups, query] = annotationsFilter.toJSONQuery([ + 'label=="person" & attr["Attribute 1"] ==attr["Attribute 2"]', ]); + expect(groups).toEqual([['label=="person"', '&', 'attr["Attribute 1"] ==attr["Attribute 2"]']]); expect(query).toBe('$.objects[?((@.label=="person"&@.attr["Attribute 1"]==@.attr["Attribute 2"]))].clientID'); }); test('convert filters to a json query', () => { const annotationsFilter = new AnnotationsFilter(); - const [groups, query] = annotationsFilter - .toJSONQuery(['label=="car" & attr["parked"]==true', 'label=="pedestrian" & width > 150']); + const [groups, query] = annotationsFilter.toJSONQuery([ + 'label=="car" & attr["parked"]==true', + 'label=="pedestrian" & width > 150', + ]); expect(groups).toEqual([ ['label=="car"', '&', 'attr["parked"]==true'], '|', ['label=="pedestrian"', '&', 'width > 150'], ]); - expect(query).toBe('$.objects[?((@.label=="car"&@.attr["parked"]==true)|(@.label=="pedestrian"&@.width>150))].clientID'); + expect(query).toBe( + '$.objects[?((@.label=="car"&@.attr["parked"]==true)|(@.label=="pedestrian"&@.width>150))].clientID', + ); }); test('convert filters to a json query', () => { const annotationsFilter = new AnnotationsFilter(); - const [groups, query] = annotationsFilter - .toJSONQuery(['(( label==["car \\"mazda\\""]) & (attr["sunglass ( help ) es"]==true | (width > 150 | height > 150 & (clientID == serverID))))) ']); - expect(groups).toEqual([[[ - ['label==["car `mazda`"]'], - '&', - ['attr["sunglass ( help ) es"]==true', '|', - ['width > 150', '|', 'height > 150', '&', + const [groups, query] = annotationsFilter.toJSONQuery([ + // eslint-disable-next-line + '(( label==["car \\"mazda\\""]) & (attr["sunglass ( help ) es"]==true | (width > 150 | height > 150 & (clientID == serverID))))) ', + ]); + expect(groups).toEqual([ + [ + [ + ['label==["car `mazda`"]'], + '&', [ - 'clientID == serverID', + 'attr["sunglass ( help ) es"]==true', + '|', + ['width > 150', '|', 'height > 150', '&', ['clientID == serverID']], ], ], ], - ]]]); - expect(query).toBe('$.objects[?((((@.label==["car `mazda`"])&(@.attr["sunglass ( help ) es"]==true|(@.width>150|@.height>150&(@.clientID==serverID))))))].clientID'); + ]); + expect(query).toBe( + // eslint-disable-next-line + '$.objects[?((((@.label==["car `mazda`"])&(@.attr["sunglass ( help ) es"]==true|(@.width>150|@.height>150&(@.clientID==serverID))))))].clientID', + ); }); }); diff --git a/cvat-core/tests/mocks/dummy-data.mock.js b/cvat-core/tests/mocks/dummy-data.mock.js index dd688e14..33a3c500 100644 --- a/cvat-core/tests/mocks/dummy-data.mock.js +++ b/cvat-core/tests/mocks/dummy-data.mock.js @@ -1,2643 +1,2548 @@ /* eslint-disable */ const aboutDummyData = { - "name": "Computer Vision Annotation Tool", - "description": "CVAT is completely re-designed and re-implemented version of Video Annotation Tool from Irvine, California tool. It is free, online, interactive video and image annotation tool for computer vision. It is being used by our team to annotate million of objects with different properties. Many UI and UX decisions are based on feedbacks from professional data annotation team.", - "version": "0.5.dev20190516142240" -} + name: 'Computer Vision Annotation Tool', + description: + 'CVAT is completely re-designed and re-implemented version of Video Annotation Tool from Irvine, California tool. It is free, online, interactive video and image annotation tool for computer vision. It is being used by our team to annotate million of objects with different properties. Many UI and UX decisions are based on feedbacks from professional data annotation team.', + version: '0.5.dev20190516142240', +}; const formatsDummyData = { - "exporters": [ + exporters: [ { - "name": "CVAT for video 1.1", - "ext": "XML", - "version": "1.1", + name: 'CVAT for video 1.1', + ext: 'XML', + version: '1.1', }, { - "name": "CVAT for images 1.1", - "ext": "XML", - "version": "1.1", + name: 'CVAT for images 1.1', + ext: 'XML', + version: '1.1', }, { - "name": "PASCAL VOC 1.0", - "ext": "ZIP", - "version": "1.0", + name: 'PASCAL VOC 1.0', + ext: 'ZIP', + version: '1.0', }, { - "name": "YOLO 1.0", - "ext": "ZIP", - "version": "1.0", + name: 'YOLO 1.0', + ext: 'ZIP', + version: '1.0', }, ], - "importers": [ + importers: [ { - "name": "CVAT 1.1", - "ext": "XML, ZIP", - "version": "1.1", + name: 'CVAT 1.1', + ext: 'XML, ZIP', + version: '1.1', }, { - "name": "PASCAL VOC 1.0", - "ext": "ZIP", - "version": "1.0", + name: 'PASCAL VOC 1.0', + ext: 'ZIP', + version: '1.0', }, { - "name": "MYFORMAT 1.0", - "ext": "TXT", - "version": "1.0", - } + name: 'MYFORMAT 1.0', + ext: 'TXT', + version: '1.0', + }, ], }; const usersDummyData = { - "count": 2, - "next": null, - "previous": null, - "results": [ + count: 2, + next: null, + previous: null, + results: [ { - "url": "http://localhost:7000/api/v1/users/1", - "id": 1, - "username": "admin", - "first_name": "", - "last_name": "", - "email": "admin@dummy.com", - "groups": [ - "admin" - ], - "is_staff": true, - "is_superuser": true, - "is_active": true, - "last_login": "2019-05-17T11:53:05.961434+03:00", - "date_joined": "2019-05-13T15:33:17.833200+03:00" + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + first_name: '', + last_name: '', + email: 'admin@dummy.com', + groups: ['admin'], + is_staff: true, + is_superuser: true, + is_active: true, + last_login: '2019-05-17T11:53:05.961434+03:00', + date_joined: '2019-05-13T15:33:17.833200+03:00', }, { - "url": "http://localhost:7000/api/v1/users/2", - "id": 2, - "username": "bsekache", - "first_name": "", - "last_name": "", - "email": "", - "groups": [ - "user", - "observer" - ], - "is_staff": false, - "is_superuser": false, - "is_active": true, - "last_login": "2019-05-16T13:07:19.564241+03:00", - "date_joined": "2019-05-16T13:05:57+03:00" - } - ] -} + url: 'http://localhost:7000/api/v1/users/2', + id: 2, + username: 'bsekache', + first_name: '', + last_name: '', + email: '', + groups: ['user', 'observer'], + is_staff: false, + is_superuser: false, + is_active: true, + last_login: '2019-05-16T13:07:19.564241+03:00', + date_joined: '2019-05-16T13:05:57+03:00', + }, + ], +}; const shareDummyData = [ { - "name": "images", - "type": "DIR", - "children": [ + name: 'images', + type: 'DIR', + children: [ { - "name": "image000001.jpg", - "type": "REG" + name: 'image000001.jpg', + type: 'REG', }, { - "name": "nowy-jork-time-sqare.jpg", - "type": "REG" + name: 'nowy-jork-time-sqare.jpg', + type: 'REG', }, { - "name": "123123.jpg", - "type": "REG" + name: '123123.jpg', + type: 'REG', }, { - "name": "ws_Oasis-night_1920x1200.jpg", - "type": "REG" + name: 'ws_Oasis-night_1920x1200.jpg', + type: 'REG', }, { - "name": "image000002.jpg", - "type": "REG" + name: 'image000002.jpg', + type: 'REG', }, { - "name": "fdgdfgfd.jpg", - "type": "REG" + name: 'fdgdfgfd.jpg', + type: 'REG', }, { - "name": "bbbbb.jpg", - "type": "REG" + name: 'bbbbb.jpg', + type: 'REG', }, { - "name": "gdfgdfgdf.jpg", - "type": "REG" - } - ] + name: 'gdfgdfgdf.jpg', + type: 'REG', + }, + ], }, { - "name": "2.avi", - "type": "REG" + name: '2.avi', + type: 'REG', }, { - "name": "data", - "type": "DIR", - "children": [], + name: 'data', + type: 'DIR', + children: [], }, { - "name": "out.MOV", - "type": "REG" + name: 'out.MOV', + type: 'REG', }, { - "name": "bbbbb.jpg", - "type": "REG" - } -] + name: 'bbbbb.jpg', + type: 'REG', + }, +]; -const tasksDummyData = { - "count": 5, - "next": null, - "previous": null, - "results": [ +const projectsDummyData = { + count: 2, + next: null, + previous: null, + results: [ { - "url": "http://localhost:7000/api/v1/tasks/102", - "id": 102, - "name": "Test", - "size": 1, - "mode": "annotation", - "owner": 1, - "assignee": null, - "bug_tracker": "", - "created_date": "2019-09-05T11:59:22.987942Z", - "updated_date": "2019-09-05T14:04:07.569344Z", - "overlap": 0, - "segment_size": 0, - "z_order": false, - "status": "annotation", - "labels": [{ - "id": 5, - "name": "car", - "attributes": [] - }], - "segments": [{ - "start_frame": 0, - "stop_frame": 0, - "jobs": [{ - "url":"http://localhost:7000/api/v1/jobs/112", - "id": 112, - "assignee":null, - "status":"annotation" - }] - }], - "image_quality": 50, - "start_frame": 0, - "stop_frame": 0, - "frame_filter": "" - }, { - "url": "http://localhost:7000/api/v1/tasks/100", - "id": 100, - "name": "Image Task", - "size": 9, - "mode": "annotation", - "owner": 1, - "assignee": null, - "bug_tracker": "", - "created_date": "2019-06-18T13:05:08.941304+03:00", - "updated_date": "2019-07-16T15:51:29.142871+03:00", - "overlap": 0, - "segment_size": 0, - "z_order": false, - "status": "annotation", - "labels": [ - { - "id": 1, - "name": "car,", - "attributes": [ - - ] - }, - { - "id": 2, - "name": "person", - "attributes": [ + url: 'http://192.168.0.139:7000/api/v1/projects/6', + id: 6, + name: 'Some empty project', + labels: [], + tasks: [], + owner: { + url: 'http://localhost:7000/api/v1/users/2', + id: 2, + username: 'bsekache', + }, + assignee: { + url: 'http://localhost:7000/api/v1/users/2', + id: 2, + username: 'bsekache', + }, + bug_tracker: '', + created_date: '2020-10-19T20:41:07.808029Z', + updated_date: '2020-10-19T20:41:07.808084Z', + status: 'annotation', + }, + { + url: 'http://192.168.0.139:7000/api/v1/projects/1', + id: 2, + name: 'Test project with roads', + labels: [ + { + id: 1, + name: 'car', + color: '#2080c0', + attributes: [ + { + id: 199, + name: 'color', + mutable: false, + input_type: 'select', + default_value: 'red', + values: ['red', 'black', 'white', 'yellow', 'pink', 'green', 'blue', 'orange'], + }, + ], + }, + ], + tasks: [ + { + url: 'http://192.168.0.139:7000/api/v1/tasks/2', + id: 2, + name: 'road 1', + project_id: 1, + mode: 'interpolation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2020-10-12T08:59:59.878083Z', + updated_date: '2020-10-18T21:02:20.831294Z', + overlap: 5, + segment_size: 100, + z_order: false, + status: 'completed', + labels: [ + { + id: 1, + name: 'car', + color: '#2080c0', + attributes: [ + { + id: 199, + name: 'color', + mutable: false, + input_type: 'select', + default_value: 'red', + values: ['red', 'black', 'white', 'yellow', 'pink', 'green', 'blue', 'orange'], + }, + ], + }, + ], + segments: [ + { + start_frame: 0, + stop_frame: 99, + jobs: [ + { + url: 'http://192.168.0.139:7000/api/v1/jobs/1', + id: 1, + assignee: null, + reviewer: null, + status: 'completed', + }, + ], + }, + { + start_frame: 95, + stop_frame: 194, + jobs: [ + { + url: 'http://192.168.0.139:7000/api/v1/jobs/2', + id: 2, + assignee: null, + reviewer: null, + status: 'completed', + }, + ], + }, + { + start_frame: 190, + stop_frame: 289, + jobs: [ + { + url: 'http://192.168.0.139:7000/api/v1/jobs/3', + id: 3, + assignee: null, + reviewer: null, + status: 'completed', + }, + ], + }, + { + start_frame: 285, + stop_frame: 384, + jobs: [ + { + url: 'http://192.168.0.139:7000/api/v1/jobs/4', + id: 4, + assignee: null, + reviewer: null, + status: 'completed', + }, + ], + }, + { + start_frame: 380, + stop_frame: 431, + jobs: [ + { + url: 'http://192.168.0.139:7000/api/v1/jobs/5', + id: 5, + assignee: null, + reviewer: null, + status: 'completed', + }, + ], + }, + ], + data_chunk_size: 36, + data_compressed_chunk_type: 'imageset', + data_original_chunk_type: 'video', + size: 432, + image_quality: 100, + data: 1, + }, + ], + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2020-10-12T08:21:56.558898Z', + updated_date: '2020-10-12T08:21:56.558982Z', + status: 'completed', + }, + ], +}; - ] - } +const tasksDummyData = { + count: 5, + next: null, + previous: null, + results: [ + { + url: 'http://localhost:7000/api/v1/tasks/102', + id: 102, + name: 'Test', + size: 1, + mode: 'annotation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2019-09-05T11:59:22.987942Z', + updated_date: '2019-09-05T14:04:07.569344Z', + overlap: 0, + segment_size: 0, + status: 'annotation', + labels: [ + { + id: 5, + name: 'car', + attributes: [], + }, ], - "segments": [ - { - "start_frame": 0, - "stop_frame": 8, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/100", - "id": 100, - "assignee": null, - "status": "annotation" - } - ] - } + segments: [ + { + start_frame: 0, + stop_frame: 0, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/112', + id: 112, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, ], - "image_quality": 50, - "start_frame": 0, - "stop_frame": 0, - "frame_filter": "" + image_quality: 50, + start_frame: 0, + stop_frame: 0, + frame_filter: '', }, { - "url": "http://localhost:7000/api/v1/tasks/10", - "id": 101, - "name": "Video Task", - "size": 5002, - "mode": "interpolation", - "owner": 1, - "assignee": null, - "bug_tracker": "", - "created_date": "2019-06-21T16:34:49.199691+03:00", - "updated_date": "2019-07-12T16:43:58.904892+03:00", - "overlap": 5, - "segment_size": 500, - "z_order": false, - "status": "annotation", - "labels": [ - { - "id": 22, - "name": "bicycle", - "attributes":[ - { - "id": 13, - "name": "driver", - "mutable": false, - "input_type": "radio", - "default_value": "man", - "values": [ - "man", - "woman" - ] - }, - { - "id": 14, - "name": "sport", - "mutable": true, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - } - ] - }, - { - "id": 21, - "name": "car", - "attributes": [ - { - "id": 10, - "name": "model", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "bmw", - "mazda", - "suzuki", - "kia" - ] - }, - { - "id": 11, - "name": "driver", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "man", - "woman" - ] - }, - { - "id": 12, - "name": "parked", - "mutable": true, - "input_type": "checkbox", - "default_value": "true", - "values": [ - "true" - ] - } - ] - }, - { - "id": 20, - "name": "face", - "attributes": [ - { - "id": 6, - "name": "age", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "baby (0-5)", - "child (6-12)", - "adolescent (13-19)", - "adult (20-45)", - "middle-age (46-64)", - "old (65-)" - ] - }, - { - "id": 7, - "name": "glass", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "sunglass", - "transparent", - "other" - ] - }, - { - "id": 8, - "name": "beard", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "yes" - ] - }, - { - "id": 9, - "name": "race", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "asian", - "black", - "caucasian", - "other" - ] - } - ] - }, - { - "id": 23, - "name": "motorcycle", - "attributes": [ - { - "id": 15, - "name": "model", - "mutable": false, - "input_type": "text", - "default_value": "unknown", - "values": [ - "unknown" - ] - } - ] - }, - { - "id": 19, - "name": "person, pedestrian", - "attributes": [ - { - "id": 1, - "name": "action", - "mutable": true, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "sitting", - "raising_hand", - "standing" - ] - }, - { - "id": 2, - "name": "age", - "mutable": false, - "input_type": "number", - "default_value": "1", - "values": [ - "1", - "100", - "1" - ] - }, - { - "id": 3, - "name": "gender", - "mutable" :false, - "input_type": "select", - "default_value": "male", - "values": [ - "male", - "female" - ] - }, - { - "id": 4, - "name": "false positive", - "mutable": false, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - }, - { - "id": 5, - "name": "clother", - "mutable": true, - "input_type": "text", - "default_value": "non, initialized", - "values": [ - "non, initialized" - ] - } - ] - }, - { - "id": 24, - "name": "road", - "attributes": [ - - ] - } + url: 'http://localhost:7000/api/v1/tasks/100', + id: 100, + name: 'Image Task', + size: 9, + mode: 'annotation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2019-06-18T13:05:08.941304+03:00', + updated_date: '2019-07-16T15:51:29.142871+03:00', + overlap: 0, + segment_size: 0, + status: 'annotation', + labels: [ + { + id: 1, + name: 'car,', + attributes: [], + }, + { + id: 2, + name: 'person', + attributes: [], + }, ], - "segments": [ - { - "start_frame": 0, - "stop_frame": 499, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/10", - "id": 101, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 495, - "stop_frame": 994, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/11", - "id": 102, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 990, - "stop_frame": 1489, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/12", - "id": 103, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 1485, - "stop_frame": 1984, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/13", - "id": 104, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 1980, - "stop_frame": 2479, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/14", - "id": 105, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 2475, - "stop_frame": 2974, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/15", - "id": 106, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 2970, - "stop_frame": 3469, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/16", - "id": 107, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 3465, - "stop_frame": 3964, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/17", - "id": 108, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 3960, - "stop_frame": 4459, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/18", - "id": 109, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 4455, - "stop_frame": 4954, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/19", - "id": 110, - "assignee": null, - "status": "annotation" - } - ] - }, - { - "start_frame": 4950, - "stop_frame": 5001, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/20", - "id": 111, - "assignee": null, - "status": "annotation" - } - ] - } + segments: [ + { + start_frame: 0, + stop_frame: 8, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/100', + id: 100, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, ], - "image_quality": 50, - "start_frame": 0, - "stop_frame": 5001, - "frame_filter": "" + image_quality: 50, + start_frame: 0, + stop_frame: 0, + frame_filter: '', }, { - "url": "http://localhost:7000/api/v1/tasks/3", - "id": 3, - "name": "Test Task", - "size": 5002, - "mode": "interpolation", - "owner": 2, - "assignee": null, - "bug_tracker": "", - "created_date": "2019-05-16T13:08:00.621747+03:00", - "updated_date": "2019-05-16T13:08:00.621797+03:00", - "overlap": 5, - "segment_size": 5000, - "z_order": true, - "flipped": false, - "status": "annotation", - "labels": [ + url: 'http://localhost:7000/api/v1/tasks/10', + id: 101, + name: 'Video Task', + size: 5002, + mode: 'interpolation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2019-06-21T16:34:49.199691+03:00', + updated_date: '2019-07-12T16:43:58.904892+03:00', + overlap: 5, + segment_size: 500, + status: 'annotation', + labels: [ { - "id": 16, - "name": "bicycle", - "attributes": [ - { - "id": 43, - "name": "driver", - "mutable": false, - "input_type": "radio", - "default_value": "man", - "values": [ - "man", - "woman" - ] - }, - { - "id": 44, - "name": "sport", - "mutable": true, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - } - ] + id: 22, + name: 'bicycle', + attributes: [ + { + id: 13, + name: 'driver', + mutable: false, + input_type: 'radio', + default_value: 'man', + values: ['man', 'woman'], + }, + { + id: 14, + name: 'sport', + mutable: true, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + ], }, { - "id": 15, - "name": "car", - "attributes": [ - { - "id": 40, - "name": "model", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "bmw", - "mazda", - "suzuki", - "kia" - ] - }, - { - "id": 41, - "name": "driver", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "man", - "woman" - ] - }, - { - "id": 42, - "name": "parked", - "mutable": true, - "input_type": "checkbox", - "default_value": "true", - "values": [ - "true" - ] - } - ] + id: 21, + name: 'car', + attributes: [ + { + id: 10, + name: 'model', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'bmw', 'mazda', 'suzuki', 'kia'], + }, + { + id: 11, + name: 'driver', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'man', 'woman'], + }, + { + id: 12, + name: 'parked', + mutable: true, + input_type: 'checkbox', + default_value: 'true', + values: ['true'], + }, + ], }, { - "id": 14, - "name": "face", - "attributes": [ - { - "id": 36, - "name": "age", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "baby (0-5)", - "child (6-12)", - "adolescent (13-19)", - "adult (20-45)", - "middle-age (46-64)", - "old (65-)" - ] - }, - { - "id": 37, - "name": "glass", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "sunglass", - "transparent", - "other" - ] - }, - { - "id": 38, - "name": "beard", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "yes" - ] - }, - { - "id": 39, - "name": "race", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "asian", - "black", - "caucasian", - "other" - ] - } - ] + id: 20, + name: 'face', + attributes: [ + { + id: 6, + name: 'age', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: [ + '__undefined__', + 'skip', + 'baby (0-5)', + 'child (6-12)', + 'adolescent (13-19)', + 'adult (20-45)', + 'middle-age (46-64)', + 'old (65-)', + ], + }, + { + id: 7, + name: 'glass', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'sunglass', 'transparent', 'other'], + }, + { + id: 8, + name: 'beard', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'yes'], + }, + { + id: 9, + name: 'race', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'asian', 'black', 'caucasian', 'other'], + }, + ], }, { - "id": 17, - "name": "motorcycle", - "attributes": [ - { - "id": 45, - "name": "model", - "mutable": false, - "input_type": "text", - "default_value": "unknown", - "values": [ - "unknown" - ] - } - ] + id: 23, + name: 'motorcycle', + attributes: [ + { + id: 15, + name: 'model', + mutable: false, + input_type: 'text', + default_value: 'unknown', + values: ['unknown'], + }, + ], }, { - "id": 13, - "name": "person, pedestrian", - "attributes": [ - { - "id": 31, - "name": "action", - "mutable": true, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "sitting", - "raising_hand", - "standing" - ] - }, - { - "id": 32, - "name": "age", - "mutable": false, - "input_type": "number", - "default_value": "1", - "values": [ - "1", - "100", - "1" - ] - }, - { - "id": 33, - "name": "gender", - "mutable": false, - "input_type": "select", - "default_value": "male", - "values": [ - "male", - "female" - ] - }, - { - "id": 34, - "name": "false positive", - "mutable": false, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - }, - { - "id": 35, - "name": "clother", - "mutable": true, - "input_type": "text", - "default_value": "non, initialized", - "values": [ - "non, initialized" - ] - } - ] + id: 19, + name: 'person, pedestrian', + attributes: [ + { + id: 1, + name: 'action', + mutable: true, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'sitting', 'raising_hand', 'standing'], + }, + { + id: 2, + name: 'age', + mutable: false, + input_type: 'number', + default_value: '1', + values: ['1', '100', '1'], + }, + { + id: 3, + name: 'gender', + mutable: false, + input_type: 'select', + default_value: 'male', + values: ['male', 'female'], + }, + { + id: 4, + name: 'false positive', + mutable: false, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + { + id: 5, + name: 'clother', + mutable: true, + input_type: 'text', + default_value: 'non, initialized', + values: ['non, initialized'], + }, + ], }, { - "id": 18, - "name": "road", - "attributes": [] - } + id: 24, + name: 'road', + attributes: [], + }, ], - "segments": [ + segments: [ + { + start_frame: 0, + stop_frame: 499, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/10', + id: 101, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 495, + stop_frame: 994, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/11', + id: 102, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 990, + stop_frame: 1489, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/12', + id: 103, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, { - "start_frame": 0, - "stop_frame": 4999, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/3", - "id": 3, - "assignee": null, - "status": "annotation" - } - ] + start_frame: 1485, + stop_frame: 1984, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/13', + id: 104, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 1980, + stop_frame: 2479, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/14', + id: 105, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 2475, + stop_frame: 2974, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/15', + id: 106, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 2970, + stop_frame: 3469, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/16', + id: 107, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 3465, + stop_frame: 3964, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/17', + id: 108, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 3960, + stop_frame: 4459, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/18', + id: 109, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 4455, + stop_frame: 4954, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/19', + id: 110, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], }, { - "start_frame": 4995, - "stop_frame": 5001, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/4", - "id": 4, - "assignee": null, - "status": "annotation" - } - ] - } + start_frame: 4950, + stop_frame: 5001, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/20', + id: 111, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, ], - "image_quality": 50 + image_quality: 50, + start_frame: 0, + stop_frame: 5001, + frame_filter: '', }, { - "url": "http://localhost:7000/api/v1/tasks/2", - "id": 2, - "name": "Video", - "size": 75, - "mode": "interpolation", - "owner": 1, - "assignee": null, - "bug_tracker": "", - "created_date": "2019-05-15T11:40:19.487999+03:00", - "updated_date": "2019-05-15T16:58:27.992785+03:00", - "overlap": 5, - "segment_size": 0, - "z_order": false, - "flipped": false, - "status": "annotation", - "labels": [ + url: 'http://localhost:7000/api/v1/tasks/3', + id: 3, + name: 'Test Task', + size: 5002, + mode: 'interpolation', + owner: { + url: 'http://localhost:7000/api/v1/users/2', + id: 2, + username: 'bsekache', + }, + assignee: null, + bug_tracker: '', + created_date: '2019-05-16T13:08:00.621747+03:00', + updated_date: '2019-05-16T13:08:00.621797+03:00', + overlap: 5, + segment_size: 5000, + flipped: false, + status: 'annotation', + labels: [ { - "id": 10, - "name": "bicycle", - "attributes": [ - { - "id": 28, - "name": "driver", - "mutable": false, - "input_type": "radio", - "default_value": "man", - "values": [ - "man", - "woman" - ] - }, - { - "id": 29, - "name": "sport", - "mutable": true, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - } - ] + id: 16, + name: 'bicycle', + attributes: [ + { + id: 43, + name: 'driver', + mutable: false, + input_type: 'radio', + default_value: 'man', + values: ['man', 'woman'], + }, + { + id: 44, + name: 'sport', + mutable: true, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + ], }, { - "id": 9, - "name": "car", - "attributes": [ - { - "id": 25, - "name": "model", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "bmw", - "mazda", - "suzuki", - "kia" - ] - }, - { - "id": 26, - "name": "driver", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "man", - "woman" - ] - }, - { - "id": 27, - "name": "parked", - "mutable": true, - "input_type": "checkbox", - "default_value": "true", - "values": [ - "true" - ] - } - ] + id: 15, + name: 'car', + attributes: [ + { + id: 40, + name: 'model', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'bmw', 'mazda', 'suzuki', 'kia'], + }, + { + id: 41, + name: 'driver', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'man', 'woman'], + }, + { + id: 42, + name: 'parked', + mutable: true, + input_type: 'checkbox', + default_value: 'true', + values: ['true'], + }, + ], }, { - "id": 8, - "name": "face", - "attributes": [ - { - "id": 21, - "name": "age", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "baby (0-5)", - "child (6-12)", - "adolescent (13-19)", - "adult (20-45)", - "middle-age (46-64)", - "old (65-)" - ] - }, - { - "id": 22, - "name": "glass", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "sunglass", - "transparent", - "other" - ] - }, - { - "id": 23, - "name": "beard", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "yes" - ] - }, - { - "id": 24, - "name": "race", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "asian", - "black", - "caucasian", - "other" - ] - } - ] + id: 14, + name: 'face', + attributes: [ + { + id: 36, + name: 'age', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: [ + '__undefined__', + 'skip', + 'baby (0-5)', + 'child (6-12)', + 'adolescent (13-19)', + 'adult (20-45)', + 'middle-age (46-64)', + 'old (65-)', + ], + }, + { + id: 37, + name: 'glass', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'sunglass', 'transparent', 'other'], + }, + { + id: 38, + name: 'beard', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'yes'], + }, + { + id: 39, + name: 'race', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'asian', 'black', 'caucasian', 'other'], + }, + ], }, { - "id": 11, - "name": "motorcycle", - "attributes": [ - { - "id": 30, - "name": "model", - "mutable": false, - "input_type": "text", - "default_value": "unknown", - "values": [ - "unknown" - ] - } - ] + id: 17, + name: 'motorcycle', + attributes: [ + { + id: 45, + name: 'model', + mutable: false, + input_type: 'text', + default_value: 'unknown', + values: ['unknown'], + }, + ], }, { - "id": 7, - "name": "person, pedestrian", - "attributes": [ - { - "id": 16, - "name": "action", - "mutable": true, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "sitting", - "raising_hand", - "standing" - ] - }, - { - "id": 17, - "name": "age", - "mutable": false, - "input_type": "number", - "default_value": "1", - "values": [ - "1", - "100", - "1" - ] - }, - { - "id": 18, - "name": "gender", - "mutable": false, - "input_type": "select", - "default_value": "male", - "values": [ - "male", - "female" - ] - }, - { - "id": 19, - "name": "false positive", - "mutable": false, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - }, - { - "id": 20, - "name": "clother", - "mutable": true, - "input_type": "text", - "default_value": "non, initialized", - "values": [ - "non, initialized" - ] - } - ] + id: 13, + name: 'person, pedestrian', + attributes: [ + { + id: 31, + name: 'action', + mutable: true, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'sitting', 'raising_hand', 'standing'], + }, + { + id: 32, + name: 'age', + mutable: false, + input_type: 'number', + default_value: '1', + values: ['1', '100', '1'], + }, + { + id: 33, + name: 'gender', + mutable: false, + input_type: 'select', + default_value: 'male', + values: ['male', 'female'], + }, + { + id: 34, + name: 'false positive', + mutable: false, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + { + id: 35, + name: 'clother', + mutable: true, + input_type: 'text', + default_value: 'non, initialized', + values: ['non, initialized'], + }, + ], }, { - "id": 12, - "name": "road", - "attributes": [] - } + id: 18, + name: 'road', + attributes: [], + }, ], - "segments": [ + segments: [ { - "start_frame": 0, - "stop_frame": 74, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/2", - "id": 2, - "assignee": null, - "status": "annotation" - } - ] - } + start_frame: 0, + stop_frame: 4999, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/3', + id: 3, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, + { + start_frame: 4995, + stop_frame: 5001, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/4', + id: 4, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, ], - "image_quality": 50 + image_quality: 50, }, { - "url": "http://localhost:7000/api/v1/tasks/1", - "id": 1, - "name": "Labels Set", - "size": 9, - "mode": "annotation", - "owner": 1, - "assignee": null, - "bug_tracker": "http://bugtracker.com/issue12345", - "created_date": "2019-05-13T15:35:29.871003+03:00", - "updated_date": "2019-05-15T11:20:55.770587+03:00", - "overlap": 0, - "segment_size": 0, - "z_order": true, - "flipped": false, - "status": "annotation", - "labels": [ + url: 'http://localhost:7000/api/v1/tasks/2', + id: 2, + name: 'Video', + size: 75, + mode: 'interpolation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: '', + created_date: '2019-05-15T11:40:19.487999+03:00', + updated_date: '2019-05-15T16:58:27.992785+03:00', + overlap: 5, + segment_size: 0, + flipped: false, + status: 'annotation', + labels: [ { - "id": 4, - "name": "bicycle", - "attributes": [ - { - "id": 13, - "name": "driver", - "mutable": false, - "input_type": "radio", - "default_value": "man", - "values": [ - "man", - "woman" - ] - }, - { - "id": 14, - "name": "sport", - "mutable": true, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - } - ] + id: 10, + name: 'bicycle', + attributes: [ + { + id: 28, + name: 'driver', + mutable: false, + input_type: 'radio', + default_value: 'man', + values: ['man', 'woman'], + }, + { + id: 29, + name: 'sport', + mutable: true, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + ], }, { - "id": 3, - "name": "car", - "attributes": [ - { - "id": 10, - "name": "model", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "bmw", - "mazda", - "suzuki", - "kia" - ] - }, - { - "id": 11, - "name": "driver", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "man", - "woman" - ] - }, - { - "id": 12, - "name": "parked", - "mutable": true, - "input_type": "checkbox", - "default_value": "true", - "values": [ - "true" - ] - } - ] + id: 9, + name: 'car', + attributes: [ + { + id: 25, + name: 'model', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'bmw', 'mazda', 'suzuki', 'kia'], + }, + { + id: 26, + name: 'driver', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'man', 'woman'], + }, + { + id: 27, + name: 'parked', + mutable: true, + input_type: 'checkbox', + default_value: 'true', + values: ['true'], + }, + ], }, { - "id": 2, - "name": "face", - "attributes": [ - { - "id": 6, - "name": "age", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "baby (0-5)", - "child (6-12)", - "adolescent (13-19)", - "adult (20-45)", - "middle-age (46-64)", - "old (65-)" - ] - }, - { - "id": 7, - "name": "glass", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "sunglass", - "transparent", - "other" - ] - }, - { - "id": 8, - "name": "beard", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "no", - "yes" - ] - }, - { - "id": 9, - "name": "race", - "mutable": false, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "skip", - "asian", - "black", - "caucasian", - "other" - ] - } - ] + id: 8, + name: 'face', + attributes: [ + { + id: 21, + name: 'age', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: [ + '__undefined__', + 'skip', + 'baby (0-5)', + 'child (6-12)', + 'adolescent (13-19)', + 'adult (20-45)', + 'middle-age (46-64)', + 'old (65-)', + ], + }, + { + id: 22, + name: 'glass', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'sunglass', 'transparent', 'other'], + }, + { + id: 23, + name: 'beard', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'yes'], + }, + { + id: 24, + name: 'race', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'asian', 'black', 'caucasian', 'other'], + }, + ], }, { - "id": 5, - "name": "motorcycle", - "attributes": [ - { - "id": 15, - "name": "model", - "mutable": false, - "input_type": "text", - "default_value": "unknown", - "values": [ - "unknown" - ] - } - ] + id: 11, + name: 'motorcycle', + attributes: [ + { + id: 30, + name: 'model', + mutable: false, + input_type: 'text', + default_value: 'unknown', + values: ['unknown'], + }, + ], }, { - "id": 1, - "name": "person, pedestrian", - "attributes": [ - { - "id": 1, - "name": "action", - "mutable": true, - "input_type": "select", - "default_value": "__undefined__", - "values": [ - "__undefined__", - "sitting", - "raising_hand", - "standing" - ] - }, - { - "id": 2, - "name": "age", - "mutable": false, - "input_type": "number", - "default_value": "1", - "values": [ - "1", - "100", - "1" - ] - }, - { - "id": 3, - "name": "gender", - "mutable": false, - "input_type": "select", - "default_value": "male", - "values": [ - "male", - "female" - ] - }, - { - "id": 4, - "name": "false positive", - "mutable": false, - "input_type": "checkbox", - "default_value": "false", - "values": [ - "false" - ] - }, - { - "id": 5, - "name": "clother", - "mutable": true, - "input_type": "text", - "default_value": "non, initialized", - "values": [ - "non, initialized" - ] - } - ] + id: 7, + name: 'person, pedestrian', + attributes: [ + { + id: 16, + name: 'action', + mutable: true, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'sitting', 'raising_hand', 'standing'], + }, + { + id: 17, + name: 'age', + mutable: false, + input_type: 'number', + default_value: '1', + values: ['1', '100', '1'], + }, + { + id: 18, + name: 'gender', + mutable: false, + input_type: 'select', + default_value: 'male', + values: ['male', 'female'], + }, + { + id: 19, + name: 'false positive', + mutable: false, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + { + id: 20, + name: 'clother', + mutable: true, + input_type: 'text', + default_value: 'non, initialized', + values: ['non, initialized'], + }, + ], }, { - "id": 6, - "name": "road", - "attributes": [] - } + id: 12, + name: 'road', + attributes: [], + }, ], - "segments": [ + segments: [ { - "start_frame": 0, - "stop_frame": 8, - "jobs": [ - { - "url": "http://localhost:7000/api/v1/jobs/1", - "id": 1, - "assignee": null, - "status": "annotation" - } - ] - } - ], - "image_quality": 95 - } - ] -} - -const taskAnnotationsDummyData = { - '112': { - "version":21, - "tags": [], - "shapes": [{ - "type": "rectangle", - "occluded": false, - "z_order": 1, - "points": [ - 557.7890625, - 276.2216796875, - 907.1888732910156, - 695.5014038085938 - ], - "id": 15, - "frame": 0, - "label_id": 5, - "group": 0, - "attributes": [] - }], - "tracks": [{ - "id": 15, - "frame": 0, - "label_id": 5, - "group": 0, - "shapes": [{ - "type": "rectangle", - "occluded": false, - "z_order": 13, - "points": [ - 792.787109375, - 16.5234375, - 1171.1027526855469, - 521.3458862304688 - ], - "id": 22, - "frame": 0, - "outside": false, - "attributes": [] - }], - "attributes": [] - }] - }, - '101': { - "version":21, - "tags":[], - "shapes":[], - "tracks":[ - { - "id": 25, // interpolation - "frame": 10, - "label_id": 19, - "group": 0, - "shapes": [{ - "type": "polygon", - "occluded": false, - "z_order": 2, - "points": [ - 377.64912280702083, - 458.5473684210556, - 383.82456140351314, - 458.5473684210556, - 406.98245614035477, - 455.45964912281124, - 431.6842105263204, - 455.45964912281124, - 457.92982456140817, - 455.45964912281124, - 482.6315789473738, - 455.45964912281124, - 508.87719298246157, - 455.45964912281124, - 535.1228070175493, - 455.45964912281124, - 559.8245614035113, - 455.45964912281124, - 587.6140350877249, - 455.45964912281124, - 620.0350877193014, - 455.45964912281124, - 640.1052631578968, - 455.45964912281124, - 664.8070175438625, - 453.9157894736891, - 692.5964912280724, - 450.8280701754411, - 721.9298245614082, - 450.8280701754411, - 743.5438596491258, - 447.74035087719676, - 769.7894736842136, - 446.1964912280746, - 796.0350877193014, - 446.1964912280746, - 823.8245614035113, - 446.1964912280746, - 846.9824561403548, - 446.1964912280746, - 876.3157894736869, - 446.1964912280746, - 905.6491228070226, - 446.1964912280746, - 931.8947368421104, - 446.1964912280746, - 959.6842105263204, - 446.1964912280746, - 987.4736842105303, - 446.1964912280746, - 1015.2631578947403, - 446.1964912280746, - 1039.964912280706, - 446.1964912280746, - 1066.2105263157937, - 446.1964912280746, - 1090.9122807017593, - 446.1964912280746, - 1115.614035087725, - 446.1964912280746, - 1138.7719298245647, - 449.28421052631893, - 1231.4000000000015, - 413.8000000000011, - 1180.4561403508815, - 467.81052631579223, - 1180.4561403508815, - 494.05614035088, - 1180.4561403508815, - 520.3017543859678, - 1180.4561403508815, - 545.0035087719334, - 1180.4561403508815, - 571.2491228070212, - 1180.4561403508815, - 597.494736842109, - 1180.4561403508815, - 620.6526315789524, - 1180.4561403508815, - 649.9859649122845, - 1180.4561403508815, - 676.2315789473723, - 1180.4561403508815, - 699.3894736842158, - 1180.4561403508815, - 727.1789473684257, - 1180.4561403508815, - 747.2491228070212, - 1180.4561403508815, - 771.9508771929868, - 1180.4561403508815, - 802.8280701754411, - 1180.4561403508815, - 830.6175438596547, - 1180.4561403508815, - 853.7754385964945, - 1180.4561403508815, - 880.0210526315823, - 1183.5438596491258, - 901.6350877193036, - 1183.5438596491258, - 929.4245614035135, - 1186.6315789473738, - 952.5824561403533, - 1188.175438596496, - 975.7403508771968, - 1188.175438596496, - 1001.9859649122845, - 1188.175438596496, - 1023.6000000000022, - 1188.175438596496, - 1057.5649122807044, - 1186.6315789473738, - 1082.26666666667, - 1186.6315789473738, - 1108.5122807017578, - 1186.6315789473738, - 1133.2140350877235, - 1175.82421875, - 1154.828125, - 1155.7543859649159, - 1156.371929824567, - 1132.5964912280724, - 1154.828070175441, - 1106.3508771929846, - 1154.828070175441, - 1078.5614035087747, - 1154.828070175441, - 1053.8596491228127, - 1150.1964912280746, - 1030.7017543859693, - 1148.6526315789524, - 1002.9122807017593, - 1148.6526315789524, - 982.8421052631602, - 1148.6526315789524, - 953.5087719298281, - 1147.1087719298303, - 922.6315789473738, - 1147.1087719298303, - 891.7543859649159, - 1147.1087719298303, - 868.5964912280724, - 1147.1087719298303, - 839.2631578947403, - 1147.1087719298303, - 816.1052631578968, - 1147.1087719298303, - 786.7719298245647, - 1147.1087719298303, - 760.5263157894769, - 1147.1087719298303, - 735.8245614035113, - 1147.1087719298303, - 708.0350877193014, - 1142.47719298246, - 684.8771929824616, - 1140.933333333338, - 658.6315789473738, - 1140.933333333338, - 633.9298245614082, - 1140.933333333338, - 607.6842105263204, - 1139.3894736842158, - 581.4385964912326, - 1134.7578947368456, - 559.8245614035113, - 1133.2140350877235, - 535.1228070175493, - 1131.6701754386013, - 505.7894736842136, - 1131.6701754386013, - 482.6315789473738, - 1131.6701754386013, - 454.8421052631602, - 1130.1263157894791, - 430.1403508771964, - 1130.1263157894791, - 405.4385964912326, - 1130.1263157894791, - 383.82421875, - 1130.126953125, - 382.28070175438916, - 1113.143859649128, - 380.736842105267, - 1088.4421052631624, - 380.736842105267, - 1056.0210526315823, - 380.736842105267, - 1026.6877192982502, - 379.1929824561448, - 1005.0736842105289, - 374.5614035087765, - 978.8280701754411, - 371.47368421053034, - 949.494736842109, - 371.47368421053034, - 921.705263157899, - 371.47368421053034, - 897.0035087719334, - 371.47368421053034, - 866.1263157894791, - 371.47368421053034, - 842.9684210526357, - 371.47368421053034, - 810.5473684210556, - 371.47368421053034, - 778.1263157894791, - 377.64912280702083, - 751.8807017543913, - 380.736842105267, - 722.5473684210556, - 385.3684210526353, - 693.2140350877235, - 385.3684210526353, - 668.5122807017578, - 386.9122807017575, - 643.8105263157922, - 388.45614035088147, - 619.1087719298266, - 388.45614035088147, - 591.3192982456167, - 388.45614035088147, - 563.5298245614067, - 388.45614035088147, - 535.7403508771968, - 388.45614035088147, - 511.03859649123115, - 386.9122807017575, - 487.88070175439134 - ], - "id":382, - "frame":10, - "outside":false, - "attributes": [{ - "spec_id":1, - "value":"__undefined__" - }, { - "spec_id":5, - "value":"non, initialized" - }] - }, { - "type": "polygon", - "occluded": false, - "z_order": 2, - "points": [ - 502.701171875, - 1093.07421875, - 860.8771929824616, - 443.10877192982844, - 1462.9824561403548, - 1120.8631578947425 - ], - "id": 383, - "frame": 20, - "outside": false, - "attributes": [] - }, { - "type": "polygon", - "occluded": false, - "z_order": 2, - "points": [ - 502.701171875, - 1093.07421875, - 860.8771929824616, - 443.10877192982844, - 1462.9824561403548, - 1120.8631578947425 + start_frame: 0, + stop_frame: 74, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/2', + id: 2, + assignee: null, + reviewer: null, + status: 'annotation', + }, ], - "id": 384, - "frame": 22, - "outside": true, - "attributes": [] - }], - "attributes": [{ - "spec_id": 2, - "value": "1" - }, { - "spec_id": 3, - "value": "male" - }, { - "spec_id": 4, - "value": "false" - }] - }, - { - "id": 60, - "frame": 0, - "label_id": 19, - "group": 0, - "shapes": [{ - "type": "rectangle", - "occluded": false, - "z_order": 1, - "points": [ - 425.58984375, - 540.298828125, - 755.9765625, - 745.6328125 + }, + ], + image_quality: 50, + }, + { + url: 'http://localhost:7000/api/v1/tasks/1', + id: 1, + name: 'Labels Set', + size: 9, + mode: 'annotation', + owner: { + url: 'http://localhost:7000/api/v1/users/1', + id: 1, + username: 'admin', + }, + assignee: null, + bug_tracker: 'http://bugtracker.com/issue12345', + created_date: '2019-05-13T15:35:29.871003+03:00', + updated_date: '2019-05-15T11:20:55.770587+03:00', + overlap: 0, + segment_size: 0, + flipped: false, + status: 'annotation', + labels: [ + { + id: 4, + name: 'bicycle', + attributes: [ + { + id: 13, + name: 'driver', + mutable: false, + input_type: 'radio', + default_value: 'man', + values: ['man', 'woman'], + }, + { + id: 14, + name: 'sport', + mutable: true, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, ], - "id": 379, - "frame": 0, - "outside": false, - "attributes": [ - { - "spec_id":5, - "value":"non, initialized" - }, - { - "spec_id":1, - "value":"__undefined__" - } - ] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 1, - "points": [ - 238.8000000000011, - 498.6000000000022, - 546.01171875, - 660.720703125 + }, + { + id: 3, + name: 'car', + attributes: [ + { + id: 10, + name: 'model', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'bmw', 'mazda', 'suzuki', 'kia'], + }, + { + id: 11, + name: 'driver', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'man', 'woman'], + }, + { + id: 12, + name: 'parked', + mutable: true, + input_type: 'checkbox', + default_value: 'true', + values: ['true'], + }, ], - "id": 380, - "frame": 10, - "outside": false, - "attributes": [] - }, { - "type":"rectangle", - "occluded":false, - "z_order":1, - "points":[ - 13.3955078125, - 447.650390625, - 320.6072265624989, - 609.7710937499978 + }, + { + id: 2, + name: 'face', + attributes: [ + { + id: 6, + name: 'age', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: [ + '__undefined__', + 'skip', + 'baby (0-5)', + 'child (6-12)', + 'adolescent (13-19)', + 'adult (20-45)', + 'middle-age (46-64)', + 'old (65-)', + ], + }, + { + id: 7, + name: 'glass', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'sunglass', 'transparent', 'other'], + }, + { + id: 8, + name: 'beard', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'no', 'yes'], + }, + { + id: 9, + name: 'race', + mutable: false, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'skip', 'asian', 'black', 'caucasian', 'other'], + }, ], - "id":381, - "frame":20, - "outside":false, - "attributes":[ - - ] - }], - "attributes":[ + }, { - "spec_id":2, - "value":"1" + id: 5, + name: 'motorcycle', + attributes: [ + { + id: 15, + name: 'model', + mutable: false, + input_type: 'text', + default_value: 'unknown', + values: ['unknown'], + }, + ], }, { - "spec_id":3, - "value":"male" + id: 1, + name: 'person, pedestrian', + attributes: [ + { + id: 1, + name: 'action', + mutable: true, + input_type: 'select', + default_value: '__undefined__', + values: ['__undefined__', 'sitting', 'raising_hand', 'standing'], + }, + { + id: 2, + name: 'age', + mutable: false, + input_type: 'number', + default_value: '1', + values: ['1', '100', '1'], + }, + { + id: 3, + name: 'gender', + mutable: false, + input_type: 'select', + default_value: 'male', + values: ['male', 'female'], + }, + { + id: 4, + name: 'false positive', + mutable: false, + input_type: 'checkbox', + default_value: 'false', + values: ['false'], + }, + { + id: 5, + name: 'clother', + mutable: true, + input_type: 'text', + default_value: 'non, initialized', + values: ['non, initialized'], + }, + ], }, { - "spec_id":4, - "value":"false" - }] - } - ] - }, - '100': { - "version": 16, - "tags": [], - "shapes": [{ - "type": "rectangle", - "occluded": false, - "z_order": 1, - "points": [ - 387.91, - 403.81, - 595.14, - 712.25 - ], - "id": 108, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 2, - "points": [ - 783.12, - 368.91, - 990.35, - 677.34 - ], - "id": 109, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 3, - "points": [ - 1277.1, - 239.99, - 1484.33, - 548.43 - ], - "id": 110, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 4, - "points": [ - 1420.48, - 713.49, - 1627.71, - 1021.92 - ], - "id": 111, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes":[ - - ] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 5, - "points": [ - 896.38, - 659.27, - 1103.61, - 967.71 - ], - "id": 112, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "polygon", - "occluded": false, - "z_order": 6, - "points": [ - 449.36, - 892.97, - 449.36, - 892.97, - 468.63, - 913.46, - 495.14, - 933.94, - 527.67, - 955.62, - 562.61, - 973.7, - 589.12, - 983.34, - 613.21, - 988.15, - 632.49, - 991.77, - 656.59, - 994.18, - 686.71, - 994.18, - 733.69, - 980.93, - 772.25, - 959.24, - 809.6, - 927.91, - 837.31, - 896.59, - 851.77, - 867.67, - 861.41, - 841.17, - 862.61, - 805.02, - 840.92, - 759.24, - 802.37, - 720.68, - 777.07, - 703.82, - 750.56, - 690.56, - 726.47, - 684.54, - 698.75, - 680.92, - 681.89, - 680.92, - 656.59, - 680.92, - 633.69, - 683.33, - 608.39, - 690.56, - 578.27, - 706.22, - 548.15, - 718.27, - 518.03, - 730.32, - 486.71, - 743.57, - 458.99, - 756.83, - 434.9, - 766.47, - 408.39, - 777.31, - 381.89, - 786.95, - 354.17, - 794.18, - 331.28, - 800.2, - 295.14, - 803.82, - 283.09, - 800.2, - 267.43, - 783.33, - 255.38, - 766.47, - 232.49, - 733.94, - 220.44, - 713.45, - 212.0, - 688.15, - 208.39, - 666.47, - 210.8, - 647.19 - ], - "id": 113, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes":[] - }, { - "type": "polygon", - "occluded": false, - "z_order": 7, - "points": [ - 1260.84, - 344.81, - 1260.84, - 344.81, - 1280.11, - 365.29, - 1306.62, - 385.78, - 1339.15, - 407.46, - 1374.09, - 425.53, - 1400.6, - 435.17, - 1424.69, - 439.99, - 1443.97, - 443.61, - 1468.07, - 446.02, - 1498.19, - 446.02, - 1545.18, - 432.76, - 1583.73, - 411.08, - 1621.08, - 379.75, - 1648.79, - 348.43, - 1663.25, - 319.51, - 1672.89, - 293.0, - 1674.09, - 256.86, - 1652.41, - 211.08, - 1613.85, - 172.52, - 1588.55, - 155.65, - 1562.04, - 142.4, - 1537.95, - 136.38, - 1510.24, - 132.76, - 1493.37, - 132.76, - 1468.07, - 132.76, - 1445.18, - 135.17, - 1419.87, - 142.4, - 1389.75, - 158.06, - 1359.63, - 170.11, - 1329.51, - 182.16, - 1298.19, - 195.41, - 1270.48, - 208.67, - 1246.38, - 218.3, - 1219.87, - 229.15, - 1193.37, - 238.79, - 1165.66, - 246.02, - 1142.76, - 252.04, - 1106.62, - 255.65, - 1094.57, - 252.04, - 1078.91, - 235.17, - 1066.86, - 218.3, - 1043.97, - 185.77, - 1031.92, - 165.29, - 1023.49, - 139.99, - 1019.87, - 118.3, - 1022.28, - 99.03 - ], - "id": 114, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "polygon", - "occluded": false, - "z_order": 8, - "points": [ - 1113.21, - 723.09, - 1322.86, - 1018.28, - 1562.62, - 873.7, - 1587.92, - 641.16, - 1267.43, - 530.32 - ], - "id": 115, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "polyline", - "occluded": false, - "z_order": 9, - "points": [ - 268.63, - 359.23, - 277.07, - 344.78, - 292.73, - 325.5, - 312.01, - 311.04, - 331.28, - 300.2, - 349.36, - 295.38, - 375.86, - 290.56, - 387.91, - 290.56, - 418.03, - 290.56, - 439.72, - 292.97, - 457.79, - 295.38, - 492.73, - 301.4, - 525.26, - 306.22, - 534.9, - 306.22, - 571.04, - 296.58, - 591.53, - 284.54, - 610.8, - 272.49, - 640.92, - 253.21, - 655.38, - 238.75 - ], - "id": 116, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "points", - "occluded": false, - "z_order": 10, - "points": [ - 1089.12, - 505.02, - 1178.28, - 543.57, - 1074.66, - 602.61, - 1109.6, - 680.92, - 1172.25, - 631.53, - 1036.11, - 576.1, - 1057.79, - 445.98, - 1185.51, - 400.2 - ], - "id": 117, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [ - - ] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1565.03, - 555.62, - 1787.92, - 765.26 - ], - "id": 118, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 100.0, - 100.0 - ], - "id": 119, - "frame": 1, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "polygon", - "occluded": false, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 0.0, - 100.0, - 200.0 - ], - "id": 120, - "frame": 1, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 121, - "frame": 1, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 122, - "frame": 1, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 123, - "frame": 2, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 124, - "frame": 2, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 125, - "frame": 3, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 126, - "frame": 3, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 127, - "frame": 4, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 128, - "frame": 4, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 129, - "frame": 5, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 130, - "frame": 5, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 131, - "frame": 6, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 132, - "frame": 6, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 133, - "frame": 7, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 - ], - "id": 134, - "frame": 7, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": false, - "z_order": 11, - "points": [ - 1211.6, - 500.48, - 1434.49, - 710.12 - ], - "id": 135, - "frame": 8, - "label_id": 1, - "group": 0, - "attributes": [] - }, { - "type": "rectangle", - "occluded": true, - "z_order": 0, - "points": [ - 0.0, - 0.0, - 200.0, - 200.0 + id: 6, + name: 'road', + attributes: [], + }, ], - "id": 136, - "frame": 8, - "label_id": 2, - "group": 0, - "attributes": [] - }, { - "type": "cuboid", - "occluded": false, - "z_order":12, - "points": [ - 37.037109375, - 834.1583663313359, - 37.037109375, - 1005.6748046875, - 500.1052119006872, - 850.3421313142153, - 500.1052119006872, - 1021.9585696703798, - 600.6842465753452, - 763.1514501284273, - 600.6842465753452, - 934.6678884845915, - 137.82724152601259, - 747.0278858154179, - 137.82724152601259, - 918.4444406426646, + segments: [ + { + start_frame: 0, + stop_frame: 8, + jobs: [ + { + url: 'http://localhost:7000/api/v1/jobs/1', + id: 1, + assignee: null, + reviewer: null, + status: 'annotation', + }, + ], + }, ], - "id": 137, - "frame": 0, - "label_id": 1, - "group": 0, - "attributes": [ + image_quality: 95, + }, + ], +}; - ] - }], - "tracks":[] - } +const taskAnnotationsDummyData = { + 112: { + version: 21, + tags: [], + shapes: [ + { + type: 'rectangle', + occluded: false, + z_order: 1, + points: [557.7890625, 276.2216796875, 907.1888732910156, 695.5014038085938], + id: 15, + frame: 0, + label_id: 5, + group: 0, + attributes: [], + }, + ], + tracks: [ + { + id: 15, + frame: 0, + label_id: 5, + group: 0, + shapes: [ + { + type: 'rectangle', + occluded: false, + z_order: 13, + points: [792.787109375, 16.5234375, 1171.1027526855469, 521.3458862304688], + id: 22, + frame: 0, + outside: false, + attributes: [], + }, + ], + attributes: [], + }, + ], + }, + 101: { + version: 21, + tags: [], + shapes: [], + tracks: [ + { + id: 25, // interpolation + frame: 10, + label_id: 19, + group: 0, + shapes: [ + { + type: 'polygon', + occluded: false, + z_order: 2, + points: [ + 377.64912280702083, + 458.5473684210556, + 383.82456140351314, + 458.5473684210556, + 406.98245614035477, + 455.45964912281124, + 431.6842105263204, + 455.45964912281124, + 457.92982456140817, + 455.45964912281124, + 482.6315789473738, + 455.45964912281124, + 508.87719298246157, + 455.45964912281124, + 535.1228070175493, + 455.45964912281124, + 559.8245614035113, + 455.45964912281124, + 587.6140350877249, + 455.45964912281124, + 620.0350877193014, + 455.45964912281124, + 640.1052631578968, + 455.45964912281124, + 664.8070175438625, + 453.9157894736891, + 692.5964912280724, + 450.8280701754411, + 721.9298245614082, + 450.8280701754411, + 743.5438596491258, + 447.74035087719676, + 769.7894736842136, + 446.1964912280746, + 796.0350877193014, + 446.1964912280746, + 823.8245614035113, + 446.1964912280746, + 846.9824561403548, + 446.1964912280746, + 876.3157894736869, + 446.1964912280746, + 905.6491228070226, + 446.1964912280746, + 931.8947368421104, + 446.1964912280746, + 959.6842105263204, + 446.1964912280746, + 987.4736842105303, + 446.1964912280746, + 1015.2631578947403, + 446.1964912280746, + 1039.964912280706, + 446.1964912280746, + 1066.2105263157937, + 446.1964912280746, + 1090.9122807017593, + 446.1964912280746, + 1115.614035087725, + 446.1964912280746, + 1138.7719298245647, + 449.28421052631893, + 1231.4000000000015, + 413.8000000000011, + 1180.4561403508815, + 467.81052631579223, + 1180.4561403508815, + 494.05614035088, + 1180.4561403508815, + 520.3017543859678, + 1180.4561403508815, + 545.0035087719334, + 1180.4561403508815, + 571.2491228070212, + 1180.4561403508815, + 597.494736842109, + 1180.4561403508815, + 620.6526315789524, + 1180.4561403508815, + 649.9859649122845, + 1180.4561403508815, + 676.2315789473723, + 1180.4561403508815, + 699.3894736842158, + 1180.4561403508815, + 727.1789473684257, + 1180.4561403508815, + 747.2491228070212, + 1180.4561403508815, + 771.9508771929868, + 1180.4561403508815, + 802.8280701754411, + 1180.4561403508815, + 830.6175438596547, + 1180.4561403508815, + 853.7754385964945, + 1180.4561403508815, + 880.0210526315823, + 1183.5438596491258, + 901.6350877193036, + 1183.5438596491258, + 929.4245614035135, + 1186.6315789473738, + 952.5824561403533, + 1188.175438596496, + 975.7403508771968, + 1188.175438596496, + 1001.9859649122845, + 1188.175438596496, + 1023.6000000000022, + 1188.175438596496, + 1057.5649122807044, + 1186.6315789473738, + 1082.26666666667, + 1186.6315789473738, + 1108.5122807017578, + 1186.6315789473738, + 1133.2140350877235, + 1175.82421875, + 1154.828125, + 1155.7543859649159, + 1156.371929824567, + 1132.5964912280724, + 1154.828070175441, + 1106.3508771929846, + 1154.828070175441, + 1078.5614035087747, + 1154.828070175441, + 1053.8596491228127, + 1150.1964912280746, + 1030.7017543859693, + 1148.6526315789524, + 1002.9122807017593, + 1148.6526315789524, + 982.8421052631602, + 1148.6526315789524, + 953.5087719298281, + 1147.1087719298303, + 922.6315789473738, + 1147.1087719298303, + 891.7543859649159, + 1147.1087719298303, + 868.5964912280724, + 1147.1087719298303, + 839.2631578947403, + 1147.1087719298303, + 816.1052631578968, + 1147.1087719298303, + 786.7719298245647, + 1147.1087719298303, + 760.5263157894769, + 1147.1087719298303, + 735.8245614035113, + 1147.1087719298303, + 708.0350877193014, + 1142.47719298246, + 684.8771929824616, + 1140.933333333338, + 658.6315789473738, + 1140.933333333338, + 633.9298245614082, + 1140.933333333338, + 607.6842105263204, + 1139.3894736842158, + 581.4385964912326, + 1134.7578947368456, + 559.8245614035113, + 1133.2140350877235, + 535.1228070175493, + 1131.6701754386013, + 505.7894736842136, + 1131.6701754386013, + 482.6315789473738, + 1131.6701754386013, + 454.8421052631602, + 1130.1263157894791, + 430.1403508771964, + 1130.1263157894791, + 405.4385964912326, + 1130.1263157894791, + 383.82421875, + 1130.126953125, + 382.28070175438916, + 1113.143859649128, + 380.736842105267, + 1088.4421052631624, + 380.736842105267, + 1056.0210526315823, + 380.736842105267, + 1026.6877192982502, + 379.1929824561448, + 1005.0736842105289, + 374.5614035087765, + 978.8280701754411, + 371.47368421053034, + 949.494736842109, + 371.47368421053034, + 921.705263157899, + 371.47368421053034, + 897.0035087719334, + 371.47368421053034, + 866.1263157894791, + 371.47368421053034, + 842.9684210526357, + 371.47368421053034, + 810.5473684210556, + 371.47368421053034, + 778.1263157894791, + 377.64912280702083, + 751.8807017543913, + 380.736842105267, + 722.5473684210556, + 385.3684210526353, + 693.2140350877235, + 385.3684210526353, + 668.5122807017578, + 386.9122807017575, + 643.8105263157922, + 388.45614035088147, + 619.1087719298266, + 388.45614035088147, + 591.3192982456167, + 388.45614035088147, + 563.5298245614067, + 388.45614035088147, + 535.7403508771968, + 388.45614035088147, + 511.03859649123115, + 386.9122807017575, + 487.88070175439134, + ], + id: 382, + frame: 10, + outside: false, + attributes: [ + { + spec_id: 1, + value: '__undefined__', + }, + { + spec_id: 5, + value: 'non, initialized', + }, + ], + }, + { + type: 'polygon', + occluded: false, + z_order: 2, + points: [ + 502.701171875, + 1093.07421875, + 860.8771929824616, + 443.10877192982844, + 1462.9824561403548, + 1120.8631578947425, + ], + id: 383, + frame: 20, + outside: false, + attributes: [], + }, + { + type: 'polygon', + occluded: false, + z_order: 2, + points: [ + 502.701171875, + 1093.07421875, + 860.8771929824616, + 443.10877192982844, + 1462.9824561403548, + 1120.8631578947425, + ], + id: 384, + frame: 22, + outside: true, + attributes: [], + }, + ], + attributes: [ + { + spec_id: 2, + value: '1', + }, + { + spec_id: 3, + value: 'male', + }, + { + spec_id: 4, + value: 'false', + }, + ], + }, + { + id: 60, + frame: 0, + label_id: 19, + group: 0, + shapes: [ + { + type: 'rectangle', + occluded: false, + z_order: 1, + points: [425.58984375, 540.298828125, 755.9765625, 745.6328125], + id: 379, + frame: 0, + outside: false, + attributes: [ + { + spec_id: 5, + value: 'non, initialized', + }, + { + spec_id: 1, + value: '__undefined__', + }, + ], + }, + { + type: 'rectangle', + occluded: false, + z_order: 1, + points: [238.8000000000011, 498.6000000000022, 546.01171875, 660.720703125], + id: 380, + frame: 10, + outside: false, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 1, + points: [13.3955078125, 447.650390625, 320.6072265624989, 609.7710937499978], + id: 381, + frame: 20, + outside: false, + attributes: [], + }, + ], + attributes: [ + { + spec_id: 2, + value: '1', + }, + { + spec_id: 3, + value: 'male', + }, + { + spec_id: 4, + value: 'false', + }, + ], + }, + ], + }, + 100: { + version: 16, + tags: [], + shapes: [ + { + type: 'rectangle', + occluded: false, + z_order: 1, + points: [387.91, 403.81, 595.14, 712.25], + id: 108, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 2, + points: [783.12, 368.91, 990.35, 677.34], + id: 109, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 3, + points: [1277.1, 239.99, 1484.33, 548.43], + id: 110, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 4, + points: [1420.48, 713.49, 1627.71, 1021.92], + id: 111, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 5, + points: [896.38, 659.27, 1103.61, 967.71], + id: 112, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'polygon', + occluded: false, + z_order: 6, + points: [ + 449.36, + 892.97, + 449.36, + 892.97, + 468.63, + 913.46, + 495.14, + 933.94, + 527.67, + 955.62, + 562.61, + 973.7, + 589.12, + 983.34, + 613.21, + 988.15, + 632.49, + 991.77, + 656.59, + 994.18, + 686.71, + 994.18, + 733.69, + 980.93, + 772.25, + 959.24, + 809.6, + 927.91, + 837.31, + 896.59, + 851.77, + 867.67, + 861.41, + 841.17, + 862.61, + 805.02, + 840.92, + 759.24, + 802.37, + 720.68, + 777.07, + 703.82, + 750.56, + 690.56, + 726.47, + 684.54, + 698.75, + 680.92, + 681.89, + 680.92, + 656.59, + 680.92, + 633.69, + 683.33, + 608.39, + 690.56, + 578.27, + 706.22, + 548.15, + 718.27, + 518.03, + 730.32, + 486.71, + 743.57, + 458.99, + 756.83, + 434.9, + 766.47, + 408.39, + 777.31, + 381.89, + 786.95, + 354.17, + 794.18, + 331.28, + 800.2, + 295.14, + 803.82, + 283.09, + 800.2, + 267.43, + 783.33, + 255.38, + 766.47, + 232.49, + 733.94, + 220.44, + 713.45, + 212.0, + 688.15, + 208.39, + 666.47, + 210.8, + 647.19, + ], + id: 113, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'polygon', + occluded: false, + z_order: 7, + points: [ + 1260.84, + 344.81, + 1260.84, + 344.81, + 1280.11, + 365.29, + 1306.62, + 385.78, + 1339.15, + 407.46, + 1374.09, + 425.53, + 1400.6, + 435.17, + 1424.69, + 439.99, + 1443.97, + 443.61, + 1468.07, + 446.02, + 1498.19, + 446.02, + 1545.18, + 432.76, + 1583.73, + 411.08, + 1621.08, + 379.75, + 1648.79, + 348.43, + 1663.25, + 319.51, + 1672.89, + 293.0, + 1674.09, + 256.86, + 1652.41, + 211.08, + 1613.85, + 172.52, + 1588.55, + 155.65, + 1562.04, + 142.4, + 1537.95, + 136.38, + 1510.24, + 132.76, + 1493.37, + 132.76, + 1468.07, + 132.76, + 1445.18, + 135.17, + 1419.87, + 142.4, + 1389.75, + 158.06, + 1359.63, + 170.11, + 1329.51, + 182.16, + 1298.19, + 195.41, + 1270.48, + 208.67, + 1246.38, + 218.3, + 1219.87, + 229.15, + 1193.37, + 238.79, + 1165.66, + 246.02, + 1142.76, + 252.04, + 1106.62, + 255.65, + 1094.57, + 252.04, + 1078.91, + 235.17, + 1066.86, + 218.3, + 1043.97, + 185.77, + 1031.92, + 165.29, + 1023.49, + 139.99, + 1019.87, + 118.3, + 1022.28, + 99.03, + ], + id: 114, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'polygon', + occluded: false, + z_order: 8, + points: [1113.21, 723.09, 1322.86, 1018.28, 1562.62, 873.7, 1587.92, 641.16, 1267.43, 530.32], + id: 115, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'polyline', + occluded: false, + z_order: 9, + points: [ + 268.63, + 359.23, + 277.07, + 344.78, + 292.73, + 325.5, + 312.01, + 311.04, + 331.28, + 300.2, + 349.36, + 295.38, + 375.86, + 290.56, + 387.91, + 290.56, + 418.03, + 290.56, + 439.72, + 292.97, + 457.79, + 295.38, + 492.73, + 301.4, + 525.26, + 306.22, + 534.9, + 306.22, + 571.04, + 296.58, + 591.53, + 284.54, + 610.8, + 272.49, + 640.92, + 253.21, + 655.38, + 238.75, + ], + id: 116, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'points', + occluded: false, + z_order: 10, + points: [ + 1089.12, + 505.02, + 1178.28, + 543.57, + 1074.66, + 602.61, + 1109.6, + 680.92, + 1172.25, + 631.53, + 1036.11, + 576.1, + 1057.79, + 445.98, + 1185.51, + 400.2, + ], + id: 117, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1565.03, 555.62, 1787.92, 765.26], + id: 118, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 0, + points: [0.0, 0.0, 100.0, 100.0], + id: 119, + frame: 1, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'polygon', + occluded: false, + z_order: 0, + points: [0.0, 0.0, 200.0, 0.0, 100.0, 200.0], + id: 120, + frame: 1, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 121, + frame: 1, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 122, + frame: 1, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 123, + frame: 2, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 124, + frame: 2, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 125, + frame: 3, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 126, + frame: 3, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 127, + frame: 4, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 128, + frame: 4, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 129, + frame: 5, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 130, + frame: 5, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 131, + frame: 6, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 132, + frame: 6, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 133, + frame: 7, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 134, + frame: 7, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: false, + z_order: 11, + points: [1211.6, 500.48, 1434.49, 710.12], + id: 135, + frame: 8, + label_id: 1, + group: 0, + attributes: [], + }, + { + type: 'rectangle', + occluded: true, + z_order: 0, + points: [0.0, 0.0, 200.0, 200.0], + id: 136, + frame: 8, + label_id: 2, + group: 0, + attributes: [], + }, + { + type: 'cuboid', + occluded: false, + z_order: 12, + points: [ + 37.037109375, + 834.1583663313359, + 37.037109375, + 1005.6748046875, + 500.1052119006872, + 850.3421313142153, + 500.1052119006872, + 1021.9585696703798, + 600.6842465753452, + 763.1514501284273, + 600.6842465753452, + 934.6678884845915, + 137.82724152601259, + 747.0278858154179, + 137.82724152601259, + 918.4444406426646, + ], + id: 137, + frame: 0, + label_id: 1, + group: 0, + attributes: [], + }, + ], + tracks: [], + }, }; const jobAnnotationsDummyData = JSON.parse(JSON.stringify(taskAnnotationsDummyData)); const frameMetaDummyData = { - 1: { - "chunk_size": 36, - "size": 9, - "image_quality": 95, - "start_frame": 0, - "stop_frame": 8, - "frame_filter": "", - "frames":[{ - "width": 1920, - "height": 1080 - }, { - "width": 1600, - "height": 1143 - }, { - "width": 1600, - "height": 859 - }, { - "width": 3840, - "height": 2160 - }, { - "width": 2560, - "height": 1920 - }, { - "width": 1920, - "height": 1080 - }, { - "width": 1920, - "height": 1080 - }, { - "width": 700, - "height": 453 - }, { - "width": 1920, - "height": 1200 - }], + 1: { + chunk_size: 36, + size: 9, + image_quality: 95, + start_frame: 0, + stop_frame: 8, + frame_filter: '', + frames: [ + { + width: 1920, + height: 1080, + }, + { + width: 1600, + height: 1143, + }, + { + width: 1600, + height: 859, + }, + { + width: 3840, + height: 2160, + }, + { + width: 2560, + height: 1920, + }, + { + width: 1920, + height: 1080, + }, + { + width: 1920, + height: 1080, + }, + { + width: 700, + height: 453, + }, + { + width: 1920, + height: 1200, + }, + ], }, 2: { - "chunk_size": 36, - "size": 75, - "image_quality": 50, - "start_frame": 0, - "stop_frame": 74, - "frame_filter": "", - "frames": [{ - "width": 1920, - "height": 1080 - }], + chunk_size: 36, + size: 75, + image_quality: 50, + start_frame: 0, + stop_frame: 74, + frame_filter: '', + frames: [ + { + width: 1920, + height: 1080, + }, + ], }, 3: { - "chunk_size": 36, - "size": 5002, - "image_quality": 50, - "start_frame": 0, - "stop_frame": 5001, - "frame_filter": "", - "frames": [{ - "width": 1888, - "height": 1408 - }], + chunk_size: 36, + size: 5002, + image_quality: 50, + start_frame: 0, + stop_frame: 5001, + frame_filter: '', + frames: [ + { + width: 1888, + height: 1408, + }, + ], }, 100: { - "chunk_size": 36, - "size": 9, - "image_quality": 50, - "start_frame": 0, - "stop_frame": 8, - "frame_filter": "", - "frames": [{ - "width": 1920, - "height": 1080 - }, { - "width": 1600, - "height": 1143 - }, { - "width": 1600, - "height": 859 - }, { - "width": 3840, - "height": 2160 - }, { - "width": 2560, - "height": 1920 - }, { - "width": 1920, - "height": 1080 - }, { - "width": 1920, - "height": 1080 - }, { - "width": 700, - "height": 453 - }, { - "width": 1920, - "height": 1200 - }], + chunk_size: 36, + size: 9, + image_quality: 50, + start_frame: 0, + stop_frame: 8, + frame_filter: '', + frames: [ + { + width: 1920, + height: 1080, + }, + { + width: 1600, + height: 1143, + }, + { + width: 1600, + height: 859, + }, + { + width: 3840, + height: 2160, + }, + { + width: 2560, + height: 1920, + }, + { + width: 1920, + height: 1080, + }, + { + width: 1920, + height: 1080, + }, + { + width: 700, + height: 453, + }, + { + width: 1920, + height: 1200, + }, + ], }, 101: { - "chunk_size": 36, - "size": 5002, - "image_quality": 50, - "start_frame": 0, - "stop_frame": 5001, - "frame_filter": "", - "frames": [{ - "width": 1888, - "height": 1408 - }], + chunk_size: 36, + size: 5002, + image_quality: 50, + start_frame: 0, + stop_frame: 5001, + frame_filter: '', + frames: [ + { + width: 1888, + height: 1408, + }, + ], }, 102: { - "chunk_size": 36, - "size": 1, - "image_quality": 50, - "start_frame": 0, - "stop_frame": 0, - "frame_filter": "", - "frames": [{ - "width":1920, - "height":1080 - }], + chunk_size: 36, + size: 1, + image_quality: 50, + start_frame: 0, + stop_frame: 0, + frame_filter: '', + frames: [ + { + width: 1920, + height: 1080, + }, + ], }, -} +}; module.exports = { tasksDummyData, + projectsDummyData, aboutDummyData, shareDummyData, usersDummyData, @@ -2645,5 +2550,4 @@ module.exports = { jobAnnotationsDummyData, frameMetaDummyData, formatsDummyData, -} - +}; diff --git a/cvat-core/tests/mocks/server-proxy.mock.js b/cvat-core/tests/mocks/server-proxy.mock.js index f189e254..d52f3aed 100644 --- a/cvat-core/tests/mocks/server-proxy.mock.js +++ b/cvat-core/tests/mocks/server-proxy.mock.js @@ -1,16 +1,10 @@ -/* - * Copyright (C) 2018 Intel Corporation - * SPDX-License-Identifier: MIT -*/ - -/* eslint import/no-extraneous-dependencies: 0 */ - -/* global - require:false -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const { tasksDummyData, + projectsDummyData, aboutDummyData, formatsDummyData, shareDummyData, @@ -20,6 +14,22 @@ const { frameMetaDummyData, } = require('./dummy-data.mock'); +function QueryStringToJSON(query) { + const pairs = [...new URLSearchParams(query).entries()]; + + const result = {}; + for (const pair of pairs) { + const [key, value] = pair; + if (['id'].includes(key)) { + result[key] = +value; + } else { + result[key] = value; + } + } + + return JSON.parse(JSON.stringify(result)); +} + class ServerProxy { constructor() { async function about() { @@ -34,14 +44,11 @@ class ServerProxy { const components = directory.split('/'); for (const component of components) { - const idx = position.map(x => x.name).indexOf(component); + const idx = position.map((x) => x.name).indexOf(component); if (idx !== -1 && 'children' in position[idx]) { position = position[idx].children; } else { - throw new window.cvat.exceptions.ServerError( - `${component} is not a valid directory`, - 400, - ); + throw new window.cvat.exceptions.ServerError(`${component} is not a valid directory`, 400); } } } @@ -65,23 +72,65 @@ class ServerProxy { return null; } - async function getTasks(filter = '') { - function QueryStringToJSON(query) { - const pairs = [...new URLSearchParams(query).entries()]; - - const result = {}; - for (const pair of pairs) { - const [key, value] = pair; - if (['id'].includes(key)) { - result[key] = +value; - } else { - result[key] = value; + async function getProjects(filter = '') { + const queries = QueryStringToJSON(filter); + const result = projectsDummyData.results.filter((x) => { + for (const key in queries) { + if (Object.prototype.hasOwnProperty.call(queries, key)) { + // TODO: Particular match for some fields is not checked + if (queries[key] !== x[key]) { + return false; + } } } - return JSON.parse(JSON.stringify(result)); + return true; + }); + + return result; + } + + async function saveProject(id, projectData) { + const object = projectsDummyData.results.filter((project) => project.id === id)[0]; + for (const prop in projectData) { + if ( + Object.prototype.hasOwnProperty.call(projectData, prop) + && Object.prototype.hasOwnProperty.call(object, prop) + ) { + object[prop] = projectData[prop]; + } + } + } + + async function createProject(projectData) { + const id = Math.max(...projectsDummyData.results.map((el) => el.id)) + 1; + projectsDummyData.results.push({ + id, + url: `http://localhost:7000/api/v1/projects/${id}`, + name: projectData.name, + owner: 1, + assignee: null, + bug_tracker: projectData.bug_tracker, + created_date: '2019-05-16T13:08:00.621747+03:00', + updated_date: '2019-05-16T13:08:00.621797+03:00', + status: 'annotation', + tasks: [], + labels: JSON.parse(JSON.stringify(projectData.labels)), + }); + + const createdProject = await getProjects(`?id=${id}`); + return createdProject[0]; + } + + async function deleteProject(id) { + const projects = projectsDummyData.results; + const project = projects.filter((el) => el.id === id)[0]; + if (project) { + projects.splice(projects.indexOf(project), 1); } + } + async function getTasks(filter = '') { // Emulation of a query filter const queries = QueryStringToJSON(filter); const result = tasksDummyData.results.filter((x) => { @@ -101,31 +150,36 @@ class ServerProxy { } async function saveTask(id, taskData) { - const object = tasksDummyData.results.filter(task => task.id === id)[0]; + const object = tasksDummyData.results.filter((task) => task.id === id)[0]; for (const prop in taskData) { - if (Object.prototype.hasOwnProperty.call(taskData, prop) - && Object.prototype.hasOwnProperty.call(object, prop)) { + if ( + Object.prototype.hasOwnProperty.call(taskData, prop) + && Object.prototype.hasOwnProperty.call(object, prop) + ) { object[prop] = taskData[prop]; } } } async function createTask(taskData) { - const id = Math.max(...tasksDummyData.results.map(el => el.id)) + 1; + const id = Math.max(...tasksDummyData.results.map((el) => el.id)) + 1; tasksDummyData.results.push({ id, url: `http://localhost:7000/api/v1/tasks/${id}`, name: taskData.name, + project_id: taskData.project_id || null, size: 5000, mode: 'interpolation', - owner: 2, + owner: { + id: 2, + username: 'bsekache', + }, assignee: null, bug_tracker: taskData.bug_tracker, created_date: '2019-05-16T13:08:00.621747+03:00', updated_date: '2019-05-16T13:08:00.621797+03:00', overlap: taskData.overlap ? taskData.overlap : 5, segment_size: taskData.segment_size ? taskData.segment_size : 5000, - z_order: taskData.z_order, flipped: false, status: 'annotation', image_quality: taskData.image_quality, @@ -138,47 +192,55 @@ class ServerProxy { async function deleteTask(id) { const tasks = tasksDummyData.results; - const task = tasks.filter(el => el.id === id)[0]; + const task = tasks.filter((el) => el.id === id)[0]; if (task) { tasks.splice(tasks.indexOf(task), 1); } } async function getJob(jobID) { - const jobs = tasksDummyData.results.reduce((acc, task) => { - for (const segment of task.segments) { - for (const job of segment.jobs) { - const copy = JSON.parse(JSON.stringify(job)); - copy.start_frame = segment.start_frame; - copy.stop_frame = segment.stop_frame; - copy.task_id = task.id; - - acc.push(copy); + const jobs = tasksDummyData.results + .reduce((acc, task) => { + for (const segment of task.segments) { + for (const job of segment.jobs) { + const copy = JSON.parse(JSON.stringify(job)); + copy.start_frame = segment.start_frame; + copy.stop_frame = segment.stop_frame; + copy.task_id = task.id; + + acc.push(copy); + } } - } - return acc; - }, []).filter(job => job.id === jobID); + return acc; + }, []) + .filter((job) => job.id === jobID); - return jobs[0] || { - detail: 'Not found.', - }; + return ( + jobs[0] || { + detail: 'Not found.', + } + ); } async function saveJob(id, jobData) { - const object = tasksDummyData.results.reduce((acc, task) => { - for (const segment of task.segments) { - for (const job of segment.jobs) { - acc.push(job); + const object = tasksDummyData.results + .reduce((acc, task) => { + for (const segment of task.segments) { + for (const job of segment.jobs) { + acc.push(job); + } } - } - return acc; - }, []).filter(job => job.id === id)[0]; + return acc; + }, []) + .filter((job) => job.id === id)[0]; for (const prop in jobData) { - if (Object.prototype.hasOwnProperty.call(jobData, prop) - && Object.prototype.hasOwnProperty.call(object, prop)) { + if ( + Object.prototype.hasOwnProperty.call(jobData, prop) + && Object.prototype.hasOwnProperty.call(object, prop) + ) { object[prop] = jobData[prop]; } } @@ -224,10 +286,13 @@ class ServerProxy { if (action === 'create') { let idGenerator = 1000; - data.tracks.concat(data.tags).concat(data.shapes).map((el) => { - el.id = ++idGenerator; - return el; - }); + data.tracks + .concat(data.tags) + .concat(data.shapes) + .map((el) => { + el.id = ++idGenerator; + return el; + }); return data; } @@ -243,63 +308,74 @@ class ServerProxy { return null; } - Object.defineProperties(this, Object.freeze({ - server: { - value: Object.freeze({ - about, - share, - formats, - exception, - login, - logout, - }), - writable: false, - }, - - tasks: { - value: Object.freeze({ - getTasks, - saveTask, - createTask, - deleteTask, - }), - writable: false, - }, - - jobs: { - value: Object.freeze({ - getJob, - saveJob, - }), - writable: false, - }, - - users: { - value: Object.freeze({ - getUsers, - getSelf, - }), - writable: false, - }, - - frames: { - value: Object.freeze({ - getData, - getMeta, - getPreview, - }), - writable: false, - }, - - annotations: { - value: { - updateAnnotations, - getAnnotations, + Object.defineProperties( + this, + Object.freeze({ + server: { + value: Object.freeze({ + about, + share, + formats, + exception, + login, + logout, + }), + writable: false, + }, + + projects: { + value: Object.freeze({ + get: getProjects, + save: saveProject, + create: createProject, + delete: deleteProject, + }), + writable: false, + }, + + tasks: { + value: Object.freeze({ + getTasks, + saveTask, + createTask, + deleteTask, + }), + writable: false, + }, + + jobs: { + value: Object.freeze({ + get: getJob, + save: saveJob, + }), + writable: false, + }, + + users: { + value: Object.freeze({ + get: getUsers, + self: getSelf, + }), + writable: false, + }, + + frames: { + value: Object.freeze({ + getData, + getMeta, + getPreview, + }), + writable: false, + }, + + annotations: { + value: { + updateAnnotations, + getAnnotations, + }, }, - // To implement on of important tests - writable: true, - }, - })); + }), + ); } } diff --git a/cvat-core/webpack.config.js b/cvat-core/webpack.config.js index 99b9e64d..6fcc47f5 100644 --- a/cvat-core/webpack.config.js +++ b/cvat-core/webpack.config.js @@ -1,6 +1,9 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + /* global - require:true, - __dirname:true, + __dirname:true */ const path = require('path'); @@ -16,10 +19,12 @@ const nodeConfig = { libraryTarget: 'commonjs', }, module: { - rules: [{ - test: /.js?$/, - exclude: /node_modules/, - }], + rules: [ + { + test: /.js?$/, + exclude: /node_modules/, + }, + ], }, stats: { warnings: false, @@ -40,40 +45,46 @@ const webConfig = { libraryTarget: 'window', }, module: { - rules: [{ - test: /.js?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: [ - ['@babel/preset-env', { - targets: '> 2.5%', - }], - ], - sourceType: 'unambiguous', + rules: [ + { + test: /.js?$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: [ + [ + '@babel/preset-env', + { + targets: '> 2.5%', + }, + ], + ], + sourceType: 'unambiguous', + }, }, }, - }, { - test: /3rdparty\/.*\.worker\.js$/, - use: { - loader: 'worker-loader', - options: { - publicPath: '/static/engine/js/3rdparty/', - name: '[name].[contenthash].js', + { + test: /3rdparty\/.*\.worker\.js$/, + use: { + loader: 'worker-loader', + options: { + publicPath: '/static/engine/js/3rdparty/', + name: '[name].[contenthash].js', + }, }, }, - }, { - test: /\.worker\.js$/, - exclude: /3rdparty/, - use: { - loader: 'worker-loader', - options: { - publicPath: '/static/engine/js/', - name: '[name].[contenthash].js', + { + test: /\.worker\.js$/, + exclude: /3rdparty/, + use: { + loader: 'worker-loader', + options: { + publicPath: '/static/engine/js/', + name: '[name].[contenthash].js', + }, }, }, - }, ], }, }; diff --git a/cvat-data/.eslintignore b/cvat-data/.eslintignore index dbec6390..225f7134 100644 --- a/cvat-data/.eslintignore +++ b/cvat-data/.eslintignore @@ -1 +1,2 @@ **/3rdparty/*.js +webpack.config.js diff --git a/cvat-data/.eslintrc.js b/cvat-data/.eslintrc.js index 3dca50a3..e0cb896f 100644 --- a/cvat-data/.eslintrc.js +++ b/cvat-data/.eslintrc.js @@ -1,56 +1,43 @@ -/* - * Copyright (C) 2018-2020 Intel Corporation - * - * SPDX-License-Identifier: MIT - */ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT module.exports = { - "env": { - "node": false, - "browser": true, - "es6": true, - "jquery": true, - "qunit": true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module', + ecmaVersion: 2018, }, - "parserOptions": { - "parser": "babel-eslint", - "sourceType": "module", - "ecmaVersion": 2018, - }, - "plugins": [ - "security", - "no-unsanitized", - "no-unsafe-innerhtml", - ], - "extends": [ - "eslint:recommended", - "plugin:security/recommended", - "plugin:no-unsanitized/DOM", - "airbnb-base", - ], - "rules": { - "no-await-in-loop": [0], - "global-require": [0], - "no-new": [0], - "class-methods-use-this": [0], - "no-restricted-properties": [0, { - "object": "Math", - "property": "pow", - }], - "no-plusplus": [0], - "no-param-reassign": [0], - "no-underscore-dangle": ["error", { "allowAfterThis": true }], - "no-restricted-syntax": [0, {"selector": "ForOfStatement"}], - "no-continue": [0], - "no-unsafe-innerhtml/no-unsafe-innerhtml": 1, + plugins: ['security', 'no-unsanitized', 'no-unsafe-innerhtml'], + extends: ['eslint:recommended', 'plugin:security/recommended', 'plugin:no-unsanitized/DOM', 'airbnb-base'], + rules: { + 'no-await-in-loop': [0], + 'global-require': [0], + 'no-new': [0], + 'class-methods-use-this': [0], + 'no-restricted-properties': [ + 0, + { + object: 'Math', + property: 'pow', + }, + ], + 'no-plusplus': [0], + 'no-param-reassign': [0], + 'no-underscore-dangle': ['error', { allowAfterThis: true }], + 'no-restricted-syntax': [0, { selector: 'ForOfStatement' }], + 'no-continue': [0], + 'no-unsafe-innerhtml/no-unsafe-innerhtml': 1, // This rule actual for user input data on the node.js environment mainly. - "security/detect-object-injection": 0, - "indent": ["warn", 4], - "no-useless-constructor": 0, - "func-names": [0], - "valid-typeof": [0], - "no-console": [0], // this rule deprecates console.log, console.warn etc. because "it is not good in production code" - "max-classes-per-file": [0], - "quotes": ["warn", "single"], + 'security/detect-object-injection': 0, + indent: ['warn', 4], + 'no-useless-constructor': 0, + 'func-names': [0], + 'valid-typeof': [0], + 'no-console': [0], + 'max-classes-per-file': [0], + 'max-len': ['error', { code: 120 }], + quotes: ['error', 'single'], + 'operator-linebreak': ['error', 'after'], }, }; diff --git a/cvat-data/README.md b/cvat-data/README.md index 1d356c6f..96baf650 100644 --- a/cvat-data/README.md +++ b/cvat-data/README.md @@ -7,8 +7,9 @@ npm run server # run debug server ``` ## Versioning + If you make changes in this package, please do following: -- After not important changes (typos, backward compatible bug fixes, refactoring) do: ``npm version patch`` -- After changing API (backward compatible new features) do: ``npm version minor`` -- After changing API (changes that break backward compatibility) do: ``npm version major`` +- After not important changes (typos, backward compatible bug fixes, refactoring) do: `npm version patch` +- After changing API (backward compatible new features) do: `npm version minor` +- After changing API (changes that break backward compatibility) do: `npm version major` diff --git a/cvat-data/package-lock.json b/cvat-data/package-lock.json index f392ce8e..10348522 100644 --- a/cvat-data/package-lock.json +++ b/cvat-data/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-data", - "version": "1.0.1", + "version": "1.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1239,9 +1239,19 @@ "dev": true }, "async-mutex": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.1.4.tgz", - "integrity": "sha512-zVWTmAnxxHaeB2B1te84oecI8zTDJ/8G49aVBblRX6be0oq6pAybNcUSxwfgVOmOjSCvN4aYZAqwtyNI8e1YGw==" + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.6.tgz", + "integrity": "sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" + } + } }, "atob": { "version": "2.1.2", @@ -2507,11 +2517,6 @@ "event-emitter": "~0.3.5" } }, - "es6-promise": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" - }, "es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -5044,21 +5049,42 @@ "dev": true }, "jszip": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", - "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", + "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", "requires": { - "core-js": "~2.3.0", - "es6-promise": "~3.0.2", - "lie": "~3.1.0", + "lie": "~3.3.0", "pako": "~1.0.2", - "readable-stream": "~2.0.6" + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" }, "dependencies": { - "core-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", - "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" + "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==" + }, + "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" + } } } }, @@ -5088,9 +5114,9 @@ } }, "lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "requires": { "immediate": "~3.0.5" } @@ -6086,7 +6112,8 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true }, "progress": { "version": "2.0.3", @@ -6304,6 +6331,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -6637,8 +6665,7 @@ "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 + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -6701,6 +6728,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -7125,7 +7157,8 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true }, "strip-ansi": { "version": "3.0.1", diff --git a/cvat-data/package.json b/cvat-data/package.json index 5c42155e..20566801 100644 --- a/cvat-data/package.json +++ b/cvat-data/package.json @@ -1,6 +1,6 @@ { "name": "cvat-data", - "version": "1.0.1", + "version": "1.0.2", "description": "", "main": "src/js/cvat-data.js", "devDependencies": { @@ -21,8 +21,8 @@ "worker-loader": "^2.0.0" }, "dependencies": { - "async-mutex": "^0.1.4", - "jszip": "3.1.5" + "async-mutex": "^0.2.6", + "jszip": "3.5.0" }, "scripts": { "patch": "cd src/js && patch --dry-run --forward -p0 < 3rdparty_patch.diff >> /dev/null && patch -p0 < 3rdparty_patch.diff; true", diff --git a/cvat-data/src/js/cvat-data.js b/cvat-data/src/js/cvat-data.js index 86a0a6d0..1732c347 100644 --- a/cvat-data/src/js/cvat-data.js +++ b/cvat-data/src/js/cvat-data.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:true -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const { Mutex } = require('async-mutex'); // eslint-disable-next-line max-classes-per-file @@ -19,15 +14,14 @@ const BlockType = Object.freeze({ }); class FrameProvider { - constructor(blockType, blockSize, cachedBlockCount, - decodedBlocksCacheSize = 5, maxWorkerThreadCount = 2) { + constructor(blockType, blockSize, cachedBlockCount, decodedBlocksCacheSize = 5, maxWorkerThreadCount = 2) { this._frames = {}; this._cachedBlockCount = Math.max(1, cachedBlockCount); // number of stored blocks this._decodedBlocksCacheSize = decodedBlocksCacheSize; this._blocksRanges = []; this._blocks = {}; - this._blockSize = blockSize; this._running = false; + this._blockSize = blockSize; this._blockType = blockType; this._currFrame = -1; this._requestedBlockDecode = null; @@ -42,15 +36,14 @@ class FrameProvider { } async _worker() { - if (this._requestedBlockDecode !== null - && this._decodeThreadCount < this._maxWorkerThreadCount) { + if (this._requestedBlockDecode !== null && this._decodeThreadCount < this._maxWorkerThreadCount) { await this.startDecode(); } this._timerId = setTimeout(this._worker.bind(this), 100); } isChunkCached(start, end) { - return (`${start}:${end}` in this._blocksRanges); + return `${start}:${end}` in this._blocksRanges; } /* This method removes extra data from a cache when memory overflow */ @@ -68,8 +61,10 @@ class FrameProvider { const distance = Math.floor(this._decodedBlocksCacheSize / 2); for (let i = 0; i < this._blocksRanges.length; i++) { const [start, end] = this._blocksRanges[i].split(':').map((el) => +el); - if (end < this._currFrame - distance * this._blockSize - || start > this._currFrame + distance * this._blockSize) { + if ( + end < this._currFrame - distance * this._blockSize || + start > this._currFrame + distance * this._blockSize + ) { for (let j = start; j <= end; j++) { delete this._frames[j]; } @@ -81,8 +76,7 @@ class FrameProvider { const release = await this._mutex.acquire(); try { if (this._requestedBlockDecode !== null) { - if (start === this._requestedBlockDecode.start - && end === this._requestedBlockDecode.end) { + if (start === this._requestedBlockDecode.start && end === this._requestedBlockDecode.end) { this._requestedBlockDecode.resolveCallback = resolveCallback; this._requestedBlockDecode.rejectCallback = rejectCallback; } else if (this._requestedBlockDecode.rejectCallback) { @@ -158,8 +152,7 @@ class FrameProvider { } static cropImage(imageBuffer, imageWidth, imageHeight, xOffset, yOffset, width, height) { - if (xOffset === 0 && width === imageWidth - && yOffset === 0 && height === imageHeight) { + if (xOffset === 0 && width === imageWidth && yOffset === 0 && height === imageHeight) { return new ImageData(new Uint8ClampedArray(imageBuffer), width, height); } const source = new Uint32Array(imageBuffer); @@ -170,11 +163,7 @@ class FrameProvider { const rgbaInt8Clamped = new Uint8ClampedArray(buffer); if (imageWidth === width) { - return new ImageData( - new Uint8ClampedArray(imageBuffer, yOffset * 4, bufferSize), - width, - height, - ); + return new ImageData(new Uint8ClampedArray(imageBuffer, yOffset * 4, bufferSize), width, height); } let writeIdx = 0; @@ -207,14 +196,20 @@ class FrameProvider { let index = start; worker.onmessage = (e) => { - if (e.data.consoleLog) { // ignore initialization message + if (e.data.consoleLog) { + // ignore initialization message return; } const scaleFactor = Math.ceil(this._height / e.data.height); this._frames[index] = FrameProvider.cropImage( - e.data.buf, e.data.width, e.data.height, 0, 0, - Math.floor(width / scaleFactor), Math.floor(height / scaleFactor), + e.data.buf, + e.data.width, + e.data.height, + 0, + 0, + Math.floor(width / scaleFactor), + Math.floor(height / scaleFactor), ); if (this._decodingBlocks[`${start}:${end}`].resolveCallback) { @@ -302,10 +297,10 @@ class FrameProvider { // but document.createElement doesn't work in worker // so, we get raw data and decode it here, no other way - const createImageBitmap = async function(blob) { - return new Promise((resolve,reject) => { - let img = document.createElement('img'); - img.addEventListener('load', function() { + const createImageBitmap = async function (blob) { + return new Promise((resolve) => { + const img = document.createElement('img'); + img.addEventListener('load', function () { resolve(this); }); img.src = URL.createObjectURL(blob); @@ -322,9 +317,7 @@ class FrameProvider { } if (event.data.index in this._promisedFrames) { - this._promisedFrames[event.data.index].resolve( - this._frames[event.data.index], - ); + this._promisedFrames[event.data.index].resolve(this._frames[event.data.index]); delete this._promisedFrames[event.data.index]; } @@ -357,9 +350,7 @@ class FrameProvider { Is an array of strings like "start:end" */ get cachedFrames() { - return [...this._blocksRanges].sort( - (a, b) => a.split(':')[0] - b.split(':')[0], - ); + return [...this._blocksRanges].sort((a, b) => a.split(':')[0] - b.split(':')[0]); } } diff --git a/cvat-data/src/js/unzip_imgs.worker.js b/cvat-data/src/js/unzip_imgs.worker.js index 68d0b2a5..e1244817 100644 --- a/cvat-data/src/js/unzip_imgs.worker.js +++ b/cvat-data/src/js/unzip_imgs.worker.js @@ -1,11 +1,6 @@ -/* -* Copyright (C) 2019 Intel Corporation -* SPDX-License-Identifier: MIT -*/ - -/* global - require:true -*/ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT const JSZip = require('jszip'); @@ -19,24 +14,27 @@ onmessage = (e) => { _zip.forEach((relativePath) => { const fileIndex = index++; if (fileIndex <= end) { - _zip.file(relativePath).async('blob').then((fileData) => { - if (self.createImageBitmap) { - createImageBitmap(fileData).then((img) => { + _zip.file(relativePath) + .async('blob') + .then((fileData) => { + // eslint-disable-next-line no-restricted-globals + if (self.createImageBitmap) { + createImageBitmap(fileData).then((img) => { + postMessage({ + fileName: relativePath, + index: fileIndex, + data: img, + }); + }); + } else { postMessage({ fileName: relativePath, index: fileIndex, - data: img, + data: fileData, + isRaw: true, }); - }); - } else { - postMessage({ - fileName: relativePath, - index: fileIndex, - data: fileData, - isRaw: true, - }); - } - }); + } + }); } }); }); diff --git a/cvat-data/webpack.config.js b/cvat-data/webpack.config.js index 298f6747..a286cab0 100644 --- a/cvat-data/webpack.config.js +++ b/cvat-data/webpack.config.js @@ -1,6 +1,9 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + /* global - require:true, - __dirname:true, + __dirname:true */ const path = require('path'); @@ -27,14 +30,18 @@ const cvatData = { loader: 'babel-loader', options: { presets: [ - ['@babel/preset-env', { - targets: '> 2.5%', // https://github.com/browserslist/browserslist - }], + [ + '@babel/preset-env', + { + targets: '> 2.5%', // https://github.com/browserslist/browserslist + }, + ], ], sourceType: 'unambiguous', }, }, - }, { + }, + { test: /\.worker\.js$/, exclude: /3rdparty/, use: { @@ -44,7 +51,8 @@ const cvatData = { name: '[name].[contenthash].js', }, }, - }, { + }, + { test: /3rdparty\/.*\.worker\.js$/, use: { loader: 'worker-loader', @@ -56,11 +64,7 @@ const cvatData = { }, ], }, - plugins: [ - new CopyPlugin([ - './src/js/3rdparty/avc.wasm', - ]), - ], + plugins: [new CopyPlugin(['./src/js/3rdparty/avc.wasm'])], }; module.exports = cvatData; diff --git a/cvat-ui/.eslintignore b/cvat-ui/.eslintignore new file mode 100644 index 00000000..6de001d8 --- /dev/null +++ b/cvat-ui/.eslintignore @@ -0,0 +1 @@ +webpack.config.js diff --git a/cvat-ui/.eslintrc.js b/cvat-ui/.eslintrc.js index 8c0c5b35..62da6905 100644 --- a/cvat-ui/.eslintrc.js +++ b/cvat-ui/.eslintrc.js @@ -3,47 +3,62 @@ // SPDX-License-Identifier: MIT module.exports = { - 'env': { - 'node': true, - 'browser': true, - 'es6': true, + env: { + node: true, }, - 'parserOptions': { - 'parser': '@typescript-eslint/parser', - 'ecmaVersion': 6, - 'project': './tsconfig.json', + parserOptions: { + parser: '@typescript-eslint/parser', + ecmaVersion: 6, + project: './tsconfig.json', }, - 'plugins': [ - '@typescript-eslint', - 'import', - ], - 'ignorePatterns': ['*.svg', '*.scss'], - 'extends': [ + plugins: ['@typescript-eslint', 'import'], + extends: [ 'plugin:@typescript-eslint/recommended', 'airbnb-typescript', 'plugin:import/errors', 'plugin:import/warnings', 'plugin:import/typescript', ], - 'rules': { + rules: { '@typescript-eslint/indent': ['warn', 4], + '@typescript-eslint/lines-between-class-members': 0, + 'react/static-property-placement': ['error', 'static public field'], 'react/jsx-indent': ['warn', 4], 'react/jsx-indent-props': ['warn', 4], 'react/jsx-props-no-spreading': 0, + 'implicit-arrow-linebreak': 0, 'jsx-quotes': ['error', 'prefer-single'], 'arrow-parens': ['error', 'always'], '@typescript-eslint/no-explicit-any': [0], '@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }], - 'no-restricted-syntax': [0, {'selector': 'ForOfStatement'}], + 'no-restricted-syntax': [0, { selector: 'ForOfStatement' }], 'no-plusplus': [0], - 'lines-between-class-members': 0, + 'lines-between-class-members': [0], 'react/no-did-update-set-state': 0, // https://github.com/airbnb/javascript/issues/1875 + quotes: ['error', 'single'], + 'max-len': ['error', { code: 120, ignoreStrings: true }], + 'func-names': ['warn', 'never'], + 'operator-linebreak': ['error', 'after'], + 'react/require-default-props': 'off', + 'react/no-unused-prop-types': 'off', + 'react/no-array-index-key': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/ban-types': [ + 'error', + { + types: { + '{}': false, // TODO: try to fix with Record + object: false, // TODO: try to fix with Record + Function: false, // TODO: try to fix somehow + }, + }, + ], }, - 'settings': { + settings: { 'import/resolver': { - 'typescript': { - 'directory': './tsconfig.json' - } + node: { + paths: ['src'], + }, }, }, }; diff --git a/cvat-ui/.gitignore b/cvat-ui/.gitignore index 4952a5fa..62ba6cdf 100644 --- a/cvat-ui/.gitignore +++ b/cvat-ui/.gitignore @@ -4,4 +4,5 @@ /dist /build /yarn.lock +.eslintcache diff --git a/cvat-ui/README.md b/cvat-ui/README.md index 90f4b1db..c32879e6 100644 --- a/cvat-ui/README.md +++ b/cvat-ui/README.md @@ -1,23 +1,26 @@ # cvat-ui module ## Description + This is a client UI for Computer Vision Annotation Tool based on React, Redux and Antd ## Versioning + If you make changes in this package, please do following: -- After not important changes (typos, bug fixes, refactoring) do: ``npm version patch`` -- After adding new features do: ``npm version minor`` -- After significant UI redesign do: ``npm version major`` +- After not important changes (typos, bug fixes, refactoring) do: `npm version patch` +- After adding new features do: `npm version minor` +- After significant UI redesign do: `npm version major` -Important: If you have changed versions for ``cvat-core``, ``cvat-canvas``, ``cvat-data``, -you also need to do ``npm install`` to update ``package-lock.json`` +Important: If you have changed versions for `cvat-core`, `cvat-canvas`, `cvat-data`, +you also need to do `npm install` to update `package-lock.json` ## Commands + - Installing dependencies: ```bash -cd ../cvat-core && npm install && cd - && npm install +cd ../cvat-core && npm ci && cd - && npm ci ``` - Running development UI server with autorebuild on change @@ -26,12 +29,12 @@ cd ../cvat-core && npm install && cd - && npm install npm start ``` -- Building the module from sources in the ```dist``` directory: +- Building the module from sources in the `dist` directory: ```bash npm run build npm run build -- --mode=development # without a minification ``` -Important: You also have to run CVAT REST API server (please read ``CONTRIBUTING.md``) +Important: You also have to run CVAT REST API server (please read `CONTRIBUTING.md`) to correct working since UI gets all necessary data (tasks, users, annotations) from there diff --git a/cvat-ui/package-lock.json b/cvat-ui/package-lock.json index fbbd3cea..c0668d70 100644 --- a/cvat-ui/package-lock.json +++ b/cvat-ui/package-lock.json @@ -1,43 +1,80 @@ { "name": "cvat-ui", - "version": "1.8.4", + "version": "1.13.3", "lockfileVersion": 1, "requires": true, "dependencies": { "@ant-design/colors": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.2.2.tgz", - "integrity": "sha512-YKgNbG2dlzqMhA9NtI3/pbY16m3Yl/EeWBRa+lB1X1YaYxHrxNexiQYCLTWO/uDvAjLFMEDU+zR901waBtMtjQ==", - "requires": { - "tinycolor2": "^1.4.1" - } - }, - "@ant-design/create-react-context": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@ant-design/create-react-context/-/create-react-context-0.2.5.tgz", - "integrity": "sha512-1rMAa4qgP2lfl/QBH9i78+Gjxtj9FTMpMyDGZsEBW5Kih72EuUo9958mV8PgpRkh4uwPSQ7vVZWXeyNZXVAFDg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-5.0.0.tgz", + "integrity": "sha512-Pe1rYorgVC1v4f+InDXvIlQH715pO1g7BsOhy/ehX/U6ebPKqojmkYJKU3lF+84Zmvyar7ngZ28hesAa1nWjLg==", "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" + "@ctrl/tinycolor": "^3.1.6" } }, "@ant-design/css-animation": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@ant-design/css-animation/-/css-animation-1.7.2.tgz", - "integrity": "sha512-bvVOe7A+r7lws58B7r+fgnQDK90cV45AXuvGx6i5CCSX1W/M3AJnHsNggDANBxEtWdNdFWcDd5LorB+RdSIlBw==" + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@ant-design/css-animation/-/css-animation-1.7.3.tgz", + "integrity": "sha512-LrX0OGZtW+W6iLnTAqnTaoIsRelYeuLZWsrmBJFUXDALQphPsN8cE5DCsmoSlL0QYb94BQxINiuS70Ar/8BNgA==" }, "@ant-design/icons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-2.1.1.tgz", - "integrity": "sha512-jCH+k2Vjlno4YWl6g535nHR09PwCEmTBKAG6VqF+rhkrSPRLfgpU2maagwbZPLjaHuU5Jd1DFQ2KJpQuI6uG8w==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.3.0.tgz", + "integrity": "sha512-UoIbw4oz/L/msbkgqs2nls2KP7XNKScOxVR54wRrWwnXOzJaGNwwSdYjHQz+5ETf8C53YPpzMOnRX99LFCdeIQ==", + "requires": { + "@ant-design/colors": "^5.0.0", + "@ant-design/icons-svg": "^4.0.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "insert-css": "^2.0.0", + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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==" + } + } }, - "@ant-design/icons-react": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons-react/-/icons-react-2.0.1.tgz", - "integrity": "sha512-r1QfoltMuruJZqdiKcbPim3d8LNsVPB733U0gZEUSxBLuqilwsW28K2rCTWSMTjmFX7Mfpf+v/wdiFe/XCqThw==", + "@ant-design/icons-svg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.1.0.tgz", + "integrity": "sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ==" + }, + "@ant-design/react-slick": { + "version": "0.27.14", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.27.14.tgz", + "integrity": "sha512-s6JVexqFmU5rs5Pm828ojtm5rCp8jDXyrc5OxEtCE2z58SIyQlkpnU9BJh98LEeBZyj02WFkGN8CWpSaD+G4PA==", "requires": { - "@ant-design/colors": "^3.1.0", - "babel-runtime": "^6.26.0" + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "lodash": "^4.17.15", + "resize-observer-polyfill": "^1.5.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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==" + } } }, "@babel/code-frame": { @@ -278,6 +315,28 @@ "@babel/types": "^7.0.0" } }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, "@babel/helper-split-export-declaration": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", @@ -287,6 +346,12 @@ "@babel/types": "^7.4.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", @@ -388,6 +453,25 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" } }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz", @@ -453,6 +537,23 @@ "@babel/helper-plugin-utils": "^7.0.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" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-typescript": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", @@ -918,19 +1019,19 @@ } }, "@babel/runtime-corejs3": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.7.4.tgz", - "integrity": "sha512-BBIEhzk8McXDcB3IbOi8zQPzzINUp4zcLesVlBSOcyGhzPUU8Xezk5GAG7Sy5GVhGmAO0zGd2qRSeY2g4Obqxw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.1.tgz", + "integrity": "sha512-umhPIcMrlBZ2aTWlWjUseW9LjQKxi1dpFlQS8DzsxB//5K+u6GLTC/JliPKHsd5kJVPIU6X/Hy0YvWOYPcMxBw==", "dev": true, "requires": { "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.2" + "regenerator-runtime": "^0.13.4" }, "dependencies": { "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true } } @@ -980,30 +1081,116 @@ "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", "dev": true }, + "@ctrl/tinycolor": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.2.0.tgz", + "integrity": "sha512-cP1tbXA1qJp/er2CJaO+Pbe38p7RlhV9WytUxUe79xj++Q6s/jKVvzJ9U2dF9f1/lZAdG+j94A38CsNR+uW4gw==" + }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, "@icons/material": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==" }, - "@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 + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@types/cookie": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", + "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" + }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } @@ -1023,9 +1210,9 @@ } }, "@types/json-schema": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", - "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, "@types/json5": { @@ -1034,6 +1221,11 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/lodash": { + "version": "4.14.165", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", + "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==" + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1041,15 +1233,15 @@ "dev": true }, "@types/node": { - "version": "12.12.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.3.tgz", - "integrity": "sha512-opgSsy+cEF9N8MgaVPnWVtdJ3o4mV2aMHvDq7thkQUFt0EuOHJon4rQpJfhjmNHB+ikl0Cd6WhWIErOyQ+f7tw==", + "version": "14.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz", + "integrity": "sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg==", "dev": true }, "@types/platform": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.2.tgz", - "integrity": "sha512-Tn6OuJDAG7bJbyi4R7HqcxXp1w2lmIxVXqyNhPt1Bm0FO2EWIi3CI87JVzF7ncqK0ZMPuUycS3wTMIk85EeF1Q==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.3.tgz", + "integrity": "sha512-1fuOulBHWIxAPLBtLms+UtbeRDt6rL7gP5R+Yugfzdg+poCLxXqXTE8i+FpYeiytGRLUEtnFkjsY/j+usbQBqw==" }, "@types/prop-types": { "version": "15.7.3", @@ -1063,34 +1255,35 @@ "dev": true }, "@types/react": { - "version": "16.9.11", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.11.tgz", - "integrity": "sha512-UBT4GZ3PokTXSWmdgC/GeCGEJXE5ofWyibCcecRLUVN2ZBpXQGVgQGtG2foS7CrTKFKlQVVswLvf7Js6XA/CVQ==", + "version": "16.14.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.2.tgz", + "integrity": "sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ==", "requires": { "@types/prop-types": "*", - "csstype": "^2.2.0" + "csstype": "^3.0.2" } }, "@types/react-color": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.2.tgz", - "integrity": "sha512-FhrRy0xEYEpysl1iKL11ynJc79H6ztyYc4xD1pliZyygEChleTlHGohb/bClTYPN8XeSw6yaz45l3YW5SGYftQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.4.tgz", + "integrity": "sha512-EswbYJDF1kkrx93/YU+BbBtb46CCtDMvTiGmcOa/c5PETnwTiSWoseJ1oSWeRl/4rUXkhME9bVURvvPg0W5YQw==", "requires": { - "@types/react": "*" + "@types/react": "*", + "@types/reactcss": "*" } }, "@types/react-dom": { - "version": "16.9.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.3.tgz", - "integrity": "sha512-FUuZKXPr9qlzUT9lhuzrZgLjH63TvNn28Ch3MvKG4B+F52zQtO8DtE0Opbncy3xaucNZM2WIPfuNTgkbKx5Brg==", + "version": "16.9.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.10.tgz", + "integrity": "sha512-ItatOrnXDMAYpv6G8UCk2VhbYVTjZT9aorLtA/OzDN9XJ2GKcfam68jutoAcILdRjsRUO8qb7AmyObF77Q8QFw==", "requires": { - "@types/react": "*" + "@types/react": "^16" } }, "@types/react-redux": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.5.tgz", - "integrity": "sha512-ZoNGQMDxh5ENY7PzU7MVonxDzS1l/EWiy8nUhDqxFqUZn4ovboCyvk4Djf68x6COb7vhGTKjyjxHxtFdAA5sUA==", + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.11.tgz", + "integrity": "sha512-OjaFlmqy0CRbYKBoaWF84dub3impqnLJUrz4u8PRjDzaa4n1A2cVmjMV81shwXyAD5x767efhA8STFGJz/r1Zg==", "requires": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -1099,18 +1292,18 @@ } }, "@types/react-router": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.2.tgz", - "integrity": "sha512-euC3SiwDg3NcjFdNmFL8uVuAFTpZJm0WMFUw+4eXMUnxa7M9RGFEG0szt0z+/Zgk4G2k9JBFhaEnY64RBiFmuw==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.8.tgz", + "integrity": "sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg==", "requires": { "@types/history": "*", "@types/react": "*" } }, "@types/react-router-dom": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.1.tgz", - "integrity": "sha512-yXqWGaehta/cdmjvEQfCbHFX6l1c7QHuE5n2OfhcJ33ufbt55xhAKqQ0BmT24YM3s7OKwrrUUgY3FaSzO7be3Q==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.6.tgz", + "integrity": "sha512-gjrxYqxz37zWEdMVvQtWPFMFj1dRDb4TGOcgyOfSXTrEXdF92L00WE3C471O3TV/RF1oskcStkXsOU0Ete4s/g==", "requires": { "@types/history": "*", "@types/react": "*", @@ -1118,146 +1311,321 @@ } }, "@types/react-share": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/react-share/-/react-share-3.0.1.tgz", - "integrity": "sha512-9SmC9TBOBKXvu7Otfl0Zl/1OqjPocmhEMwJnVspG3i1AW/wyKkemkL+Jshpp+tSxfcz76BbbzlBJVbsojYZHvA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/react-share/-/react-share-3.0.3.tgz", + "integrity": "sha512-GpKAVNbwMBgad0995uVLkOdKWp3CjCrvIeUt4qZcsrgLtf7SMR7gIfMgC9X2rsfLgN6saT/nr2T4QLJE9cCZiA==", "requires": { "@types/react": "*" } }, - "@types/react-slick": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.4.tgz", - "integrity": "sha512-vXoIy4GUfB7/YgqubR4H7RALo+pRdMYCeLgWwV3MPwl5pggTlEkFBTF19R7u+LJc85uMqC7RfsbkqPLMQ4ab+A==", + "@types/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-d2gQQ0IL6hXLnoRfVYZukQNWHuVsE75DzFTLPUuyyEhJS8G2VvlE+qfQQ91SJjaMqlURRCNIsX7Jcsw6cEuJlA==", "requires": { "@types/react": "*" } }, "@types/redux-logger": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.7.tgz", - "integrity": "sha512-oV9qiCuowhVR/ehqUobWWkXJjohontbDGLV88Be/7T4bqMQ3kjXwkFNL7doIIqlbg3X2PC5WPziZ8/j/QHNQ4A==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.8.tgz", + "integrity": "sha512-zM+cxiSw6nZtRbxpVp9SE3x/X77Z7e7YAfHD1NkxJyJbAGSXJGF0E9aqajZfPOa/sTYnuwutmlCldveExuCeLw==", "requires": { - "redux": "^3.6.0" - }, - "dependencies": { - "redux": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", - "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", - "requires": { - "lodash": "^4.2.1", - "lodash-es": "^4.2.1", - "loose-envify": "^1.1.0", - "symbol-observable": "^1.0.3" - } - } + "redux": "^4.0.0" } }, "@typescript-eslint/eslint-plugin": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.2.tgz", - "integrity": "sha512-HX2qOq2GOV04HNrmKnTpSIpHjfl7iwdXe3u/Nvt+/cpmdvzYvY0NHSiTkYN257jHnq4OM/yo+OsFgati+7LqJA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.5.0.tgz", + "integrity": "sha512-mjb/gwNcmDKNt+6mb7Aj/TjKzIJjOPcoCJpjBQC9ZnTRnBt1p4q5dJSSmIqAtsZ/Pff5N+hJlbiPc5bl6QN4OQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.19.2", - "eslint-utils": "^1.4.3", + "@typescript-eslint/experimental-utils": "4.5.0", + "@typescript-eslint/scope-manager": "4.5.0", + "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", + "semver": "^7.3.2", "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.5.0.tgz", + "integrity": "sha512-C0cEO0cTMPJ/w4RA/KVe4LFFkkSh9VHoFzKmyaaDWAnPYIEzVCtJ+Un8GZoJhcvq+mPFXEsXa01lcZDHDG6Www==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0" + } + }, + "@typescript-eslint/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.5.0.tgz", + "integrity": "sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz", + "integrity": "sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } } }, "@typescript-eslint/experimental-utils": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz", - "integrity": "sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.5.0.tgz", + "integrity": "sha512-bW9IpSAKYvkqDGRZzayBXIgPsj2xmmVHLJ+flGSoN0fF98pGoKFhbunIol0VF2Crka7z984EEhFi623Rl7e6gg==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.19.2", - "eslint-scope": "^5.0.0" + "@typescript-eslint/scope-manager": "4.5.0", + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/typescript-estree": "4.5.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" }, "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.5.0.tgz", + "integrity": "sha512-C0cEO0cTMPJ/w4RA/KVe4LFFkkSh9VHoFzKmyaaDWAnPYIEzVCtJ+Un8GZoJhcvq+mPFXEsXa01lcZDHDG6Www==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0" + } + }, + "@typescript-eslint/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.5.0.tgz", + "integrity": "sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz", + "integrity": "sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "eslint-visitor-keys": "^2.0.0" + } + }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } } } }, "@typescript-eslint/parser": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.19.2.tgz", - "integrity": "sha512-8uwnYGKqX9wWHGPGdLB9sk9+12sjcdqEEYKGgbS8A0IvYX59h01o8os5qXUHMq2na8vpDRaV0suTLM7S8wraTA==", - "dev": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.19.2", - "@typescript-eslint/typescript-estree": "2.19.2", - "eslint-visitor-keys": "^1.1.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz", - "integrity": "sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.5.0.tgz", + "integrity": "sha512-xb+gmyhQcnDWe+5+xxaQk5iCw6KqXd8VQxGiTeELTMoYeRjpocZYYRP1gFVM2C8Yl0SpUvLa1lhprwqZ00w3Iw==", "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": "^6.3.0", - "tsutils": "^3.17.1" + "@typescript-eslint/scope-manager": "4.5.0", + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/typescript-estree": "4.5.0", + "debug": "^4.1.1" }, "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "@typescript-eslint/scope-manager": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.5.0.tgz", + "integrity": "sha512-C0cEO0cTMPJ/w4RA/KVe4LFFkkSh9VHoFzKmyaaDWAnPYIEzVCtJ+Un8GZoJhcvq+mPFXEsXa01lcZDHDG6Www==", "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" + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@typescript-eslint/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.5.0.tgz", + "integrity": "sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==", "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz", + "integrity": "sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "eslint-visitor-keys": "^2.0.0" + } } } }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "@typescript-eslint/scope-manager": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.4.1.tgz", + "integrity": "sha512-2oD/ZqD4Gj41UdFeWZxegH3cVEEH/Z6Bhr/XvwTtGv66737XkR4C9IqEkebCuqArqBJQSj4AgNHHiN1okzD/wQ==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.1" } }, - "@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==", + "@typescript-eslint/types": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.4.1.tgz", + "integrity": "sha512-KNDfH2bCyax5db+KKIZT4rfA8rEk5N0EJ8P0T5AJjo5xrV26UAzaiqoJCxeaibqc0c/IvZxp7v2g3difn2Pn3w==", "dev": true }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", + "@typescript-eslint/typescript-estree": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.5.0.tgz", + "integrity": "sha512-gN1mffq3zwRAjlYWzb5DanarOPdajQwx5MEWkWCk0XvqC8JpafDTeioDoow2L4CA/RkYZu7xEsGZRhqrTsAG8w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "@typescript-eslint/visitor-keys": "4.5.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.5.0.tgz", + "integrity": "sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz", + "integrity": "sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.5.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "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 + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.4.1.tgz", + "integrity": "sha512-H2JMWhLaJNeaylSnMSQFEhT/S/FsJbebQALmoJxMPMxLtlVAMy2uJP/Z543n9IizhjRayLSqoInehCeNW9rWcw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.4.1", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "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 @@ -1443,25 +1811,17 @@ } }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "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.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -1498,15 +1858,6 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, - "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", @@ -1529,64 +1880,68 @@ } }, "antd": { - "version": "3.26.17", - "resolved": "https://registry.npmjs.org/antd/-/antd-3.26.17.tgz", - "integrity": "sha512-P9uSK8SZ/1AvhQCC6aaLEkVrQhjbfZyUnqNV+lDnPqtudnZD2Ycy7Og+/EhuOBsQpYQvVT2aPLMgQWFv8tdJkA==", - "requires": { - "@ant-design/create-react-context": "^0.2.4", - "@ant-design/icons": "~2.1.1", - "@ant-design/icons-react": "~2.0.1", - "@types/react-slick": "^0.23.4", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/antd/-/antd-4.9.1.tgz", + "integrity": "sha512-q+Uf8xWeUB+O+xELq3tvprj2cEot/JnCAjS24scIadHSFzCkUr1nVcHU7dTtZommx7zQgC2ajWBOCVMmJD/lrw==", + "requires": { + "@ant-design/colors": "^5.0.0", + "@ant-design/css-animation": "^1.7.2", + "@ant-design/icons": "^4.3.0", + "@ant-design/react-slick": "~0.27.0", + "@babel/runtime": "^7.11.2", "array-tree-filter": "^2.1.0", - "babel-runtime": "6.x", - "classnames": "~2.2.6", + "classnames": "^2.2.6", "copy-to-clipboard": "^3.2.0", - "css-animation": "^1.5.0", - "dom-closest": "^0.2.0", - "enquire.js": "^2.1.6", - "is-mobile": "^2.1.0", - "lodash": "^4.17.13", - "moment": "^2.24.0", - "omit.js": "^1.0.2", - "prop-types": "^15.7.2", - "raf": "^3.4.1", - "rc-animate": "^2.10.2", - "rc-calendar": "~9.15.7", - "rc-cascader": "~0.17.4", - "rc-checkbox": "~2.1.6", - "rc-collapse": "~1.11.3", - "rc-dialog": "~7.6.0", - "rc-drawer": "~3.1.1", - "rc-dropdown": "~2.4.1", - "rc-editor-mention": "^1.1.13", - "rc-form": "^2.4.10", - "rc-input-number": "~4.5.0", - "rc-mentions": "~0.4.0", - "rc-menu": "~7.5.1", - "rc-notification": "~3.3.1", - "rc-pagination": "~1.20.11", - "rc-progress": "~2.5.0", - "rc-rate": "~2.5.0", - "rc-resize-observer": "^0.1.0", - "rc-select": "~9.2.0", - "rc-slider": "~8.7.1", - "rc-steps": "~3.5.0", - "rc-switch": "~1.9.0", - "rc-table": "~6.10.5", - "rc-tabs": "~9.7.0", - "rc-time-picker": "~3.7.1", - "rc-tooltip": "~3.7.3", - "rc-tree": "~2.1.0", - "rc-tree-select": "~2.9.1", - "rc-trigger": "^2.6.2", - "rc-upload": "~2.9.1", - "rc-util": "^4.16.1", - "react-lazy-load": "^3.0.13", - "react-lifecycles-compat": "^3.0.4", - "react-slick": "~0.25.2", - "resize-observer-polyfill": "^1.5.1", - "shallowequal": "^1.1.0", - "warning": "~4.0.3" + "lodash": "^4.17.20", + "moment": "^2.25.3", + "omit.js": "^2.0.2", + "rc-cascader": "~1.4.0", + "rc-checkbox": "~2.3.0", + "rc-collapse": "~3.1.0", + "rc-dialog": "~8.4.0", + "rc-drawer": "~4.1.0", + "rc-dropdown": "~3.2.0", + "rc-field-form": "~1.17.0", + "rc-image": "~4.2.0", + "rc-input-number": "~6.1.0", + "rc-mentions": "~1.5.0", + "rc-menu": "~8.10.0", + "rc-motion": "^2.4.0", + "rc-notification": "~4.5.2", + "rc-pagination": "~3.1.2", + "rc-picker": "~2.4.1", + "rc-progress": "~3.1.0", + "rc-rate": "~2.9.0", + "rc-resize-observer": "^0.2.3", + "rc-select": "~11.5.3", + "rc-slider": "~9.6.1", + "rc-steps": "~4.1.0", + "rc-switch": "~3.2.0", + "rc-table": "~7.11.0", + "rc-tabs": "~11.7.0", + "rc-textarea": "~0.3.0", + "rc-tooltip": "~5.0.0", + "rc-tree": "~4.0.0", + "rc-tree-select": "~4.2.0", + "rc-upload": "~3.3.1", + "rc-util": "^5.1.0", + "scroll-into-view-if-needed": "^2.2.25", + "warning": "^4.0.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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==" + } } }, "anymatch": { @@ -1668,13 +2023,30 @@ } }, "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "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": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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==", + "dev": true + } } }, "arr-diff": { @@ -1708,13 +2080,107 @@ "dev": true }, "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "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.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + } } }, "array-tree-filter": { @@ -1743,54 +2209,265 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "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==", + "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": { - "object-assign": "^4.1.1", - "util": "0.10.3" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" }, "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "inherits": "2.0.1" + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.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" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + } + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "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" } } } @@ -1847,9 +2524,9 @@ "dev": true }, "async-validator": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.11.5.tgz", - "integrity": "sha512-XNtCsMAeAH1pdLMEg1z8/Bb3a8cdCbui9QbJATRFHHHW5kT6+NPI3zSVQUXgikTFITzsg+kYY5NTWhM2Orwt9w==" + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.1.tgz", + "integrity": "sha512-DDmKA7sdSAJtTVeNZHrnr2yojfFaoeW8MfQN8CeuXg8DDQHTqKk9Fdv38dSvnesHoO8MUwMI2HphOeSyIF+wmQ==" }, "asynckit": { "version": "0.4.0", @@ -1951,37 +2628,22 @@ "dev": true }, "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", + "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 }, "axobject-query": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.1.tgz", - "integrity": "sha512-lF98xa/yvy6j3fBHAgQXIYl+J4eZadOSqsPojemUqClzNbBV38wWGpUbQbVEyf4eUF5yF7eHmGgGA2JiHyjeqw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.4", - "@babel/runtime-corejs3": "^7.7.4" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", - "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - } - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true }, "babel-loader": { "version": "8.0.6", @@ -2149,9 +2811,9 @@ "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==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body-parser": { @@ -2305,21 +2967,50 @@ "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "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" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "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.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "browserify-zlib": { @@ -2529,12 +3220,6 @@ "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", @@ -2625,21 +3310,6 @@ } } }, - "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": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -2753,32 +3423,27 @@ "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=" - }, "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { - "mime-db": ">= 1.40.0 < 2" + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "dev": true + } } }, "compression": { @@ -2813,6 +3478,11 @@ } } }, + "compute-scroll-into-view": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz", + "integrity": "sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2926,8 +3596,7 @@ "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, "cookie-signature": { "version": "1.0.6", @@ -2956,17 +3625,17 @@ "dev": true }, "copy-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.2.0.tgz", - "integrity": "sha512-eOZERzvCmxS8HWzugj4Uxl8OJxa7T2k1Gi0X5qavwydHIfuSHq2dTD09LOg/XyGq4Zpb5IsR/2OJ5lbOegz78w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", "requires": { "toggle-selection": "^1.0.6" } }, "copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", "dev": true, "requires": { "cacache": "^12.0.3", @@ -2979,7 +3648,7 @@ "normalize-path": "^3.0.0", "p-limit": "^2.2.1", "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", + "serialize-javascript": "^4.0.0", "webpack-log": "^2.0.0" }, "dependencies": { @@ -3046,9 +3715,9 @@ } }, "core-js-pure": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.4.7.tgz", - "integrity": "sha512-Am3uRS8WCdTFA3lP7LtKR0PxgqYzjAMGKXaZKSNSC/8sqU0Wfq8R/YzoRs2rqtOVEunfgH+0q3O0BKOg0AvjPw==", + "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": { @@ -3082,13 +3751,21 @@ } }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "create-hash": { @@ -3118,16 +3795,6 @@ "sha.js": "^2.4.8" } }, - "create-react-class": { - "version": "15.6.3", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", - "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", @@ -3157,15 +3824,6 @@ "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-blank-pseudo": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", @@ -3297,9 +3955,9 @@ } }, "csstype": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", - "integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==" }, "currently-unhandled": { "version": "0.4.1", @@ -3314,7 +3972,7 @@ "version": "file:../cvat-canvas", "requires": { "svg.draggable.js": "2.2.2", - "svg.draw.js": "^2.0.3", + "svg.draw.js": "^2.0.4", "svg.js": "2.7.1", "svg.resize.js": "1.4.3", "svg.select.js": "3.0.1" @@ -7141,10 +7799,7 @@ "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "requires": { - "ini": "^1.3.4" - } + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=" }, "global-modules": { "version": "2.0.0", @@ -7159,7 +7814,6 @@ "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" } @@ -7173,7 +7827,6 @@ "requires": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } @@ -7409,22 +8062,11 @@ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, "http-proxy-middleware": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", "requires": { - "http-proxy": "^1.17.0", "is-glob": "^4.0.0", "micromatch": "^3.1.10" } @@ -7568,11 +8210,6 @@ "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==" - }, "inquirer": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", @@ -9867,7 +10504,6 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { "deep-extend": "^0.6.0", - "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" } @@ -11159,9 +11795,9 @@ } }, "svg.draw.js": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/svg.draw.js/-/svg.draw.js-2.0.3.tgz", - "integrity": "sha512-GGK7vBzwdEgr5fJUupqDqYPhQBXxrtBd4CcrgqAt7S4/5REmF6JTSuITeAgfVlfXftOO90t5OqLOtJ4IEEUFVw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg.draw.js/-/svg.draw.js-2.0.4.tgz", + "integrity": "sha512-NMbecB0vg11AP76B0aLfI2cX7g9WurPM8x3yKxuJ9feM1vkI1GVjWZZjWpo3mkEzB1UJ8pKngaPaUCIOGi8uUA==", "requires": { "svg.js": "2.x.x" } @@ -12228,16 +12864,16 @@ "cvat-core": { "version": "file:../cvat-core", "requires": { - "axios": "^0.18.0", + "axios": "^0.21.0", "browser-or-node": "^1.2.1", - "cvat-data": "file:../cvat-data", - "detect-browser": "^5.0.0", + "detect-browser": "^5.2.0", "error-stack-parser": "^2.0.2", "form-data": "^2.5.0", - "jest-config": "^24.8.0", + "jest-config": "^26.6.3", "js-cookie": "^2.2.0", "jsonpath": "^1.0.2", "platform": "^1.3.5", + "quickhull": "^1.0.3", "store": "^2.0.12", "worker-loader": "^2.0.0" }, @@ -12254,16 +12890,15 @@ "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==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.10.4" } }, "@babel/compat-data": { @@ -12272,55 +12907,100 @@ "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", + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.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", + "json5": "^2.1.2", + "lodash": "^4.17.19", "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==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "requires": { - "ms": "^2.1.1" + "@babel/types": "^7.12.7" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz", + "integrity": "sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw==", + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "requires": { + "@babel/types": "^7.12.1" + } } } }, "@babel/generator": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", - "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", "requires": { - "@babel/types": "^7.8.7", + "@babel/types": "^7.12.5", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" } }, @@ -12358,7 +13038,6 @@ "requires": { "@babel/compat-data": "^7.8.6", "browserslist": "^4.9.1", - "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" } @@ -12393,21 +13072,21 @@ } }, "@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==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@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==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" } }, "@babel/helper-hoist-variables": { @@ -12457,9 +13136,9 @@ } }, "@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==" + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "@babel/helper-regex": { "version": "7.8.3", @@ -12502,13 +13181,18 @@ } }, "@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==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.11.0" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, "@babel/helper-wrap-function": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", @@ -12521,29 +13205,41 @@ } }, "@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==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + } } }, "@babel/parser": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", - "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==" + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.8.3", @@ -12626,6 +13322,22 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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", @@ -12634,6 +13346,14 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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", @@ -12642,6 +13362,14 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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", @@ -12650,6 +13378,14 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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", @@ -13017,7 +13753,6 @@ "@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" } @@ -13031,53 +13766,38 @@ } }, "@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==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@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", + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", + "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "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==" - } + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", - "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, @@ -13090,14 +13810,41 @@ "minimist": "^1.2.0" } }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" } }, "@jest/core": { @@ -13105,55 +13852,49 @@ "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", "requires": { - "@jest/console": "^24.7.1", "@jest/reporters": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", "exit": "^0.1.2", "graceful-fs": "^4.1.15", "jest-changed-files": "^24.9.0", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", "jest-resolve-dependencies": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", "jest-watcher": "^24.9.0", - "micromatch": "^3.1.10", "p-each-series": "^1.0.0", - "realpath-native": "^1.1.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "strip-ansi": "^5.0.0" + "rimraf": "^2.5.4" } }, "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" } }, "@jest/reporters": { @@ -13161,25 +13902,12 @@ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", "exit": "^0.1.2", "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", "istanbul-lib-report": "^2.0.4", "istanbul-lib-source-maps": "^3.0.1", "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", "node-notifier": "^5.4.2", - "slash": "^2.0.0", "source-map": "^0.6.0", "string-length": "^2.0.0" }, @@ -13192,12 +13920,12 @@ } }, "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", + "graceful-fs": "^4.2.4", "source-map": "^0.6.0" }, "dependencies": { @@ -13209,47 +13937,48 @@ } }, "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" } }, "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", + "slash": "^3.0.0", "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "write-file-atomic": "^3.0.0" }, "dependencies": { "source-map": { @@ -13260,19 +13989,37 @@ } }, "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "requires": { + "@sinonjs/commons": "^1.7.0" } }, "@types/babel__core": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", - "integrity": "sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg==", + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -13282,34 +14029,42 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "@types/babel__traverse": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", - "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.16.tgz", + "integrity": "sha512-S63Dt4CZOkuTmpLGGWtT/mQdVORJOpx6SZWGVaP56dda/0Nx5nEe82K7/LAm8zYr6SfMq+1N2OreIOrHAx656w==", "requires": { "@babel/types": "^7.3.0" } }, + "@types/graceful-fs": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "requires": { + "@types/node": "*" + } + }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" }, "@types/istanbul-lib-report": { "version": "3.0.0", @@ -13320,23 +14075,37 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/node": { + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/prettier": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==" + }, "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" }, "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "version": "15.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.11.tgz", + "integrity": "sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA==", "requires": { "@types/yargs-parser": "*" } @@ -13515,29 +14284,22 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" - } + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, "acorn-jsx": { @@ -13546,17 +14308,14 @@ "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==" }, "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "airbnb": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/airbnb/-/airbnb-0.0.2.tgz", - "integrity": "sha512-eC+7zzGrcM///BKt04V23v+W3b9dWDUltOzo0j5lzjhvvMc4EiSxh55k2vlVnHTZ0igqA8/i/1j2j+m7UlZ54w==", - "requires": { - "chalk": "^2.4.2" - } + "integrity": "sha512-eC+7zzGrcM///BKt04V23v+W3b9dWDUltOzo0j5lzjhvvMc4EiSxh55k2vlVnHTZ0igqA8/i/1j2j+m7UlZ54w==" }, "ajv": { "version": "6.12.0", @@ -13585,9 +14344,9 @@ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "3.2.1", @@ -13598,12 +14357,12 @@ } }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "aproba": { @@ -13634,18 +14393,11 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" - }, "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==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", "is-string": "^1.0.5" } }, @@ -13716,11 +14468,6 @@ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" }, - "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==" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -13737,17 +14484,16 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz", + "integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==", "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "follow-redirects": "^1.10.0" } }, "babel-code-frame": { @@ -13816,17 +14562,18 @@ } }, "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" } }, "babel-loader": { @@ -13836,7 +14583,6 @@ "requires": { "find-cache-dir": "^2.0.0", "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", "pify": "^4.0.1" }, "dependencies": { @@ -13850,37 +14596,57 @@ "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" - } + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==" }, "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" } }, "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", "@types/babel__traverse": "^7.0.6" } }, + "babel-preset-current-node-syntax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { @@ -13981,30 +14747,11 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "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" - } - } + "fill-range": "^7.0.1" } }, "brorand": { @@ -14022,21 +14769,6 @@ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" - } - } - }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -14157,7 +14889,6 @@ "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", @@ -14234,13 +14965,48 @@ } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "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==", + "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==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "chardet": { @@ -14253,10 +15019,7 @@ "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", @@ -14306,6 +15069,11 @@ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -14341,13 +15109,13 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, "co": { @@ -14360,6 +15128,11 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -14457,7 +15230,6 @@ "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" } @@ -14564,23 +15336,30 @@ } }, "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" }, "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "requires": { - "cssom": "0.3.x" + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } } }, "cvat-data": { "version": "file:../cvat-data", "requires": { - "async-mutex": "^0.1.4", - "jszip": "3.1.5" + "async-mutex": "^0.2.4", + "jszip": "3.5.0" }, "dependencies": { "ajv": { @@ -14600,20 +15379,18 @@ "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" }, "async-mutex": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.1.4.tgz", - "integrity": "sha512-zVWTmAnxxHaeB2B1te84oecI8zTDJ/8G49aVBblRX6be0oq6pAybNcUSxwfgVOmOjSCvN4aYZAqwtyNI8e1YGw==" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.4.tgz", + "integrity": "sha512-fcQKOXUKMQc57JlmjBCHtkKNrfGpHyR7vu18RfuLfeTAf4hK9PgOadPR5cDrBQ682zasrLUhJFe7EKAHJOduDg==", + "requires": { + "tslib": "^2.0.0" + } }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, - "core-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", - "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -14624,11 +15401,6 @@ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, - "es6-promise": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" - }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", @@ -14668,21 +15440,20 @@ } }, "jszip": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", - "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", + "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", "requires": { - "core-js": "~2.3.0", - "es6-promise": "~3.0.2", - "lie": "~3.1.0", + "lie": "~3.3.0", "pako": "~1.0.2", - "readable-stream": "~2.0.6" + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" } }, "lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "requires": { "immediate": "~3.0.5" } @@ -14708,9 +15479,9 @@ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "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==" }, "punycode": { "version": "2.1.1", @@ -14718,18 +15489,24 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "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.1", + "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.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==" + }, "schema-utils": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", @@ -14739,10 +15516,23 @@ "ajv-keywords": "^3.1.0" } }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "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" + } + }, + "tslib": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.2.tgz", + "integrity": "sha512-wAH28hcEKwna96/UacuWaVspVLkg4x1aDM9JlzqaQTOFczCktkVAb5fmXChgandR1EraDPs2w8P+ozM+oafwxg==" }, "uri-js": { "version": "4.2.2", @@ -14791,33 +15581,21 @@ } }, "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" } }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "decamelize": { @@ -14825,6 +15603,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -14835,13 +15618,10 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, - "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" - } + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "define-property": { "version": "2.0.2", @@ -14895,9 +15675,9 @@ } }, "detect-browser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.0.0.tgz", - "integrity": "sha512-jUaq/SAT9YMlmhq/8w7gnqqr8AMcc7iYG1eAp7vP/7xn2eLtlcnEmxOkh2PmTg2Q+jVSUO3XD4sZ/IldbGg3dA==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.0.tgz", + "integrity": "sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA==" }, "detect-file": { "version": "1.0.0", @@ -14905,14 +15685,14 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" }, "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" }, "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" }, "diffie-hellman": { "version": "5.0.3", @@ -14938,11 +15718,18 @@ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" }, "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "requires": { - "webidl-conversions": "^4.0.2" + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } } }, "duplexify": { @@ -14970,10 +15757,15 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.377.tgz", "integrity": "sha512-cm2WzMKf/3dW5+hNANKm8GAW6SwIWOqLTJ6GPCD0Bbw1qJ9Wzm9nmx9M+byzSsgw8CdCv5fb/wzLFqVS5h6QrA==" }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==" + }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emojis-list": { "version": "3.0.0", @@ -15038,34 +15830,6 @@ "stackframe": "^1.1.1" } }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.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==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", @@ -15185,7 +15949,6 @@ "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", @@ -15209,13 +15972,11 @@ "levn": "^0.3.0", "lodash": "^4.17.14", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "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", @@ -15256,7 +16017,6 @@ "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", "requires": { "confusing-browser-globals": "^1.0.7", - "object.assign": "^4.1.0", "object.entries": "^1.1.0" } }, @@ -15272,10 +16032,7 @@ "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" - } + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" } } }, @@ -15291,10 +16048,7 @@ "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" - } + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" }, "find-up": { "version": "2.1.0", @@ -15309,8 +16063,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^2.0.0" } }, "p-limit": { @@ -15365,10 +16118,7 @@ "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" - } + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" }, "doctrine": { "version": "1.5.0", @@ -15394,8 +16144,7 @@ "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "pify": "^2.0.0" } }, "locate-path": { @@ -15403,8 +16152,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^2.0.0" } }, "p-limit": { @@ -15540,10 +16288,7 @@ "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" - } + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" }, "doctrine": { "version": "2.1.0", @@ -15580,7 +16325,6 @@ "json-stable-stringify": "^1.0.0", "levn": "^0.3.0", "lodash": "^4.0.0", - "mkdirp": "^0.5.0", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.1", @@ -15588,7 +16332,6 @@ "progress": "^1.1.8", "require-uncached": "^1.0.2", "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", "strip-json-comments": "~2.0.1", "table": "^3.7.8", "text-table": "~0.2.0", @@ -15600,7 +16343,6 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "requires": { - "acorn": "^5.5.0", "acorn-jsx": "^3.0.0" } }, @@ -15776,10 +16518,7 @@ "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "requires": { - "mkdirp": "^0.5.1" - } + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=" } } }, @@ -15955,6 +16694,11 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -15967,16 +16711,39 @@ } }, "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "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==", + "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==" + } } }, "ext": { @@ -16137,24 +16904,11 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "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" - } - } + "to-regex-range": "^5.0.1" } }, "find-cache-dir": { @@ -16168,11 +16922,12 @@ } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "findup-sync": { @@ -16182,7 +16937,6 @@ "requires": { "detect-file": "^1.0.0", "is-glob": "^4.0.0", - "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" } }, @@ -16211,12 +16965,9 @@ } }, "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" - } + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" }, "for-in": { "version": "1.0.2", @@ -16277,638 +17028,101 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", - "optional": true, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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=" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "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-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "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=" + }, + "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" + } + }, + "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": { - "node-pre-gyp": "*" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": 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=", - "optional": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": false, - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "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", - "resolved": false, - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "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", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "optional": 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==", - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": 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==", - "optional": true - }, - "minipass": { - "version": "2.9.0", - "resolved": false, - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": false, - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, - "needle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.3.tgz", - "integrity": "sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw==", - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "resolved": false, - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", - "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", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "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", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "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", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "optional": true - }, - "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=", - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "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=", - "optional": 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==", - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "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", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "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", - "resolved": false, - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "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==", - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "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", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": 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=", - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "optional": true - }, - "tar": { - "version": "4.4.13", - "resolved": false, - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "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", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "optional": true - }, - "yallist": { - "version": "3.1.1", - "resolved": false, - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "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=" - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "requires": { - "is-property": "^1.0.0" - } - }, - "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=" - }, - "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" - } - }, - "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" + "is-extglob": "^2.1.0" } } } @@ -16926,7 +17140,6 @@ "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" } @@ -16940,7 +17153,6 @@ "requires": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } @@ -16951,9 +17163,9 @@ "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==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "growly": { "version": "1.3.0", @@ -16966,12 +17178,25 @@ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + } } }, "has": { @@ -17002,11 +17227,6 @@ "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", @@ -17026,10 +17246,23 @@ "kind-of": "^4.0.0" }, "dependencies": { - "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-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" + } + } + } }, "kind-of": { "version": "4.0.0", @@ -17083,11 +17316,11 @@ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" }, "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "requires": { - "whatwg-encoding": "^1.0.1" + "whatwg-encoding": "^1.0.5" } }, "html-escaper": { @@ -17175,18 +17408,12 @@ "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==" - }, "inquirer": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "requires": { "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", @@ -17196,7 +17423,6 @@ "run-async": "^2.2.0", "rxjs": "^6.4.0", "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { @@ -17210,7 +17436,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" }, "dependencies": { @@ -17231,19 +17456,16 @@ "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==" }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -17252,11 +17474,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -17281,14 +17498,9 @@ } }, "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-ci": { "version": "2.0.0", @@ -17298,6 +17510,14 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -17306,11 +17526,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -17321,11 +17536,6 @@ } } }, - "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==" - }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -17354,9 +17564,9 @@ "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=" + "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==" }, "is-generator-fn": { "version": "2.1.0", @@ -17389,27 +17599,9 @@ } }, "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": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "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" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-plain-object": { "version": "2.0.4", @@ -17419,6 +17611,11 @@ "isobject": "^3.0.1" } }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -17429,14 +17626,6 @@ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "requires": { - "has": "^1.0.3" - } - }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -17452,14 +17641,6 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" }, - "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==", - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -17496,22 +17677,19 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" }, "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "dependencies": { "semver": { @@ -17526,7 +17704,6 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "requires": { - "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, @@ -17547,7 +17724,6 @@ "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" @@ -17596,18 +17772,10 @@ "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", "requires": { "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", "exit": "^0.1.2", "import-local": "^2.0.0", "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^13.3.0" + "prompts": "^2.0.1" } } } @@ -17617,136 +17785,141 @@ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" + "execa": "^1.0.0" } }, "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", "requires": { - "detect-newline": "^2.1.0" + "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" } }, "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" } }, "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" }, "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^24.9.0", + "expect": "^26.6.2", "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" } }, "jest-junit": { @@ -17754,8 +17927,6 @@ "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-6.4.0.tgz", "integrity": "sha512-GXEZA5WBeUich94BARoEUccJumhCgCerg7mXDFLxWwI2P7wL3Z7sGWk+53x343YdBLjiMR9aD/gYMVKO+0pE4Q==", "requires": { - "jest-validate": "^24.0.0", - "mkdirp": "^0.5.1", "strip-ansi": "^4.0.0", "xml": "^1.0.1" }, @@ -17776,205 +17947,227 @@ } }, "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "requires": { - "@jest/types": "^24.9.0" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" }, "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==" + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" }, "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" } }, "jest-resolve-dependencies": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", - "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", - "requires": { - "@jest/types": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.9.0" - } + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==" }, "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "source-map-support": "^0.5.6", - "throat": "^4.0.0" + "throat": "^5.0.0" } }, "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" } }, "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } }, "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" + "pretty-format": "^26.6.2", + "semver": "^7.3.2" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.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==" - } + "micromatch": "^4.0.2" } }, "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^24.9.0" + "pretty-format": "^26.6.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + } } }, "jest-watcher": { @@ -17982,30 +18175,31 @@ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", "string-length": "^2.0.0" } }, "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" + "supports-color": "^7.0.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "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==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -18056,7 +18250,6 @@ "markdown-it": "^8.4.2", "markdown-it-anchor": "^5.0.2", "marked": "^0.7.0", - "mkdirp": "^0.5.1", "requizzle": "^0.2.3", "strip-json-comments": "^3.0.1", "taffydb": "2.6.2", @@ -18076,35 +18269,35 @@ } }, "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", "xml-name-validator": "^3.0.0" } }, @@ -18113,10 +18306,10 @@ "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.2.3", @@ -18147,9 +18340,9 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "requires": { "minimist": "^1.2.5" } @@ -18223,11 +18416,6 @@ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=" }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -18250,6 +18438,11 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", @@ -18258,17 +18451,6 @@ "uc.micro": "^1.0.1" } }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", @@ -18295,12 +18477,11 @@ } }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -18311,20 +18492,12 @@ "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" - }, - "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" - } + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" }, "lru-cache": { "version": "5.1.1", @@ -18453,23 +18626,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "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" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "miller-rabin": { @@ -18558,21 +18720,6 @@ } } }, - "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", @@ -18581,15 +18728,14 @@ "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=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mute-stream": { "version": "0.0.7", @@ -18720,12 +18866,9 @@ } }, "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" - } + "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", @@ -18773,11 +18916,6 @@ "is-descriptor": "^0.1.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==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -18788,16 +18926,6 @@ } } }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" - }, - "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", @@ -18806,37 +18934,15 @@ "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.entries": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -18850,8 +18956,6 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } @@ -18934,19 +19038,19 @@ "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==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-reduce": { @@ -18996,12 +19100,14 @@ } }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, "parse-passwd": { @@ -19010,9 +19116,9 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" }, "pascalcase": { "version": "0.1.1", @@ -19030,9 +19136,9 @@ "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=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -19054,14 +19160,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - } - }, "pbkdf2": { "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", @@ -19079,10 +19177,10 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pirates": { "version": "4.0.1", @@ -19095,10 +19193,7 @@ "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" - } + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==" }, "platform": { "version": "1.3.5", @@ -19110,11 +19205,6 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -19126,14 +19216,37 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "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==", + "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==" + } } }, "private": { @@ -19176,9 +19289,9 @@ "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==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "public-encrypt": { "version": "4.0.3", @@ -19243,6 +19356,11 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, + "quickhull": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/quickhull/-/quickhull-1.0.3.tgz", + "integrity": "sha512-AQbLaXdzGDJdO9Mu3qY/NY5JWlDqIutCLW8vJbsQTq+/bydIZeltnMVRKCElp81Y5/uRm4Yw/RsMdcltFYsS6w==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -19261,27 +19379,36 @@ } }, "react-is": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", - "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==" + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } } }, "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, "readable-stream": { @@ -19304,7 +19431,6 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "requires": { "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", "readable-stream": "^2.0.2" } }, @@ -19333,14 +19459,6 @@ } } }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "requires": { - "util.promisify": "^1.0.0" - } - }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -19474,25 +19592,45 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } } } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "require-directory": { @@ -19530,10 +19668,11 @@ } }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -19680,12 +19819,129 @@ "micromatch": "^3.1.4", "minimist": "^1.1.1", "walker": "~1.0.5" + }, + "dependencies": { + "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" + } + }, + "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" + } + } + } + }, + "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" + } + } + } + }, + "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" + } + } + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + } } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } }, "schema-utils": { "version": "1.0.0", @@ -19783,9 +20039,9 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "sisteransi": { "version": "1.0.4", @@ -19793,9 +20049,9 @@ "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==" }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { "version": "2.1.0", @@ -19803,8 +20059,7 @@ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "requires": { "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "astral-regex": "^1.0.0" } }, "snapdragon": { @@ -19845,6 +20100,11 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -19902,11 +20162,6 @@ "kind-of": "^3.2.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -19940,9 +20195,9 @@ } }, "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==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -19961,32 +20216,32 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "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==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" }, "split-string": { "version": "3.1.0", @@ -20026,9 +20281,19 @@ } }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } }, "stackframe": { "version": "1.1.1", @@ -20132,31 +20397,13 @@ } }, "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" - } - }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "string_decoder": { @@ -20168,17 +20415,17 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" }, "strip-eof": { "version": "1.0.0", @@ -20210,8 +20457,7 @@ "requires": { "ajv": "^6.10.2", "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "slice-ansi": "^2.1.0" } }, "taffydb": { @@ -20270,14 +20516,13 @@ } }, "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "text-table": { @@ -20286,9 +20531,9 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, "through": { "version": "2.3.8", @@ -20343,11 +20588,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -20370,29 +20610,29 @@ } }, "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=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "requires": { + "ip-regex": "^2.1.0", "psl": "^1.1.28", "punycode": "^2.1.1" } }, "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", "requires": { - "punycode": "^2.1.0" + "punycode": "^2.1.1" } }, "tslib": { @@ -20431,11 +20671,29 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -20600,17 +20858,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -20653,6 +20900,14 @@ "browser-process-hrtime": "^1.0.0" } }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", @@ -20672,9 +20927,9 @@ } }, "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { "version": "4.42.0", @@ -20691,12 +20946,9 @@ "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", @@ -20732,7 +20984,6 @@ "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", @@ -20796,17 +21047,13 @@ "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" + "y18n": "^4.0.0" } } } @@ -20841,13 +21088,13 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", "requires": { "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" } }, "which": { @@ -20902,13 +21149,36 @@ } }, "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==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "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==", + "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==" + } } }, "wrappy": { @@ -20919,28 +21189,23 @@ "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "requires": { - "mkdirp": "^0.5.1" - } + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==" }, "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" }, "xml": { "version": "1.0.1", @@ -20952,6 +21217,11 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, "xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", @@ -20963,9 +21233,9 @@ "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==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" }, "yallist": { "version": "3.1.1", @@ -20973,26 +21243,27 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^3.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yargs-parser": "^18.1.2" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -21007,9 +21278,9 @@ "dev": true }, "damerau-levenshtein": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", - "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", "dev": true }, "dashdash": { @@ -21021,6 +21292,16 @@ "assert-plus": "^1.0.0" } }, + "date-fns": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", + "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==" + }, + "dayjs": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.6.tgz", + "integrity": "sha512-HngNLtPEBWRo8EFVmHFmSXAjtCX8rGNqeXQI0Gh7wCTSqwaKgPIDqu9m07wABVopNwzvOeCb+2711vQhDlcIXw==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -21048,9 +21329,9 @@ "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" }, "deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", - "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", "dev": true, "requires": { "is-arguments": "^1.0.4", @@ -21075,45 +21356,6 @@ "requires": { "execa": "^1.0.0", "ip-regex": "^2.1.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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" - } - } } }, "define-properties": { @@ -21236,6 +21478,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "dir-glob": { @@ -21290,21 +21540,12 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "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", - "isarray": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } + "esutils": "^2.0.2" } }, "dom-align": { @@ -21312,14 +21553,6 @@ "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.0.tgz", "integrity": "sha512-YkoezQuhp3SLFGdOlr5xkqZ640iXrnHAwVYcDg8ZKRUtO7mSzSC2BA5V0VuyAwPSJA4CLIc6EDDJh4bEsD2+zA==" }, - "dom-closest": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-closest/-/dom-closest-0.2.0.tgz", - "integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=", - "requires": { - "dom-matches": ">=1.0.1" - } - }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -21329,16 +21562,6 @@ "utila": "~0.4" } }, - "dom-matches": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-matches/-/dom-matches-2.0.0.tgz", - "integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw=" - }, - "dom-scroll-into-view": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", - "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=" - }, "dom-serializer": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", @@ -21394,31 +21617,21 @@ "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" }, "dotenv-defaults": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-1.0.2.tgz", - "integrity": "sha512-iXFvHtXl/hZPiFj++1hBg4lbKwGM+t/GlvELDnRtOFdjXyWP7mubkVr+eZGWG62kdsbulXAef6v/j6kiWc/xGA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-1.1.1.tgz", + "integrity": "sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q==", "requires": { "dotenv": "^6.2.0" } }, "dotenv-webpack": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-1.7.0.tgz", - "integrity": "sha512-wwNtOBW/6gLQSkb8p43y0Wts970A3xtNiG/mpwj9MLUhtPCQG6i+/DSXXoNN7fbPCU/vQ7JjwGmgOeGZSSZnsw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-1.8.0.tgz", + "integrity": "sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg==", "requires": { "dotenv-defaults": "^1.0.2" } }, - "draft-js": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.10.5.tgz", - "integrity": "sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg==", - "requires": { - "fbjs": "^0.8.15", - "immutable": "~3.7.4", - "object-assign": "^4.1.0" - } - }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -21498,6 +21711,14 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "emoji-regex": { @@ -21518,14 +21739,6 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, - "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", @@ -21588,10 +21801,22 @@ } } }, - "enquire.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", - "integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=" + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + } + } }, "entities": { "version": "2.0.0", @@ -21667,22 +21892,24 @@ "dev": true }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.11.0.tgz", + "integrity": "sha512-G9+qtYVCHaDi1ZuWzBsOWo2wSwd70TXnU6UHA3cTYHp7gCTXZcpggWFoUVAMRarg68qtPoNfFbzPh+VdOgmwmw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "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", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", @@ -21691,90 +21918,126 @@ "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", + "levn": "^0.4.1", + "lodash": "^4.17.19", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "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.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "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 }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "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" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" } }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "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.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", - "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "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" } }, + "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 + }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", @@ -21785,10 +22048,10 @@ "resolve-from": "^4.0.0" } }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "resolve-from": { @@ -21798,63 +22061,173 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": "^4.1.0" + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" } } } }, "eslint-config-airbnb": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz", - "integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.0.tgz", + "integrity": "sha512-Fz4JIUKkrhO0du2cg5opdyPKQXOI2MvF8KUvN2710nJMT6jaRUpRE2swrJftAjVGL7T1otLM5ieo5RqS1v9Udg==", "dev": true, "requires": { - "eslint-config-airbnb-base": "^14.0.0", + "eslint-config-airbnb-base": "^14.2.0", "object.assign": "^4.1.0", - "object.entries": "^1.1.0" + "object.entries": "^1.1.2" } }, "eslint-config-airbnb-base": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", - "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz", + "integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==", "dev": true, "requires": { - "confusing-browser-globals": "^1.0.7", + "confusing-browser-globals": "^1.0.9", "object.assign": "^4.1.0", - "object.entries": "^1.1.0" + "object.entries": "^1.1.2" } }, "eslint-config-airbnb-typescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-7.0.0.tgz", - "integrity": "sha512-ki0JvJEdz2E0QWMeDfSgyr7tLwSmTYhMwaZP0XNnBhQfsjAAlLXwpQZHZBIpaoPrc2Fs6pFUTUU39xD3XPXKZQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-12.0.0.tgz", + "integrity": "sha512-TUCVru1Z09eKnVAX5i3XoNzjcCOU3nDQz2/jQGkg1jVYm+25fKClveziSl16celfCq+npU0MBPW/ZnXdGFZ9lw==", "dev": true, "requires": { - "@typescript-eslint/parser": "^2.19.0", - "eslint-config-airbnb": "^18.0.1", - "eslint-config-airbnb-base": "^14.0.0" + "@typescript-eslint/parser": "4.4.1", + "eslint-config-airbnb": "18.2.0", + "eslint-config-airbnb-base": "14.2.0" + }, + "dependencies": { + "@typescript-eslint/parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.4.1.tgz", + "integrity": "sha512-S0fuX5lDku28Au9REYUsV+hdJpW/rNW0gWlc4SXzF/kdrRaAVX9YCxKpziH7djeWT/HFAjLZcnY7NJD8xTeUEg==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.4.1", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/typescript-estree": "4.4.1", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.4.1.tgz", + "integrity": "sha512-wP/V7ScKzgSdtcY1a0pZYBoCxrCstLrgRQ2O9MmCUZDtmgxCO/TCqOTGRVwpP4/2hVfqMz/Vw1ZYrG8cVxvN3g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "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 + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } } }, "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "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.5.0" + "resolve": "^1.13.1" }, "dependencies": { "debug": { @@ -21871,29 +22244,26 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } } } }, - "eslint-import-resolver-typescript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.0.0.tgz", - "integrity": "sha512-bT5Frpl8UWoHBtY25vKUOMoVIMlJQOMefHLyQ4Tz3MQpIZ2N6yYKEEIHMo38bszBNUuMBW6M3+5JNYxeiGFH4w==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "is-glob": "^4.0.1", - "resolve": "^1.12.0", - "tiny-glob": "^0.2.6", - "tsconfig-paths": "^3.9.0" - } - }, "eslint-module-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", - "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "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.8", + "debug": "^2.6.9", "pkg-dir": "^2.0.0" }, "dependencies": { @@ -21949,98 +22319,249 @@ "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 - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "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 + }, + "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-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "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.4", + "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": { + "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" + } + }, + "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" + } + }, + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.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" + } + }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", "dev": true, "requires": { - "find-up": "^2.1.0" + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" } } } }, - "eslint-plugin-eslint-plugin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz", - "integrity": "sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg==", - "dev": true - }, - "eslint-plugin-import": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", - "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "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": { - "array-includes": "^3.0.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.0", + "@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", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.11.0" + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", "dev": true, "requires": { - "ms": "2.0.0" + "regenerator-runtime": "^0.13.4" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "emoji-regex": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz", + "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==", + "dev": true + }, + "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==", "dev": true } } }, - "eslint-plugin-jsx-a11y": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", - "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.5", - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", - "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.2", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^7.0.2", - "has": "^1.0.3", - "jsx-ast-utils": "^2.2.1" - } - }, "eslint-plugin-react": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz", - "integrity": "sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", + "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", - "eslint-plugin-eslint-plugin": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.2.3", - "object.entries": "^1.1.0", - "object.fromentries": "^2.0.1", - "object.values": "^1.1.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.13.1" + "resolve": "^1.18.1", + "string.prototype.matchall": "^4.0.2" }, "dependencies": { "doctrine": { @@ -22052,21 +22573,125 @@ "esutils": "^2.0.2" } }, + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.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" + } + }, "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", "dev": true, "requires": { + "is-core-module": "^2.0.0", "path-parse": "^1.0.6" } } } }, "eslint-plugin-react-hooks": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", - "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", "dev": true }, "eslint-scope": { @@ -22080,29 +22705,45 @@ } }, "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==", + "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" + }, + "dependencies": { + "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==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", "dev": true }, "espree": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", - "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, "requires": { - "acorn": "^7.1.0", - "acorn-jsx": "^5.1.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "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==", + "dev": true + } } }, "esprima": { @@ -22112,12 +22753,20 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "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": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { @@ -22148,20 +22797,15 @@ "dev": true }, "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "eventlistener": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/eventlistener/-/eventlistener-0.0.1.tgz", - "integrity": "sha1-7Suqu4UiJ68rz4iRUscsY8pTLrg=" - }, "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, "eventsource": { @@ -22183,6 +22827,36 @@ "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" + }, + "dependencies": { + "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" + } + } + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -22336,17 +23010,6 @@ } } }, - "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", @@ -22424,6 +23087,74 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "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", @@ -22436,6 +23167,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -22445,42 +23185,12 @@ "websocket-driver": ">=0.5.1" } }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - }, - "dependencies": { - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" - } - } - }, "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.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", - "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", - "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", @@ -22607,9 +23317,9 @@ } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "flatten": { @@ -22661,24 +23371,10 @@ } }, "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "dev": true }, "for-in": { "version": "1.0.2", @@ -23014,12 +23710,6 @@ "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, @@ -23405,28 +24095,6 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } } }, "gaze": { @@ -23450,6 +24118,15 @@ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "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", @@ -23541,12 +24218,6 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "globalyzer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.4.tgz", - "integrity": "sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA==", - "dev": true - }, "globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", @@ -23568,20 +24239,14 @@ } } }, - "globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true - }, "globule": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", - "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", "dev": true, "requires": { "glob": "~7.1.1", - "lodash": "~4.17.12", + "lodash": "~4.17.10", "minimatch": "~3.0.2" } }, @@ -23596,15 +24261,10 @@ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" }, - "hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" - }, "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, "har-schema": { @@ -23614,13 +24274,33 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + } } }, "has": { @@ -23692,13 +24372,33 @@ } }, "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "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.1", - "safe-buffer": "^5.0.1" + "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.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "hash.js": { @@ -23783,9 +24483,9 @@ "dev": true }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "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", @@ -23809,9 +24509,9 @@ } }, "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", "dev": true }, "html-minifier": { @@ -23927,16 +24627,10 @@ } } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { "eventemitter3": "^4.0.0", @@ -23977,6 +24671,7 @@ "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" } @@ -24008,11 +24703,6 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "immutable": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" - }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -24058,9 +24748,9 @@ "dev": true }, "in-publish": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", "dev": true }, "indent-string": { @@ -24101,121 +24791,145 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "inquirer": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", - "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", + "insert-css": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", + "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ=" + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.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": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" }, "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 + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } }, - "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==", + "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" + } + }, + "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 }, - "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==", + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "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==", + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "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" - } - } + "has-symbols": "^1.0.1" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" }, "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 + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } } } } } }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, "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 - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -24229,9 +24943,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "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==", "dev": true }, "is-absolute-url": { @@ -24293,6 +25007,15 @@ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, + "is-core-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", + "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -24377,10 +25100,11 @@ "is-extglob": "^2.1.1" } }, - "is-mobile": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-2.2.1.tgz", - "integrity": "sha512-6zELsfVFr326eq2CI53yvqq6YBanOxKBybwDT+MbMS2laBnK6Ez8m5XHSuTQQbnKRfpDzCod1CMWW5q3wZYMvA==" + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true }, "is-number": { "version": "3.0.0", @@ -24415,17 +25139,15 @@ "dev": true, "requires": { "is-path-inside": "^2.1.0" - }, - "dependencies": { - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - } + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" } }, "is-plain-object": { @@ -24437,12 +25159,6 @@ "isobject": "^3.0.1" } }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -24455,7 +25171,14 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "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.2", @@ -24507,15 +25230,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -24523,9 +25237,9 @@ "dev": true }, "js-base64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", - "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", "dev": true }, "js-levenshtein": { @@ -24650,12 +25364,12 @@ } }, "jsx-ast-utils": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", - "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", + "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.0.3", + "array-includes": "^3.1.1", "object.assign": "^4.1.0" } }, @@ -24671,23 +25385,29 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "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": { - "invert-kv": "^2.0.0" + "language-subtag-registry": "~0.3.2" } }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "load-json-file": { @@ -24749,9 +25469,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash-es": { "version": "4.17.15", @@ -24770,11 +25490,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -24800,15 +25515,10 @@ "lodash._reinterpolate": "^3.0.0" } }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" - }, "loglevel": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz", - "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", + "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==", "dev": true }, "loose-envify": { @@ -24855,15 +25565,6 @@ "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", @@ -24913,17 +25614,6 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, - "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", @@ -25071,6 +25761,12 @@ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -25106,6 +25802,14 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "mime": { @@ -25129,12 +25833,6 @@ "mime-db": "1.40.0" } }, - "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 - }, "mini-create-react-context": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz", @@ -25146,20 +25844,21 @@ } }, "mini-store": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mini-store/-/mini-store-2.0.0.tgz", - "integrity": "sha512-EG0CuwpQmX+XL4QVS0kxNwHW5ftSbhygu1qxQH0pipugjnPkbvkalCdQbEihMwtQY6d3MTN+MS0q+aurs+RfLQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/mini-store/-/mini-store-3.0.6.tgz", + "integrity": "sha512-YzffKHbYsMQGUWQRKdsearR79QsMzzJcDDmZKlJBqt5JNkqpyJHYlK6gP61O36X+sLf76sO9G6mhKBe83gIZIQ==", "requires": { - "hoist-non-react-statics": "^2.3.1", - "prop-types": "^15.6.0", - "react-lifecycles-compat": "^3.0.4", + "hoist-non-react-statics": "^3.3.2", "shallowequal": "^1.0.2" }, "dependencies": { "hoist-non-react-statics": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", - "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } } } }, @@ -25247,9 +25946,9 @@ } }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "move-concurrently": { "version": "1.0.1", @@ -25287,17 +25986,6 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, - "mutationobserver-shim": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/mutationobserver-shim/-/mutationobserver-shim-0.3.7.tgz", - "integrity": "sha512-oRIDTyZQU96nAiz2AQyngwx1e89iApl2hN5AOYwyxLUB47UYsU3Wv9lJWqH5y/QdiYkc5HQLi23ZNB3fELdHcQ==" - }, - "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.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -25356,19 +26044,10 @@ "lower-case": "^1.1.1" } }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", "dev": true }, "node-gyp": { @@ -25488,9 +26167,9 @@ } }, "node-sass": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", - "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", "dev": true, "requires": { "async-foreach": "^0.1.3", @@ -25507,7 +26186,7 @@ "node-gyp": "^3.8.0", "npmlog": "^4.0.0", "request": "^2.88.0", - "sass-graph": "^2.2.4", + "sass-graph": "2.2.5", "stdout-stream": "^1.4.0", "true-case-path": "^1.0.2" }, @@ -25663,10 +26342,86 @@ "dev": true }, "object-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", - "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz", + "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } }, "object-keys": { "version": "1.1.1", @@ -25696,27 +26451,212 @@ } }, "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "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.12.0", - "function-bind": "^1.1.1", + "es-abstract": "^1.17.5", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + } } }, "object.fromentries": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.1.tgz", - "integrity": "sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA==", + "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.15.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + } } }, "object.getownpropertydescriptors": { @@ -25757,12 +26697,9 @@ "dev": true }, "omit.js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/omit.js/-/omit.js-1.0.2.tgz", - "integrity": "sha512-/QPc6G2NS+8d4L/cQhbk6Yit1WTB6Us2g84A7A/1+w9d/eRGHyEqC5kkQtHVoHZ5NFWGG7tUGgrhVZwgZanKrQ==", - "requires": { - "babel-runtime": "^6.23.0" - } + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/omit.js/-/omit.js-2.0.2.tgz", + "integrity": "sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==" }, "on-finished": { "version": "2.3.0", @@ -25788,15 +26725,6 @@ "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" - } - }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -25807,17 +26735,17 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "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" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "original": { @@ -25837,59 +26765,9 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "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" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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" - } - } - } + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true }, "os-tmpdir": { "version": "1.0.2", @@ -25907,24 +26785,12 @@ "os-tmpdir": "^1.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=", - "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": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", @@ -26040,14 +26906,13 @@ } }, "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.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" @@ -26131,26 +26996,15 @@ } }, "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 - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "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==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -26163,7 +27017,14 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true }, "pify": { "version": "4.0.1", @@ -26201,14 +27062,14 @@ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", - "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", "dev": true, "requires": { "async": "^2.6.2", "debug": "^3.1.1", - "mkdirp": "^0.5.1" + "mkdirp": "^0.5.5" }, "dependencies": { "debug": { @@ -26219,6 +27080,21 @@ "requires": { "ms": "^2.1.1" } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "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" + } } } }, @@ -26764,9 +27640,9 @@ } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "pretty-error": { @@ -26803,14 +27679,6 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -26828,13 +27696,13 @@ } }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "dev": true, "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "ipaddr.js": "1.9.1" } }, "prr": { @@ -26850,9 +27718,9 @@ "dev": true }, "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "public-encrypt": { @@ -26867,6 +27735,14 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "pump": { @@ -26933,19 +27809,11 @@ "dev": true }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "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", @@ -26992,485 +27860,809 @@ } }, "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-calendar": { - "version": "9.15.11", - "resolved": "https://registry.npmjs.org/rc-calendar/-/rc-calendar-9.15.11.tgz", - "integrity": "sha512-qv0VXfAAnysMWJigxaP6se4bJHvr17D9qsLbi8BOpdgEocsS0RkgY1IUiFaOVYKJDy/EyLC447O02sV/y5YYBg==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz", + "integrity": "sha512-myAM2R4qoB6LqBul0leaqY8gFaiECDJ3MtQDmzDo9xM9NRT/04TvWOYd2YHU9zvGzqk9QXF6S9/MifzSKDZeMw==", "requires": { - "babel-runtime": "6.x", + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "moment": "2.x", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.0", - "rc-util": "^4.1.1", - "react-lifecycles-compat": "^3.0.4" + "dom-align": "^1.7.0", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-cascader": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-0.17.5.tgz", - "integrity": "sha512-WYMVcxU0+Lj+xLr4YYH0+yXODumvNXDcVEs5i7L1mtpWwYkubPV/zbQpn+jGKFCIW/hOhjkU4J1db8/P/UKE7A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-1.4.0.tgz", + "integrity": "sha512-6kgQljDQEKjVAVRkZtvvoi+2qv4u42M6oLuvt4ZDBa16r3X9ZN8TAq3atVyC840ivbGKlHT50OcdVx/iwiHc1w==", "requires": { "array-tree-filter": "^2.1.0", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.0", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.4", - "shallow-equal": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1", "warning": "^4.0.1" } }, "rc-checkbox": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.1.8.tgz", - "integrity": "sha512-6qOgh0/by0nVNASx6LZnhRTy17Etcgav+IrI7kL9V9kcDZ/g7K14JFlqrtJ3NjDq/Kyn+BPI1st1XvbkhfaJeg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.1.tgz", + "integrity": "sha512-i290/iTqmZ0WtI2UPIryqT9rW6O99+an4KeZIyZDH3r+Jbb6YdddaWNdzq7g5m9zaNhJvgjf//wJtC4fvve2Tg==", "requires": { - "babel-runtime": "^6.23.0", - "classnames": "2.x", - "prop-types": "15.x", - "react-lifecycles-compat": "^3.0.4" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-collapse": { - "version": "1.11.8", - "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-1.11.8.tgz", - "integrity": "sha512-8EhfPyScTYljkbRuIoHniSwZagD5UPpZ3CToYgoNYWC85L2qCbPYF7+OaC713FOrIkp6NbfNqXsITNxmDAmxog==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.0.tgz", + "integrity": "sha512-EwpNPJcLe7b+5JfyaxM9ZNnkCgqArt3QQO0Cr5p5plwz/C9h8liAmjYY5I4+hl9lAjBqb7ZwLu94+z+rt5g1WQ==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "css-animation": "1.x", - "prop-types": "^15.5.6", - "rc-animate": "2.x", - "react-is": "^16.7.0", - "react-lifecycles-compat": "^3.0.4", + "rc-motion": "^2.3.4", + "rc-util": "^5.2.1", "shallowequal": "^1.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-dialog": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-7.6.1.tgz", - "integrity": "sha512-KUKf+2eZ4YL+lnXMG3hR4ZtIhC9glfH27NtTVz3gcoDIPAf3uUvaXVRNoDCiSi+OGKLyIb/b6EoidFh6nQC5Wg==", + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.4.4.tgz", + "integrity": "sha512-cIc5NdglkYwQrRAeJ7ryJo7wrak+w4rWsqDm9HVHcWmN4fdToyIhfni4L5FQUcdzfWvBx+sK9gTrUWhv9y07yw==", "requires": { - "babel-runtime": "6.x", - "rc-animate": "2.x", - "rc-util": "^4.16.1" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-drawer": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-3.1.3.tgz", - "integrity": "sha512-2z+RdxmzXyZde/1OhVMfDR1e/GBswFeWSZ7FS3Fdd0qhgVdpV1wSzILzzxRaT481ItB5hOV+e8pZT07vdJE8kg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.1.0.tgz", + "integrity": "sha512-kjeQFngPjdzAFahNIV0EvEBoIKMOnvUsAxpkSPELoD/1DuR4nLafom5ryma+TIxGwkFJ92W6yjsMi1U9aiOTeQ==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "^2.2.6", - "rc-util": "^4.16.1", - "react-lifecycles-compat": "^3.0.4" + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-dropdown": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-2.4.1.tgz", - "integrity": "sha512-p0XYn0wrOpAZ2fUGE6YJ6U8JBNc5ASijznZ6dkojdaEfQJAeZtV9KMEewhxkVlxGSbbdXe10ptjBlTEW9vEwEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.0.tgz", + "integrity": "sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==", "requires": { - "babel-runtime": "^6.26.0", + "@babel/runtime": "^7.10.1", "classnames": "^2.2.6", - "prop-types": "^15.5.8", - "rc-trigger": "^2.5.1", - "react-lifecycles-compat": "^3.0.2" - } - }, - "rc-editor-core": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/rc-editor-core/-/rc-editor-core-0.8.10.tgz", - "integrity": "sha512-T3aHpeMCIYA1sdAI7ynHHjXy5fqp83uPlD68ovZ0oClTSc3tbHmyCxXlA+Ti4YgmcpCYv7avF6a+TIbAka53kw==", - "requires": { - "babel-runtime": "^6.26.0", - "classnames": "^2.2.5", - "draft-js": "^0.10.0", - "immutable": "^3.7.4", - "lodash": "^4.16.5", - "prop-types": "^15.5.8", - "setimmediate": "^1.0.5" - } - }, - "rc-editor-mention": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/rc-editor-mention/-/rc-editor-mention-1.1.13.tgz", - "integrity": "sha512-3AOmGir91Fi2ogfRRaXLtqlNuIwQpvla7oUnGHS1+3eo7b+fUp5IlKcagqtwUBB5oDNofoySXkLBxzWvSYNp/Q==", - "requires": { - "babel-runtime": "^6.23.0", - "classnames": "^2.2.5", - "dom-scroll-into-view": "^1.2.0", - "draft-js": "~0.10.0", - "immutable": "~3.7.4", - "prop-types": "^15.5.8", - "rc-animate": "^2.3.0", - "rc-editor-core": "~0.8.3" + "rc-trigger": "^5.0.4" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-form": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/rc-form/-/rc-form-2.4.11.tgz", - "integrity": "sha512-8BL+FNlFLTOY/A5X6tU35GQJLSIpsmqpwn/tFAYQTczXc4dMJ33ggtH248Cum8+LS0jLTsJKG2L4Qp+1CkY+sA==", + "rc-field-form": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.17.2.tgz", + "integrity": "sha512-+pufRy5x4G5yHxQ3k1nhgQqyqerPVJQ2jaLGojHjNpmZ2Si20o1KniMLsZxe6X8dfq4ePmH6M3IngfDnS+CrMA==", "requires": { - "async-validator": "~1.11.3", - "babel-runtime": "6.x", - "create-react-class": "^15.5.3", - "dom-scroll-into-view": "1.x", - "hoist-non-react-statics": "^3.3.0", - "lodash": "^4.17.4", - "rc-util": "^4.15.3", - "warning": "^4.0.3" + "@babel/runtime": "^7.8.4", + "async-validator": "^3.0.3", + "rc-util": "^5.0.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-hammerjs": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/rc-hammerjs/-/rc-hammerjs-0.6.10.tgz", - "integrity": "sha512-Vgh9qIudyN5CHRop4M+v+xUniQBFWXKrsJxQRVtJOi2xgRrCeI52/bkpaL5HWwUhqTK9Ayq0n7lYTItT6ld5rg==", + "rc-image": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-4.2.0.tgz", + "integrity": "sha512-yGqq6wPrIn86hMfC1Hl7M3NNS6zqnl9dvFWJg/StuI86jZBU0rm9rePTfKs+4uiwU3HXxpfsXlaG2p8GWRDLiw==", "requires": { - "babel-runtime": "6.x", - "hammerjs": "^2.0.8", - "prop-types": "^15.5.9" + "@ant-design/icons": "^4.2.2", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-dialog": "~8.4.0", + "rc-util": "^5.0.6" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-input-number": { - "version": "4.5.7", - "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-4.5.7.tgz", - "integrity": "sha512-99PrQ90sTOKyyj7eu0VzwxY17xQ+bwG1XTQd+bTwFQ+IOUkIw7L4qSAYxt58sVYL+Cw+bu/RAtT2IpT9yC2pCQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-6.1.1.tgz", + "integrity": "sha512-9t2xf1G0YEism7FAXAvF1huBk7ZNABPBf6NL+3/aDL123WiT/vhhod4cldiDWTM1Yb2EDKR//ZIa546ScdsUaA==", "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.0", - "prop-types": "^15.5.7", - "rc-util": "^4.5.1", - "rmc-feedback": "^2.0.0" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-mentions": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-0.4.2.tgz", - "integrity": "sha512-DTZurQzacLXOfVuiHydGzqkq7cFMHXF18l2jZ9PhWUn2cqvOSY3W4osN0Pq29AOMOBpcxdZCzgc7Lb0r/bgkDw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.5.2.tgz", + "integrity": "sha512-GqV0tOtHY3pLpOsFCxJ2i6Ad8AVfxFmz0NlD/8rb8IG8pMpthJKcdfnXlNZRx3Fa9O4YEgJpdSY1WEbmlx2DWQ==", "requires": { - "@ant-design/create-react-context": "^0.2.4", + "@babel/runtime": "^7.10.1", "classnames": "^2.2.6", - "rc-menu": "^7.4.22", - "rc-trigger": "^2.6.2", - "rc-util": "^4.6.0", - "react-lifecycles-compat": "^3.0.4" + "rc-menu": "^8.0.1", + "rc-textarea": "^0.3.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-menu": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-7.5.5.tgz", - "integrity": "sha512-4YJXJgrpUGEA1rMftXN7bDhrV5rPB8oBJoHqT+GVXtIWCanfQxEnM3fmhHQhatL59JoAFMZhJaNzhJIk4FUWCQ==", + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-8.10.1.tgz", + "integrity": "sha512-HmTOLPkSrz5RcdDopD4+nI95YXR2DzdSq9ek3NX2EVgD1UHknlp1QAEJ5MompYdAqdtOspJUqgM/zNt0iQALOw==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "dom-scroll-into-view": "1.x", - "mini-store": "^2.0.0", - "mutationobserver-shim": "^0.3.2", - "rc-animate": "^2.10.1", - "rc-trigger": "^2.3.0", - "rc-util": "^4.13.0", + "mini-store": "^3.0.1", + "omit.js": "^2.0.0", + "rc-motion": "^2.0.1", + "rc-trigger": "^5.1.2", + "rc-util": "^5.5.0", "resize-observer-polyfill": "^1.5.0", "shallowequal": "^1.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-motion": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.1.tgz", + "integrity": "sha512-TWLvymfMu8SngPx5MDH8dQ0D2RYbluNTfam4hY/dNNx9RQ3WtGuZ/GXHi2ymLMzH+UNd6EEFYkOuR5JTTtm8Xg==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-notification": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-3.3.1.tgz", - "integrity": "sha512-U5+f4BmBVfMSf3OHSLyRagsJ74yKwlrQAtbbL5ijoA0F2C60BufwnOcHG18tVprd7iaIjzZt1TKMmQSYSvgrig==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.4.tgz", + "integrity": "sha512-VsN0ouF4uglE5g3C9oDsXLNYX0Sz++ZNUFYCswkxhpImYJ9u6nJOpyA71uOYDVCu6bAF54Y5Hi/b+EcnMzkepg==", "requires": { - "babel-runtime": "6.x", + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "prop-types": "^15.5.8", - "rc-animate": "2.x", - "rc-util": "^4.0.4" + "rc-motion": "^2.2.0", + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-pagination": { - "version": "1.20.15", - "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-1.20.15.tgz", - "integrity": "sha512-/Xr4/3GOa1DtL8iCYl7qRUroEMrRDhZiiuHwcVFfSiwa9LYloMlUWcOJsnr8LN6A7rLPdm3/CHStUNeYd+2pKw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.2.tgz", + "integrity": "sha512-KbJvkTvRiD51vTIAi0oTARPUHNb0iV6njbDBe8yLkc3PWYDJaszASfuss6YJ98EIxEeGzuEk6xsUAEKWRJgz2g==", "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.6", - "prop-types": "^15.5.7", - "react-lifecycles-compat": "^3.0.4" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-picker": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.4.3.tgz", + "integrity": "sha512-tOIHslTQKpoGNmbpp6YOBwS39dQSvtAuhOm3bWCkkc4jCqUqeR/velCwqefZX1BX4+t1gUMc1dIia9XvOKrEkg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "^2.15.0", + "dayjs": "^1.8.30", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-progress": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-2.5.3.tgz", - "integrity": "sha512-K2fa4CnqGehLZoMrdmBeZ86ONSTVcdk5FlqetbwJ3R/+42XfqhwQVOjWp2MH4P7XSQOMAGcNOy1SFfCP3415sg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.1.1.tgz", + "integrity": "sha512-1ns3pW7ll9bHfdXtlVLF+vngdvlxiCDtiqwXnZFEdurst11JTiPxVdeqnCNbhWx5hP4kCKkAPqG1N0FVfTSUGA==", "requires": { - "babel-runtime": "6.x", - "prop-types": "^15.5.8" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-rate": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.5.1.tgz", - "integrity": "sha512-3iJkNJT8xlHklPCdeZtUZmJmRVUbr6AHRlfSsztfYTXVlHrv2TcPn3XkHsH+12j812WVB7gvilS2j3+ffjUHXg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.1.tgz", + "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", - "prop-types": "^15.5.8", - "rc-util": "^4.3.0", - "react-lifecycles-compat": "^3.0.4" + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-resize-observer": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-0.1.3.tgz", - "integrity": "sha512-uzOQEwx83xdQSFOkOAM7x7GHIQKYnrDV4dWxtCxyG1BS1pkfJ4EvDeMfsvAJHSYkQXVBu+sgRHGbRtLG3qiuUg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-0.2.6.tgz", + "integrity": "sha512-YX6nYnd6fk7zbuvT6oSDMKiZjyngjHoy+fz+vL3Tez38d/G5iGdaDJa2yE7345G6sc4Mm1IGRUIwclvltddhmA==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "^2.2.1", - "rc-util": "^4.13.0", + "rc-util": "^5.0.0", "resize-observer-polyfill": "^1.5.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-select": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-9.2.3.tgz", - "integrity": "sha512-WhswxOMWiNnkXRbxyrj0kiIvyCfo/BaRPaYbsDetSIAU2yEDwKHF798blCP5u86KLOBKBvtxWLFCkSsQw1so5w==", + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-11.5.3.tgz", + "integrity": "sha512-ASSO4J/ayfbQQ+KOEounIMGhySDHpQtrIuH1WEABOBy8HgKec8kOLmyLH+YIXSUDnTf/gtxmflgFtl7sQ9pkSw==", "requires": { - "babel-runtime": "^6.23.0", + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "component-classes": "1.x", - "dom-scroll-into-view": "1.x", - "prop-types": "^15.5.8", - "raf": "^3.4.0", - "rc-animate": "2.x", - "rc-menu": "^7.3.0", - "rc-trigger": "^2.5.4", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.2", - "warning": "^4.0.2" + "rc-motion": "^2.0.1", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1", + "rc-virtual-list": "^3.2.0", + "warning": "^4.0.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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==", + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.6.5.tgz", + "integrity": "sha512-XRUJDK668hy8MwGnHzZlXCQXXIOUnEs4m2vwk1jgDILVBxI0GwGOlC6T499pYY+NEWg8YgdCOAucFs/+X5WHpg==", "requires": { - "babel-runtime": "6.x", + "@babel/runtime": "^7.10.1", "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": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-steps": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-3.5.0.tgz", - "integrity": "sha512-2Vkkrpa7PZbg7qPsqTNzVDov4u78cmxofjjnIHiGB9+9rqKS8oTLPzbW2uiWDr3Lk+yGwh8rbpGO1E6VAgBCOg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.3.tgz", + "integrity": "sha512-GXrMfWQOhN3sVze3JnzNboHpQdNHcdFubOETUHyDpa/U3HEKBZC3xJ8XK4paBgF4OJ3bdUVLC+uBPc6dCxvDYA==", "requires": { - "babel-runtime": "^6.23.0", + "@babel/runtime": "^7.10.2", "classnames": "^2.2.3", - "lodash": "^4.17.5", - "prop-types": "^15.5.7" + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-switch": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-1.9.0.tgz", - "integrity": "sha512-Isas+egaK6qSk64jaEw4GgPStY4umYDbT7ZY93bZF1Af+b/JEsKsJdNOU2qG3WI0Z6tXo2DDq0kJCv8Yhu0zww==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz", + "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "^2.2.1", - "prop-types": "^15.5.6", - "react-lifecycles-compat": "^3.0.4" + "rc-util": "^5.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-table": { - "version": "6.10.15", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-6.10.15.tgz", - "integrity": "sha512-LAr0M/gqt+irOjvPNBLApmQ0CUHNOfKsEBhu1uIuB3OlN1ynA9z+sdoTQyNd9+8NSl0MYnQOOfhtLChAY7nU0A==", + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.11.3.tgz", + "integrity": "sha512-YyZry1CdqUrcH7MmWtLQZVvVZWbmTEbI5m650AZ+zYw4D5VF701samkMYl5z/H9yQFr+ugvDtXcya+e3vwRkMQ==", "requires": { + "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", - "component-classes": "^1.2.6", - "lodash": "^4.17.5", - "mini-store": "^2.0.0", - "prop-types": "^15.5.8", - "rc-util": "^4.13.0", - "react-lifecycles-compat": "^3.0.2", - "shallowequal": "^1.0.2" + "rc-resize-observer": "^0.2.0", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-tabs": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-9.7.0.tgz", - "integrity": "sha512-kvmgp8/MfLzFZ06hWHignqomFQ5nF7BqKr5O1FfhE4VKsGrep52YSF/1MvS5oe0NPcI9XGNS2p751C5v6cYDpQ==", + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.7.2.tgz", + "integrity": "sha512-2M/XE4TdecnjsDylJSs49OmjJuDuix3VmSiNaPd50PMqFc+dc4fEof3J8/ad12enicVOcsH4BEQEms//Kn4DBw==", "requires": { - "@ant-design/create-react-context": "^0.2.4", - "babel-runtime": "6.x", + "@babel/runtime": "^7.11.2", "classnames": "2.x", - "lodash": "^4.17.5", - "prop-types": "15.x", - "raf": "^3.4.1", - "rc-hammerjs": "~0.6.0", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.4", - "resize-observer-polyfill": "^1.5.1", - "warning": "^4.0.3" + "rc-dropdown": "^3.1.3", + "rc-menu": "^8.6.1", + "rc-resize-observer": "^0.2.1", + "rc-util": "^5.5.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-time-picker": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/rc-time-picker/-/rc-time-picker-3.7.3.tgz", - "integrity": "sha512-Lv1Mvzp9fRXhXEnRLO4nW6GLNxUkfAZ3RsiIBsWjGjXXvMNjdr4BX/ayElHAFK0DoJqOhm7c5tjmIYpEOwcUXg==", + "rc-textarea": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.1.tgz", + "integrity": "sha512-bO5Ol5uD6A++aWI6BJ0Pa/8OZcGeacP9LxIGkUqkCwPyOG3kaLOsWb8ya4xCfrsC2P4vDTsHsJmmmG5wuXGFRg==", "requires": { - "classnames": "2.x", - "moment": "2.x", - "prop-types": "^15.5.8", - "raf": "^3.4.1", - "rc-trigger": "^2.2.0", - "react-lifecycles-compat": "^3.0.4" + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "omit.js": "^2.0.0", + "rc-resize-observer": "^0.2.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-tooltip": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-3.7.3.tgz", - "integrity": "sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww==", + "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": "6.x", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.2" + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-tree": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-2.1.4.tgz", - "integrity": "sha512-Xey794Iavgs8YldFlXcZLOhfcIhlX5Oz/yfKufknBXf2AlZCOkc7aHqSM9uTF7fBPtTGPhPxNEfOqHfY7b7xng==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-4.0.0.tgz", + "integrity": "sha512-C2xlkA+/IypkHBPzbpAJGVWJh2HjeRbYCusA/m5k09WT6hQT0nC7LtLVmnb7QZecdBQPhoOgQh8gPwBR+xEMjQ==", "requires": { - "@ant-design/create-react-context": "^0.2.4", + "@babel/runtime": "^7.10.1", "classnames": "2.x", - "prop-types": "^15.5.8", - "rc-animate": "^2.6.0", - "rc-util": "^4.5.1", - "react-lifecycles-compat": "^3.0.4", - "warning": "^4.0.3" + "rc-motion": "^2.0.1", + "rc-util": "^5.0.0", + "rc-virtual-list": "^3.0.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-tree-select": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-2.9.4.tgz", - "integrity": "sha512-0HQkXAN4XbfBW20CZYh3G+V+VMrjX42XRtDCpyv6PDUm5vikC0Ob682ZBCVS97Ww2a5Hf6Ajmu0ahWEdIEpwhg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-4.2.0.tgz", + "integrity": "sha512-VrrvBiOov6WR44RTGMqSw1Dmodg6Y++EH6a6R0ew43qsV4Ob0FGYRgoX811kImtt2Z+oAPJ6zZXN4WKtsQd3Gw==", "requires": { - "classnames": "^2.2.1", - "dom-scroll-into-view": "^1.2.1", - "prop-types": "^15.5.8", - "raf": "^3.4.0", - "rc-animate": "^2.8.2", - "rc-tree": "~2.1.0", - "rc-trigger": "^3.0.0", - "rc-util": "^4.5.0", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.0.2", - "warning": "^4.0.1" + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "^11.1.1", + "rc-tree": "^4.0.0", + "rc-util": "^5.0.5" }, "dependencies": { - "rc-trigger": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-3.0.0.tgz", - "integrity": "sha512-hQxbbJpo23E2QnYczfq3Ec5J5tVl2mUDhkqxrEsQAqk16HfADQg+iKNWzEYXyERSncdxfnzYuaBgy764mNRzTA==", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.6", - "prop-types": "15.x", - "raf": "^3.4.0", - "rc-align": "^2.4.1", - "rc-animate": "^3.0.0-rc.1", - "rc-util": "^4.15.7" - }, - "dependencies": { - "rc-animate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/rc-animate/-/rc-animate-3.1.0.tgz", - "integrity": "sha512-8FsM+3B1H+0AyTyGggY6JyVldHTs1CyYT8CfTmG/nGHHXlecvSLeICJhcKgRLjUiQlctNnRtB1rwz79cvBVmrw==", - "requires": { - "@ant-design/css-animation": "^1.7.2", - "classnames": "^2.2.6", - "raf": "^3.4.0", - "rc-util": "^5.0.1" - }, - "dependencies": { - "rc-util": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.0.4.tgz", - "integrity": "sha512-cd19RCrE0DJH6UcJ9+V3eaXA/5sNWyVKOKkWl8ZM2OqgNzVb8fv0obf/TkuvSN43tmTsgqY8k7OqpFYHhmef8g==", - "requires": { - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" - } - } - } - } + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" } }, - "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==" + "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-trigger": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-2.6.5.tgz", - "integrity": "sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.1.2.tgz", + "integrity": "sha512-A6UdDy95masAEIaNmazPtqHW1EOFDWi2C2bJGDpr9OYpmObDpWKdxyNijVbFb6l1viTkAU9d3FyStgNPddgFzw==", "requires": { - "babel-runtime": "6.x", + "@babel/runtime": "^7.11.2", "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-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.5.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-upload": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-2.9.4.tgz", - "integrity": "sha512-WXt0HGxXyzLrPV6iec/96Rbl/6dyrAW8pKuY6wwD7yFYwfU5bjgKjv7vC8KNMJ6wzitFrZjnoiogNL3dF9dj3Q==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-3.3.1.tgz", + "integrity": "sha512-KWkJbVM9BwU8qi/2jZwmZpAcdRzDkuyfn/yAOLu+nm47dyd6//MtxzQD3XZDFkC6jQ6D5FmlKn6DhmOfV3v43w==", "requires": { - "babel-runtime": "6.x", + "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", - "prop-types": "^15.5.7", - "warning": "4.x" + "rc-util": "^5.2.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "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-util": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-4.21.1.tgz", - "integrity": "sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.5.0.tgz", + "integrity": "sha512-YJB+zZGvCll/bhxXRVLAekr7lOvTgqMlRIhgINoINfUek7wQvi5sft46NOi3yYUYhocpuW4k8+5okW46sBsZAQ==", "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" }, "dependencies": { @@ -27481,10 +28673,20 @@ } } }, + "rc-virtual-list": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.2.3.tgz", + "integrity": "sha512-uEeYDQWwQhxR97SekPeGRbzPtHSbSpw/mYb6QpZZ9bA43kf7s1socV3fD3ySYhQVzo0I+/IUD9jFGit6FbM0WA==", + "requires": { + "classnames": "^2.2.6", + "rc-resize-observer": "^0.2.3", + "rc-util": "^5.0.7" + } + }, "react": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz", - "integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -27492,27 +28694,38 @@ } }, "react-color": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.1.tgz", - "integrity": "sha512-X5XpyJS6ncplZs74ak0JJoqPi+33Nzpv5RYWWxn17bslih+X7OlgmfpmGC1fNvdkK7/SGWYf1JJdn7D2n5gSuQ==", + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", "requires": { "@icons/material": "^0.2.4", - "lodash": "^4.17.11", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", "material-colors": "^1.2.1", "prop-types": "^15.5.10", "reactcss": "^1.2.0", "tinycolor2": "^1.4.1" } }, + "react-cookie": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.3.tgz", + "integrity": "sha512-cmi6IpdVgTSvjqssqIEvo779Gfqc4uPGHRrKMEdHcqkmGtPmxolGfsyKj95bhdLEKqMdbX8MLBCwezlnhkHK0g==", + "requires": { + "@types/hoist-non-react-statics": "^3.0.1", + "hoist-non-react-statics": "^3.0.0", + "universal-cookie": "^4.0.0" + } + }, "react-dom": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.11.0.tgz", - "integrity": "sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.17.0" + "scheduler": "^0.19.1" } }, "react-hotkeys": { @@ -27528,33 +28741,44 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", "integrity": "sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==" }, - "react-lazy-load": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/react-lazy-load/-/react-lazy-load-3.0.13.tgz", - "integrity": "sha1-OwqS0zbUPT8Nc8vm81sXBQsIuCQ=", - "requires": { - "eventlistener": "0.0.1", - "lodash.debounce": "^4.0.0", - "lodash.throttle": "^4.0.0", - "prop-types": "^15.5.8" - } - }, - "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-redux": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.1.tgz", - "integrity": "sha512-QsW0vcmVVdNQzEkrgzh2W3Ksvr8cqpAv5FhEk7tNEft+5pp7rXxAudTz3VOPawRkLIepItpkEIyLcN/VVXzjTg==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz", + "integrity": "sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA==", "requires": { - "@babel/runtime": "^7.5.5", - "hoist-non-react-statics": "^3.3.0", - "invariant": "^2.2.4", + "@babel/runtime": "^7.12.1", + "hoist-non-react-statics": "^3.3.2", "loose-envify": "^1.4.0", "prop-types": "^15.7.2", - "react-is": "^16.9.0" + "react-is": "^16.13.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "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==" + }, + "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==" + } } }, "react-router": { @@ -27599,18 +28823,6 @@ "prop-types": "^15.5.8" } }, - "react-slick": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.25.2.tgz", - "integrity": "sha512-8MNH/NFX/R7zF6W/w+FS5VXNyDusF+XDW1OU0SzODEU7wqYB+ZTGAiNJ++zVNAVqCAHdyCybScaUB+FCZOmBBw==", - "requires": { - "classnames": "^2.2.5", - "enquire.js": "^2.1.6", - "json2mq": "^0.2.0", - "lodash.debounce": "^4.0.8", - "resize-observer-polyfill": "^1.5.0" - } - }, "react-svg-core": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/react-svg-core/-/react-svg-core-3.0.3.tgz", @@ -27653,6 +28865,23 @@ "load-json-file": "^2.0.0", "normalize-package-data": "^2.3.2", "path-type": "^2.0.0" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "read-pkg-up": { @@ -27775,9 +29004,9 @@ } }, "redux": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", - "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", "requires": { "loose-envify": "^1.4.0", "symbol-observable": "^1.2.0" @@ -27841,18 +29070,112 @@ } }, "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "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.2" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + } } }, "regexpp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", - "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "regexpu-core": { @@ -27939,9 +29262,9 @@ } }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -27951,7 +29274,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -27961,7 +29284,7 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" }, @@ -28055,16 +29378,6 @@ "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", @@ -28077,6 +29390,12 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -28096,23 +29415,11 @@ "inherits": "^2.0.1" } }, - "rmc-feedback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rmc-feedback/-/rmc-feedback-2.0.0.tgz", - "integrity": "sha512-5PWOGOW7VXks/l3JzlOU9NIxRpuaSS8d9zA3UULUCuTKnpwBHNvv1jSJzxgbbCQeYzROWUpgKI4za3X4C/mKmQ==", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true }, "run-queue": { "version": "1.0.3", @@ -28123,251 +29430,37 @@ "aproba": "^1.1.1" } }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "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==" - }, - "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } + "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 + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" } }, "sass-loader": { @@ -28398,9 +29491,9 @@ "dev": true }, "scheduler": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", - "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", + "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" @@ -28416,6 +29509,14 @@ "ajv-keywords": "^3.4.1" } }, + "scroll-into-view-if-needed": { + "version": "2.2.26", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.26.tgz", + "integrity": "sha512-SQ6AOKfABaSchokAmmaxVnL9IArxEnLEX9j4wAZw+x4iUTb40q7irtHG3z4GtAWz5veVZcCnubXDBRyLVQaohw==", + "requires": { + "compute-scroll-into-view": "^1.0.16" + } + }, "scss-tokenizer": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", @@ -28444,12 +29545,12 @@ "dev": true }, "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "dev": true, "requires": { - "node-forge": "0.9.0" + "node-forge": "^0.10.0" } }, "semver": { @@ -28505,10 +29606,13 @@ } }, "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true + "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" + } }, "serve-index": { "version": "1.9.1", @@ -28610,7 +29714,8 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true }, "setprototypeof": { "version": "1.1.1", @@ -28637,11 +29742,6 @@ "kind-of": "^6.0.2" } }, - "shallow-equal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", - "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" - }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -28662,6 +29762,88 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "side-channel": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz", + "integrity": "sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==", + "dev": true, + "requires": { + "es-abstract": "^1.18.0-next.0", + "object-inspect": "^1.8.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -28808,13 +29990,22 @@ } }, "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", "dev": true, "requires": { "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "sockjs-client": { @@ -28877,9 +30068,9 @@ } }, "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==", + "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", @@ -28933,9 +30124,9 @@ "dev": true }, "spdy": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", - "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -29095,121 +30286,315 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "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==", + "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" + } + }, + "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" + } + } + } + }, + "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" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "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" + } + }, + "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" + } + } + } + }, + "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-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.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" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", "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" + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^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==", + "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": { - "safe-buffer": "~5.1.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } } } }, - "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==", + "string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", "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" + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } }, - "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==", + "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": { - "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" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, - "string_decoder": { + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "has-symbols": "^1.0.1" } - } - } - }, - "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-convert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", - "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + }, + "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 }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "object.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } } } @@ -29234,6 +30619,88 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "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" + } + }, + "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 + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "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.assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -29282,9 +30749,9 @@ } }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "style-loader": { @@ -29420,9 +30887,9 @@ } }, "terser": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz", - "integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==", + "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", @@ -29439,16 +30906,16 @@ } }, "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==", + "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": "^2.1.2", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -29467,10 +30934,13 @@ } }, "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true + "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" + } }, "source-map": { "version": "0.6.1", @@ -29486,12 +30956,6 @@ "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", @@ -29549,16 +31013,6 @@ "setimmediate": "^1.0.4" } }, - "tiny-glob": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.6.tgz", - "integrity": "sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw==", - "dev": true, - "requires": { - "globalyzer": "^0.1.0", - "globrex": "^0.1.1" - } - }, "tiny-invariant": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz", @@ -29574,15 +31028,6 @@ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" }, - "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", @@ -29655,21 +31100,13 @@ "dev": true }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "trim-newlines": { @@ -29758,12 +31195,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-fest": { @@ -29794,11 +31231,6 @@ "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", "dev": true }, - "ua-parser-js": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", - "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" - }, "uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -29887,6 +31319,15 @@ "imurmurhash": "^0.1.4" } }, + "universal-cookie": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz", + "integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==", + "requires": { + "@types/cookie": "^0.3.3", + "cookie": "^0.4.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -30109,15 +31550,137 @@ "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==", + "watchpack": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", "dev": true, + "optional": true, "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "chokidar": "^2.1.8" } }, "wbuf": { @@ -30130,20 +31693,20 @@ } }, "webpack": { - "version": "4.42.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz", - "integrity": "sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", "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.2.1", + "acorn": "^6.4.1", "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", + "enhanced-resolve": "^4.3.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -30156,7 +31719,7 @@ "schema-utils": "^1.0.0", "tapable": "^1.1.3", "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", + "watchpack": "^1.7.4", "webpack-sources": "^1.4.1" }, "dependencies": { @@ -30166,6 +31729,35 @@ "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, + "enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "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" + } + } + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -30173,14 +31765,29 @@ "dev": true }, "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "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" } }, + "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" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -30191,26 +31798,35 @@ "ajv-errors": "^1.0.0", "ajv-keywords": "^3.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==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } } } }, "webpack-cli": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", - "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", - "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" + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" }, "dependencies": { "cross-spawn": { @@ -30226,15 +31842,30 @@ "which": "^1.2.9" } }, - "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==", + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "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": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" + "minimist": "^1.2.0" + } + }, + "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" } }, "supports-color": { @@ -30245,6 +31876,12 @@ "requires": { "has-flag": "^3.0.0" } + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true } } }, @@ -30262,17 +31899,17 @@ }, "dependencies": { "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true } } }, "webpack-dev-server": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.9.0.tgz", - "integrity": "sha512-E6uQ4kRrTX9URN9s/lIbqTAztwEPdvzVrcmHE8EQ9YnuT9J8Es5Wrd8n9BKg1a0oZ5EgEke/EQFgUsp18dSTBw==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -30283,80 +31920,37 @@ "debug": "^4.1.1", "del": "^4.1.1", "express": "^4.17.1", - "html-entities": "^1.2.1", + "html-entities": "^1.3.1", "http-proxy-middleware": "0.19.1", "import-local": "^2.0.0", "internal-ip": "^4.3.0", "ip": "^1.1.5", "is-absolute-url": "^3.0.3", "killable": "^1.0.1", - "loglevel": "^1.6.4", + "loglevel": "^1.6.8", "opn": "^5.5.0", "p-retry": "^3.0.1", - "portfinder": "^1.0.25", + "portfinder": "^1.0.26", "schema-utils": "^1.0.0", "selfsigned": "^1.10.7", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.19", + "sockjs": "0.3.20", "sockjs-client": "1.4.0", - "spdy": "^4.0.1", + "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", "webpack-dev-middleware": "^3.7.2", "webpack-log": "^2.0.0", "ws": "^6.2.1", - "yargs": "12.0.5" + "yargs": "^13.3.2" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cliui": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "schema-utils": { @@ -30376,62 +31970,59 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "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" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "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": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" }, "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "ansi-regex": "^4.1.0" } } } }, + "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" + } + }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "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", @@ -30469,13 +32060,11 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -30485,11 +32074,6 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -30633,22 +32217,21 @@ "dev": true }, "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "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" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -30680,9 +32263,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "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", diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 1065c3f8..450fbc4e 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.8.4", + "version": "1.13.3", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { @@ -16,24 +16,24 @@ "devDependencies": { "@babel/core": "^7.6.0", "@babel/plugin-proposal-class-properties": "^7.5.5", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", "@babel/preset-env": "^7.6.0", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.6.0", - "@typescript-eslint/eslint-plugin": "^2.19.2", - "@typescript-eslint/parser": "^2.19.2", + "@typescript-eslint/eslint-plugin": "^4.5.0", + "@typescript-eslint/parser": "^4.5.0", "babel-loader": "^8.0.6", "babel-plugin-import": "^1.12.2", - "copy-webpack-plugin": "^5.1.1", + "copy-webpack-plugin": "^5.1.2", "css-loader": "^3.2.0", - "eslint": "^6.8.0", - "eslint-config-airbnb-typescript": "^7.0.0", - "eslint-import-resolver-typescript": "^2.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.17.0", - "eslint-plugin-react-hooks": "^1.7.0", + "eslint": "^7.11.0", + "eslint-config-airbnb-typescript": "^12.0.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.3.1", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4.2.0", "html-webpack-plugin": "^3.2.0", - "node-sass": "^4.13.0", + "node-sass": "^4.14.1", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", "react-svg-loader": "^3.0.3", @@ -41,39 +41,44 @@ "style-loader": "^1.0.0", "tsconfig-paths-webpack-plugin": "^3.2.0", "typescript": "^3.7.3", - "webpack": "^4.42.1", - "webpack-cli": "^3.3.8", - "webpack-dev-server": "^3.8.0", + "webpack": "^4.44.2", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0", "worker-loader": "^2.0.0" }, "dependencies": { - "@types/platform": "^1.3.2", - "@types/react": "^16.9.2", - "@types/react-color": "^3.0.2", - "@types/react-dom": "^16.9.0", - "@types/react-redux": "^7.1.2", + "@ant-design/icons": "^4.3.0", + "@types/lodash": "^4.14.165", + "@types/platform": "^1.3.3", + "@types/react": "^16.14.2", + "@types/react-color": "^3.0.4", + "@types/react-dom": "^16.9.10", + "@types/react-redux": "^7.1.11", "@types/react-router": "^5.0.5", - "@types/react-router-dom": "^5.1.0", - "@types/react-share": "^3.0.1", - "@types/redux-logger": "^3.0.7", - "antd": "^3.26.17", - "copy-to-clipboard": "^3.2.0", + "@types/react-router-dom": "^5.1.6", + "@types/react-share": "^3.0.3", + "@types/redux-logger": "^3.0.8", + "antd": "^4.9.1", + "copy-to-clipboard": "^3.3.1", "cvat-canvas": "file:../cvat-canvas", "cvat-core": "file:../cvat-core", - "dotenv-webpack": "^1.7.0", + "dotenv-webpack": "^1.8.0", "error-stack-parser": "^2.0.6", - "moment": "^2.24.0", + "lodash": "^4.17.20", + "moment": "^2.29.1", "platform": "^1.3.6", "prop-types": "^15.7.2", - "react": "^16.9.0", - "react-color": "^2.18.1", - "react-dom": "^16.9.0", + "rc-virtual-list": "^3.2.3", + "react": "^16.14.0", + "react-color": "^2.19.3", + "react-cookie": "^4.0.3", + "react-dom": "^16.14.0", "react-hotkeys": "^2.0.0", - "react-redux": "^7.1.1", + "react-redux": "^7.2.2", "react-router": "^5.1.0", "react-router-dom": "^5.1.0", "react-share": "^3.0.1", - "redux": "^4.0.4", + "redux": "^4.0.5", "redux-devtools-extension": "^2.13.8", "redux-logger": "^3.0.6", "redux-thunk": "^2.3.0" diff --git a/cvat-ui/src/actions/about-actions.ts b/cvat-ui/src/actions/about-actions.ts index 8f9e77c6..c1b61ca4 100644 --- a/cvat-ui/src/actions/about-actions.ts +++ b/cvat-ui/src/actions/about-actions.ts @@ -26,9 +26,7 @@ export const getAboutAsync = (): ThunkAction => async (dispatch): Promise try { const about = await core.server.about(); - dispatch( - aboutActions.getAboutSuccess(about), - ); + dispatch(aboutActions.getAboutSuccess(about)); } catch (error) { dispatch(aboutActions.getAboutFailed(error)); } diff --git a/cvat-ui/src/actions/annotation-actions.ts b/cvat-ui/src/actions/annotation-actions.ts index 3bea5b6c..1d98243e 100644 --- a/cvat-ui/src/actions/annotation-actions.ts +++ b/cvat-ui/src/actions/annotation-actions.ts @@ -3,10 +3,7 @@ // SPDX-License-Identifier: MIT import { - AnyAction, - Dispatch, - ActionCreator, - Store, + AnyAction, Dispatch, ActionCreator, Store, } from 'redux'; import { ThunkAction } from 'utils/redux'; @@ -20,12 +17,14 @@ import { Rotation, ContextMenuType, Workspace, + Model, } from 'reducers/interfaces'; import getCore from 'cvat-core-wrapper'; import logger, { LogType } from 'cvat-logger'; import { RectDrawingMethod } from 'cvat-canvas-wrapper'; import { getCVATStore } from 'cvat-store'; +import { MutableRefObject } from 'react'; interface AnnotationsParameters { filters: string[]; @@ -52,22 +51,14 @@ function receiveAnnotationsParameters(): AnnotationsParameters { const state: CombinedState = getStore().getState(); const { annotation: { - annotations: { - filters, - }, + annotations: { filters }, player: { - frame: { - number: frame, - }, - }, - job: { - instance: jobInstance, + frame: { number: frame }, }, + job: { instance: jobInstance }, }, settings: { - workspace: { - showAllInterpolationTracks, - }, + workspace: { showAllInterpolationTracks }, }, } = state; @@ -95,11 +86,17 @@ async function jobInfoGenerator(job: any): Promise> { const { total } = await job.annotations.statistics(); return { 'frame count': job.stopFrame - job.startFrame + 1, - 'track count': total.rectangle.shape + total.rectangle.track - + total.polygon.shape + total.polygon.track - + total.polyline.shape + total.polyline.track - + total.points.shape + total.points.track - + total.cuboid.shape + total.cuboid.track, + 'track count': + total.rectangle.shape + + total.rectangle.track + + total.polygon.shape + + total.polygon.track + + total.polyline.shape + + total.polyline.track + + total.points.shape + + total.points.track + + total.cuboid.shape + + total.cuboid.track, 'object count': total.total, 'box count': total.rectangle.shape + total.rectangle.track, 'polygon count': total.polygon.shape + total.polygon.track, @@ -126,6 +123,7 @@ export enum AnnotationActionTypes { CONFIRM_CANVAS_READY = 'CONFIRM_CANVAS_READY', DRAG_CANVAS = 'DRAG_CANVAS', ZOOM_CANVAS = 'ZOOM_CANVAS', + SELECT_ISSUE_POSITION = 'SELECT_ISSUE_POSITION', MERGE_OBJECTS = 'MERGE_OBJECTS', GROUP_OBJECTS = 'GROUP_OBJECTS', SPLIT_TRACK = 'SPLIT_TRACK', @@ -164,9 +162,6 @@ export enum AnnotationActionTypes { COLLECT_STATISTICS = 'COLLECT_STATISTICS', COLLECT_STATISTICS_SUCCESS = 'COLLECT_STATISTICS_SUCCESS', COLLECT_STATISTICS_FAILED = 'COLLECT_STATISTICS_FAILED', - CHANGE_JOB_STATUS = 'CHANGE_JOB_STATUS', - CHANGE_JOB_STATUS_SUCCESS = 'CHANGE_JOB_STATUS_SUCCESS', - CHANGE_JOB_STATUS_FAILED = 'CHANGE_JOB_STATUS_FAILED', UPLOAD_JOB_ANNOTATIONS = 'UPLOAD_JOB_ANNOTATIONS', UPLOAD_JOB_ANNOTATIONS_SUCCESS = 'UPLOAD_JOB_ANNOTATIONS_SUCCESS', UPLOAD_JOB_ANNOTATIONS_FAILED = 'UPLOAD_JOB_ANNOTATIONS_FAILED', @@ -184,9 +179,16 @@ export enum AnnotationActionTypes { SWITCH_Z_LAYER = 'SWITCH_Z_LAYER', ADD_Z_LAYER = 'ADD_Z_LAYER', SEARCH_ANNOTATIONS_FAILED = 'SEARCH_ANNOTATIONS_FAILED', + SEARCH_EMPTY_FRAME_FAILED = 'SEARCH_EMPTY_FRAME_FAILED', CHANGE_WORKSPACE = 'CHANGE_WORKSPACE', SAVE_LOGS_SUCCESS = 'SAVE_LOGS_SUCCESS', SAVE_LOGS_FAILED = 'SAVE_LOGS_FAILED', + INTERACT_WITH_CANVAS = 'INTERACT_WITH_CANVAS', + SET_AI_TOOLS_REF = 'SET_AI_TOOLS_REF', + GET_DATA_FAILED = 'GET_DATA_FAILED', + SWITCH_REQUEST_REVIEW_DIALOG = 'SWITCH_REQUEST_REVIEW_DIALOG', + SWITCH_SUBMIT_REVIEW_DIALOG = 'SWITCH_SUBMIT_REVIEW_DIALOG', + SET_FORCE_EXIT_ANNOTATION_PAGE_FLAG = 'SET_FORCE_EXIT_ANNOTATION_PAGE_FLAG', } export function saveLogsAsync(): ThunkAction { @@ -217,6 +219,15 @@ export function changeWorkspace(workspace: Workspace): AnyAction { }; } +export function getDataFailed(error: any): AnyAction { + return { + type: AnnotationActionTypes.GET_DATA_FAILED, + payload: { + error, + }, + }; +} + export function addZLayer(): AnyAction { return { type: AnnotationActionTypes.ADD_Z_LAYER, @@ -237,13 +248,9 @@ export function fetchAnnotationsAsync(): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const { - filters, - frame, - showAllInterpolationTracks, - jobInstance, + filters, frame, showAllInterpolationTracks, jobInstance, } = receiveAnnotationsParameters(); - const states = await jobInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await jobInstance.annotations.get(frame, showAllInterpolationTracks, filters); const [minZ, maxZ] = computeZRange(states); dispatch({ @@ -353,11 +360,9 @@ export function uploadJobAnnotationsAsync(job: any, loader: any, file: File): Th const frame = state.annotation.player.frame.number; await job.annotations.upload(file, loader); - await job.logger.log( - LogType.uploadAnnotations, { - ...(await jobInfoGenerator(job)), - }, - ); + await job.logger.log(LogType.uploadAnnotations, { + ...(await jobInfoGenerator(job)), + }); await job.annotations.clear(true); await job.actions.clear(); @@ -399,36 +404,6 @@ export function uploadJobAnnotationsAsync(job: any, loader: any, file: File): Th }; } -export function changeJobStatusAsync(jobInstance: any, status: string): ThunkAction { - return async (dispatch: ActionCreator): Promise => { - const oldStatus = jobInstance.status; - try { - dispatch({ - type: AnnotationActionTypes.CHANGE_JOB_STATUS, - payload: {}, - }); - - // eslint-disable-next-line no-param-reassign - jobInstance.status = status; - await jobInstance.save(); - - dispatch({ - type: AnnotationActionTypes.CHANGE_JOB_STATUS_SUCCESS, - payload: {}, - }); - } catch (error) { - // eslint-disable-next-line no-param-reassign - jobInstance.status = oldStatus; - dispatch({ - type: AnnotationActionTypes.CHANGE_JOB_STATUS_FAILED, - payload: { - error, - }, - }); - } - }; -} - export function collectStatisticsAsync(sessionInstance: any): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { @@ -465,20 +440,14 @@ export function showStatistics(visible: boolean): AnyAction { }; } -export function propagateObjectAsync( - sessionInstance: any, - objectState: any, - from: number, - to: number, -): ThunkAction { +export function propagateObjectAsync(sessionInstance: any, objectState: any, from: number, to: number): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const copy = { attributes: objectState.attributes, points: objectState.points, occluded: objectState.occluded, - objectType: objectState.objectType !== ObjectType.TRACK - ? objectState.objectType : ObjectType.SHAPE, + objectType: objectState.objectType !== ObjectType.TRACK ? objectState.objectType : ObjectType.SHAPE, shapeType: objectState.shapeType, label: objectState.label, zOrder: objectState.zOrder, @@ -486,9 +455,7 @@ export function propagateObjectAsync( source: objectState.source, }; - await sessionInstance.logger.log( - LogType.propagateObject, { count: to - from + 1 }, - ); + await sessionInstance.logger.log(LogType.propagateObject, { count: to - from + 1 }); const states = []; for (let frame = from; frame <= to; frame++) { copy.frame = frame; @@ -535,8 +502,7 @@ export function changePropagateFrames(frames: number): AnyAction { }; } -export function removeObjectAsync(sessionInstance: any, objectState: any, force: boolean): -ThunkAction { +export function removeObjectAsync(sessionInstance: any, objectState: any, force: boolean): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { await sessionInstance.logger.log(LogType.deleteObject, { count: 1 }); @@ -554,13 +520,13 @@ ThunkAction { }, }); } else { - throw new Error('Could not remove the object. Is it locked?'); + throw new Error('Could not remove the locked object'); } } catch (error) { dispatch({ type: AnnotationActionTypes.REMOVE_OBJECT_FAILED, payload: { - objectState, + error, }, }); } @@ -597,10 +563,7 @@ export function selectObjects(selectedStatesID: number[]): AnyAction { }; } -export function activateObject( - activatedStateID: number | null, - activatedAttributeID: number | null, -): AnyAction { +export function activateObject(activatedStateID: number | null, activatedAttributeID: number | null): AnyAction { return { type: AnnotationActionTypes.ACTIVATE_OBJECT, payload: { @@ -652,8 +615,7 @@ export function switchPlay(playing: boolean): AnyAction { }; } -export function changeFrameAsync(toFrame: number, fillBuffer?: boolean, frameStep?: number): -ThunkAction { +export function changeFrameAsync(toFrame: number, fillBuffer?: boolean, frameStep?: number): ThunkAction { return async (dispatch: ActionCreator): Promise => { const state: CombinedState = getStore().getState(); const { instance: job } = state.annotation.job; @@ -689,23 +651,21 @@ ThunkAction { payload: {}, }); - await job.logger.log( - LogType.changeFrame, { - from: frame, - to: toFrame, - }, - ); + await job.logger.log(LogType.changeFrame, { + from: frame, + to: toFrame, + }); const data = await job.frames.get(toFrame, fillBuffer, frameStep); const states = await job.annotations.get(toFrame, showAllInterpolationTracks, filters); const [minZ, maxZ] = computeZRange(states); const currentTime = new Date().getTime(); let frameSpeed; switch (state.settings.player.frameSpeed) { - case (FrameSpeed.Fast): { + case FrameSpeed.Fast: { frameSpeed = (FrameSpeed.Fast as number) / 2; break; } - case (FrameSpeed.Fastest): { + case FrameSpeed.Fastest: { frameSpeed = (FrameSpeed.Fastest as number) / 3; break; } @@ -713,8 +673,10 @@ ThunkAction { frameSpeed = state.settings.player.frameSpeed as number; } } - const delay = Math.max(0, Math.round(1000 / frameSpeed) - - currentTime + (state.annotation.player.frame.changeTime as number)); + const delay = Math.max( + 0, + Math.round(1000 / frameSpeed) - currentTime + (state.annotation.player.frame.changeTime as number), + ); dispatch({ type: AnnotationActionTypes.CHANGE_FRAME_SUCCESS, @@ -744,8 +706,7 @@ ThunkAction { }; } -export function undoActionAsync(sessionInstance: any, frame: number): -ThunkAction { +export function undoActionAsync(sessionInstance: any, frame: number): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const state = getStore().getState(); @@ -753,17 +714,20 @@ ThunkAction { // TODO: use affected IDs as an optimization const [undo] = state.annotation.annotations.history.undo.slice(-1); - const undoLog = await sessionInstance.logger.log(LogType.undoAction, { - name: undo[0], - frame: undo[1], - count: 1, - }, true); + const undoLog = await sessionInstance.logger.log( + LogType.undoAction, + { + name: undo[0], + frame: undo[1], + count: 1, + }, + true, + ); dispatch(changeFrameAsync(undo[1])); await sessionInstance.actions.undo(); const history = await sessionInstance.actions.get(); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const [minZ, maxZ] = computeZRange(states); await undoLog.close(); @@ -787,8 +751,7 @@ ThunkAction { }; } -export function redoActionAsync(sessionInstance: any, frame: number): -ThunkAction { +export function redoActionAsync(sessionInstance: any, frame: number): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const state = getStore().getState(); @@ -796,16 +759,19 @@ ThunkAction { // TODO: use affected IDs as an optimization const [redo] = state.annotation.annotations.history.redo.slice(-1); - const redoLog = await sessionInstance.logger.log(LogType.redoAction, { - name: redo[0], - frame: redo[1], - count: 1, - }, true); + const redoLog = await sessionInstance.logger.log( + LogType.redoAction, + { + name: redo[0], + frame: redo[1], + count: 1, + }, + true, + ); dispatch(changeFrameAsync(redo[1])); await sessionInstance.actions.redo(); const history = await sessionInstance.actions.get(); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const [minZ, maxZ] = computeZRange(states); await redoLog.close(); @@ -834,27 +800,20 @@ export function rotateCurrentFrame(rotation: Rotation): AnyAction { const { annotation: { player: { - frame: { - number: frameNumber, - }, + frame: { number: frameNumber }, frameAngles, }, job: { instance: job, - instance: { - startFrame, - }, + instance: { startFrame }, }, }, settings: { - player: { - rotateAll, - }, + player: { rotateAll }, }, } = state; - const frameAngle = (frameAngles[frameNumber - startFrame] - + (rotation === Rotation.CLOCKWISE90 ? 90 : 270)) % 360; + const frameAngle = (frameAngles[frameNumber - startFrame] + (rotation === Rotation.CLOCKWISE90 ? 90 : 270)) % 360; job.logger.log(LogType.rotateImage, { angle: frameAngle }); @@ -913,17 +872,16 @@ export function closeJob(): ThunkAction { }; } -export function getJobAsync( - tid: number, - jid: number, - initialFrame: number, - initialFilters: string[], -): ThunkAction { +export function getJobAsync(tid: number, jid: number, initialFrame: number, initialFilters: string[]): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const state: CombinedState = getStore().getState(); const filters = initialFilters; - const { showAllInterpolationTracks } = state.settings.workspace; + const { + settings: { + workspace: { showAllInterpolationTracks }, + }, + } = state; dispatch({ type: AnnotationActionTypes.GET_JOB, @@ -933,10 +891,12 @@ export function getJobAsync( }); const loadJobEvent = await logger.log( - LogType.loadJob, { + LogType.loadJob, + { task_id: tid, job_id: jid, - }, true, + }, + true, ); // Check state if the task is already there @@ -950,19 +910,32 @@ export function getJobAsync( } // Finally get the job from the task - const job = task.jobs - .filter((_job: any) => _job.id === jid)[0]; + const job = task.jobs.filter((_job: any) => _job.id === jid)[0]; if (!job) { throw new Error(`Task ${tid} doesn't contain the job ${jid}`); } + if (!task.labels.length && task.projectId) { + throw new Error(`Project ${task.projectId} does not contain any label`); + } + const frameNumber = Math.max(Math.min(job.stopFrame, initialFrame), job.startFrame); const frameData = await job.frames.get(frameNumber); // call first getting of frame data before rendering interface // to load and decode first chunk - await frameData.data(); - const states = await job.annotations - .get(frameNumber, showAllInterpolationTracks, filters); + try { + await frameData.data(); + } catch (error) { + dispatch({ + type: AnnotationActionTypes.GET_DATA_FAILED, + payload: { + error, + }, + }); + } + const states = await job.annotations.get(frameNumber, showAllInterpolationTracks, filters); + const issues = await job.issues(); + const reviews = await job.reviews(); const [minZ, maxZ] = computeZRange(states); const colors = [...cvat.enums.colors]; @@ -972,6 +945,8 @@ export function getJobAsync( type: AnnotationActionTypes.GET_JOB_SUCCESS, payload: { job, + issues, + reviews, states, frameNumber, frameFilename: frameData.filename, @@ -994,10 +969,9 @@ export function getJobAsync( }; } -export function saveAnnotationsAsync(sessionInstance: any): -ThunkAction { +export function saveAnnotationsAsync(sessionInstance: any, afterSave?: () => void): ThunkAction { return async (dispatch: ActionCreator): Promise => { - const { filters, frame, showAllInterpolationTracks } = receiveAnnotationsParameters(); + const { filters, showAllInterpolationTracks } = receiveAnnotationsParameters(); dispatch({ type: AnnotationActionTypes.SAVE_ANNOTATIONS, @@ -1005,9 +979,7 @@ ThunkAction { }); try { - const saveJobEvent = await sessionInstance.logger.log( - LogType.saveJob, {}, true, - ); + const saveJobEvent = await sessionInstance.logger.log(LogType.saveJob, {}, true); await sessionInstance.annotations.save((status: string) => { dispatch({ @@ -1017,16 +989,16 @@ ThunkAction { }, }); }); - - const states = await sessionInstance - .annotations.get(frame, showAllInterpolationTracks, filters); await saveJobEvent.close(); - await sessionInstance.logger.log( - LogType.sendTaskInfo, - await jobInfoGenerator(sessionInstance), - ); + await sessionInstance.logger.log(LogType.sendTaskInfo, await jobInfoGenerator(sessionInstance)); dispatch(saveLogsAsync()); + const { frame } = receiveAnnotationsParameters(); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); + if (typeof afterSave === 'function') { + afterSave(); + } + dispatch({ type: AnnotationActionTypes.SAVE_ANNOTATIONS_SUCCESS, payload: { @@ -1085,6 +1057,15 @@ export function shapeDrawn(): AnyAction { }; } +export function selectIssuePosition(enabled: boolean): AnyAction { + return { + type: AnnotationActionTypes.SELECT_ISSUE_POSITION, + payload: { + enabled, + }, + }; +} + export function mergeObjects(enabled: boolean): AnyAction { return { type: AnnotationActionTypes.MERGE_OBJECTS, @@ -1115,10 +1096,7 @@ export function splitTrack(enabled: boolean): AnyAction { export function updateAnnotationsAsync(statesToUpdate: any[]): ThunkAction { return async (dispatch: ActionCreator): Promise => { const { - jobInstance, - filters, - frame, - showAllInterpolationTracks, + jobInstance, filters, frame, showAllInterpolationTracks, } = receiveAnnotationsParameters(); try { @@ -1127,8 +1105,7 @@ export function updateAnnotationsAsync(statesToUpdate: any[]): ThunkAction { dispatch(activateObject(null, null)); } - const promises = statesToUpdate - .map((objectState: any): Promise => objectState.save()); + const promises = statesToUpdate.map((objectState: any): Promise => objectState.save()); const states = await Promise.all(promises); const history = await jobInstance.actions.get(); const [minZ, maxZ] = computeZRange(states); @@ -1143,8 +1120,7 @@ export function updateAnnotationsAsync(statesToUpdate: any[]): ThunkAction { }, }); } catch (error) { - const states = await jobInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await jobInstance.annotations.get(frame, showAllInterpolationTracks, filters); dispatch({ type: AnnotationActionTypes.UPDATE_ANNOTATIONS_FAILED, payload: { @@ -1156,14 +1132,12 @@ export function updateAnnotationsAsync(statesToUpdate: any[]): ThunkAction { }; } -export function createAnnotationsAsync(sessionInstance: any, frame: number, statesToCreate: any[]): -ThunkAction { +export function createAnnotationsAsync(sessionInstance: any, frame: number, statesToCreate: any[]): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const { filters, showAllInterpolationTracks } = receiveAnnotationsParameters(); await sessionInstance.annotations.put(statesToCreate); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const history = await sessionInstance.actions.get(); dispatch({ @@ -1184,14 +1158,12 @@ ThunkAction { }; } -export function mergeAnnotationsAsync(sessionInstance: any, frame: number, statesToMerge: any[]): -ThunkAction { +export function mergeAnnotationsAsync(sessionInstance: any, frame: number, statesToMerge: any[]): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const { filters, showAllInterpolationTracks } = receiveAnnotationsParameters(); await sessionInstance.annotations.merge(statesToMerge); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const history = await sessionInstance.actions.get(); dispatch({ @@ -1219,11 +1191,7 @@ export function resetAnnotationsGroup(): AnyAction { }; } -export function groupAnnotationsAsync( - sessionInstance: any, - frame: number, - statesToGroup: any[], -): ThunkAction { +export function groupAnnotationsAsync(sessionInstance: any, frame: number, statesToGroup: any[]): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const { filters, showAllInterpolationTracks } = receiveAnnotationsParameters(); @@ -1236,8 +1204,7 @@ export function groupAnnotationsAsync( }); await sessionInstance.annotations.group(statesToGroup, reset); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const history = await sessionInstance.actions.get(); dispatch({ @@ -1258,14 +1225,12 @@ export function groupAnnotationsAsync( }; } -export function splitAnnotationsAsync(sessionInstance: any, frame: number, stateToSplit: any): -ThunkAction { +export function splitAnnotationsAsync(sessionInstance: any, frame: number, stateToSplit: any): ThunkAction { return async (dispatch: ActionCreator): Promise => { const { filters, showAllInterpolationTracks } = receiveAnnotationsParameters(); try { await sessionInstance.annotations.split(stateToSplit, frame); - const states = await sessionInstance.annotations - .get(frame, showAllInterpolationTracks, filters); + const states = await sessionInstance.annotations.get(frame, showAllInterpolationTracks, filters); const history = await sessionInstance.actions.get(); dispatch({ @@ -1286,14 +1251,12 @@ ThunkAction { }; } -export function changeGroupColorAsync( - group: number, - color: string, -): ThunkAction { +export function changeGroupColorAsync(group: number, color: string): ThunkAction { return async (dispatch: ActionCreator): Promise => { const state: CombinedState = getStore().getState(); - const groupStates = state.annotation.annotations.states - .filter((_state: any): boolean => _state.group.id === group); + const groupStates = state.annotation.annotations.states.filter( + (_state: any): boolean => _state.group.id === group, + ); if (groupStates.length) { groupStates[0].group.color = color; dispatch(updateAnnotationsAsync(groupStates)); @@ -1303,11 +1266,7 @@ export function changeGroupColorAsync( }; } -export function searchAnnotationsAsync( - sessionInstance: any, - frameFrom: number, - frameTo: number, -): ThunkAction { +export function searchAnnotationsAsync(sessionInstance: any, frameFrom: number, frameTo: number): ThunkAction { return async (dispatch: ActionCreator): Promise => { try { const { filters } = receiveAnnotationsParameters(); @@ -1326,23 +1285,33 @@ export function searchAnnotationsAsync( }; } +export function searchEmptyFrameAsync(sessionInstance: any, frameFrom: number, frameTo: number): ThunkAction { + return async (dispatch: ActionCreator): Promise => { + try { + const frame = await sessionInstance.annotations.searchEmpty(frameFrom, frameTo); + if (frame !== null) { + dispatch(changeFrameAsync(frame)); + } + } catch (error) { + dispatch({ + type: AnnotationActionTypes.SEARCH_EMPTY_FRAME_FAILED, + payload: { + error, + }, + }); + } + }; +} + export function pasteShapeAsync(): ThunkAction { return async (dispatch: ActionCreator): Promise => { const { - canvas: { - instance: canvasInstance, - }, - job: { - instance: jobInstance, - }, + canvas: { instance: canvasInstance }, + job: { instance: jobInstance }, player: { - frame: { - number: frameNumber, - }, - }, - drawing: { - activeInitialState: initialState, + frame: { number: frameNumber }, }, + drawing: { activeInitialState: initialState }, } = getStore().getState().annotation; if (initialState) { @@ -1385,22 +1354,35 @@ export function pasteShapeAsync(): ThunkAction { }; } +export function interactWithCanvas(activeInteractor: Model, activeLabelID: number): AnyAction { + return { + type: AnnotationActionTypes.INTERACT_WITH_CANVAS, + payload: { + activeInteractor, + activeLabelID, + }, + }; +} + +export function setAIToolsRef(ref: MutableRefObject): AnyAction { + return { + type: AnnotationActionTypes.SET_AI_TOOLS_REF, + payload: { + aiToolsRef: ref, + }, + }; +} + export function repeatDrawShapeAsync(): ThunkAction { return async (dispatch: ActionCreator): Promise => { const { - canvas: { - instance: canvasInstance, - }, - job: { - labels, - instance: jobInstance, - }, + canvas: { instance: canvasInstance }, + job: { labels, instance: jobInstance }, player: { - frame: { - number: frameNumber, - }, + frame: { number: frameNumber }, }, drawing: { + activeInteractor, activeObjectType, activeLabelID, activeShapeType, @@ -1410,6 +1392,25 @@ export function repeatDrawShapeAsync(): ThunkAction { } = getStore().getState().annotation; let activeControl = ActiveControl.CURSOR; + if (activeInteractor) { + if (activeInteractor.type === 'tracker') { + canvasInstance.interact({ + enabled: true, + shapeType: 'rectangle', + }); + dispatch(interactWithCanvas(activeInteractor, activeLabelID)); + } else { + canvasInstance.interact({ + enabled: true, + shapeType: 'points', + ...activeInteractor.params.canvas, + }); + dispatch(interactWithCanvas(activeInteractor, activeLabelID)); + } + + return; + } + if (activeShapeType === ShapeType.RECTANGLE) { activeControl = ActiveControl.DRAW_RECTANGLE; } else if (activeShapeType === ShapeType.POINTS) { @@ -1443,7 +1444,7 @@ export function repeatDrawShapeAsync(): ThunkAction { rectDrawingMethod: activeRectDrawingMethod, numberOfPoints: activeNumOfPoints, shapeType: activeShapeType, - crosshair: activeShapeType === ShapeType.RECTANGLE, + crosshair: [ShapeType.RECTANGLE, ShapeType.CUBOID].includes(activeShapeType), }); } }; @@ -1452,18 +1453,12 @@ export function repeatDrawShapeAsync(): ThunkAction { export function redrawShapeAsync(): ThunkAction { return async (dispatch: ActionCreator): Promise => { const { - annotations: { - activatedStateID, - states, - }, - canvas: { - instance: canvasInstance, - }, + annotations: { activatedStateID, states }, + canvas: { instance: canvasInstance }, } = getStore().getState().annotation; if (activatedStateID !== null) { - const [state] = states - .filter((_state: any): boolean => _state.clientID === activatedStateID); + const [state] = states.filter((_state: any): boolean => _state.clientID === activatedStateID); if (state && state.objectType !== ObjectType.TAG) { let activeControl = ActiveControl.CURSOR; if (state.shapeType === ShapeType.RECTANGLE) { @@ -1490,9 +1485,36 @@ export function redrawShapeAsync(): ThunkAction { enabled: true, redraw: activatedStateID, shapeType: state.shapeType, - crosshair: state.shapeType === ShapeType.RECTANGLE, + crosshair: [ShapeType.RECTANGLE, ShapeType.CUBOID].includes(state.shapeType), }); } } }; } + +export function switchRequestReviewDialog(visible: boolean): AnyAction { + return { + type: AnnotationActionTypes.SWITCH_REQUEST_REVIEW_DIALOG, + payload: { + visible, + }, + }; +} + +export function switchSubmitReviewDialog(visible: boolean): AnyAction { + return { + type: AnnotationActionTypes.SWITCH_SUBMIT_REVIEW_DIALOG, + payload: { + visible, + }, + }; +} + +export function setForceExitAnnotationFlag(forceExit: boolean): AnyAction { + return { + type: AnnotationActionTypes.SET_FORCE_EXIT_ANNOTATION_PAGE_FLAG, + payload: { + forceExit, + }, + }; +} diff --git a/cvat-ui/src/actions/auth-actions.ts b/cvat-ui/src/actions/auth-actions.ts index f12049fa..9db70b5a 100644 --- a/cvat-ui/src/actions/auth-actions.ts +++ b/cvat-ui/src/actions/auth-actions.ts @@ -25,6 +25,12 @@ export enum AuthActionTypes { CHANGE_PASSWORD_SUCCESS = 'CHANGE_PASSWORD_SUCCESS', CHANGE_PASSWORD_FAILED = 'CHANGE_PASSWORD_FAILED', SWITCH_CHANGE_PASSWORD_DIALOG = 'SWITCH_CHANGE_PASSWORD_DIALOG', + REQUEST_PASSWORD_RESET = 'REQUEST_PASSWORD_RESET', + REQUEST_PASSWORD_RESET_SUCCESS = 'REQUEST_PASSWORD_RESET_SUCCESS', + REQUEST_PASSWORD_RESET_FAILED = 'REQUEST_PASSWORD_RESET_FAILED', + RESET_PASSWORD = 'RESET_PASSWORD_CONFIRM', + RESET_PASSWORD_SUCCESS = 'RESET_PASSWORD_CONFIRM_SUCCESS', + RESET_PASSWORD_FAILED = 'RESET_PASSWORD_CONFIRM_FAILED', LOAD_AUTH_ACTIONS = 'LOAD_AUTH_ACTIONS', LOAD_AUTH_ACTIONS_SUCCESS = 'LOAD_AUTH_ACTIONS_SUCCESS', LOAD_AUTH_ACTIONS_FAILED = 'LOAD_AUTH_ACTIONS_FAILED', @@ -44,19 +50,22 @@ export const authActions = { logoutFailed: (error: any) => createAction(AuthActionTypes.LOGOUT_FAILED, { error }), changePassword: () => createAction(AuthActionTypes.CHANGE_PASSWORD), changePasswordSuccess: () => createAction(AuthActionTypes.CHANGE_PASSWORD_SUCCESS), - changePasswordFailed: (error: any) => ( - createAction(AuthActionTypes.CHANGE_PASSWORD_FAILED, { error }) - ), - switchChangePasswordDialog: (showChangePasswordDialog: boolean) => ( - createAction(AuthActionTypes.SWITCH_CHANGE_PASSWORD_DIALOG, { showChangePasswordDialog }) - ), + changePasswordFailed: (error: any) => createAction(AuthActionTypes.CHANGE_PASSWORD_FAILED, { error }), + switchChangePasswordDialog: (showChangePasswordDialog: boolean) => + createAction(AuthActionTypes.SWITCH_CHANGE_PASSWORD_DIALOG, { showChangePasswordDialog }), + requestPasswordReset: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET), + requestPasswordResetSuccess: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_SUCCESS), + requestPasswordResetFailed: (error: any) => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_FAILED, { error }), + resetPassword: () => createAction(AuthActionTypes.RESET_PASSWORD), + resetPasswordSuccess: () => createAction(AuthActionTypes.RESET_PASSWORD_SUCCESS), + resetPasswordFailed: (error: any) => createAction(AuthActionTypes.RESET_PASSWORD_FAILED, { error }), loadServerAuthActions: () => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS), - loadServerAuthActionsSuccess: (allowChangePassword: boolean) => ( - createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_SUCCESS, { allowChangePassword }) - ), - loadServerAuthActionsFailed: (error: any) => ( - createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_FAILED, { error }) - ), + loadServerAuthActionsSuccess: (allowChangePassword: boolean, allowResetPassword: boolean) => + createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_SUCCESS, { + allowChangePassword, + allowResetPassword, + }), + loadServerAuthActionsFailed: (error: any) => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_FAILED, { error }), }; export type AuthActions = ActionUnion; @@ -69,14 +78,19 @@ export const registerAsync = ( password1: string, password2: string, confirmations: UserConfirmation[], -): ThunkAction => async ( - dispatch, -) => { +): ThunkAction => async (dispatch) => { dispatch(authActions.register()); try { - const user = await cvat.server.register(username, firstName, lastName, email, password1, password2, - confirmations); + const user = await cvat.server.register( + username, + firstName, + lastName, + email, + password1, + password2, + confirmations, + ); dispatch(authActions.registerSuccess(user)); } catch (error) { @@ -123,8 +137,11 @@ export const authorizedAsync = (): ThunkAction => async (dispatch) => { } }; -export const changePasswordAsync = (oldPassword: string, - newPassword1: string, newPassword2: string): ThunkAction => async (dispatch) => { +export const changePasswordAsync = ( + oldPassword: string, + newPassword1: string, + newPassword2: string, +): ThunkAction => async (dispatch) => { dispatch(authActions.changePassword()); try { @@ -135,16 +152,44 @@ export const changePasswordAsync = (oldPassword: string, } }; +export const requestPasswordResetAsync = (email: string): ThunkAction => async (dispatch) => { + dispatch(authActions.requestPasswordReset()); + + try { + await cvat.server.requestPasswordReset(email); + dispatch(authActions.requestPasswordResetSuccess()); + } catch (error) { + dispatch(authActions.requestPasswordResetFailed(error)); + } +}; + +export const resetPasswordAsync = ( + newPassword1: string, + newPassword2: string, + uid: string, + token: string, +): ThunkAction => async (dispatch) => { + dispatch(authActions.resetPassword()); + + try { + await cvat.server.resetPassword(newPassword1, newPassword2, uid, token); + dispatch(authActions.resetPasswordSuccess()); + } catch (error) { + dispatch(authActions.resetPasswordFailed(error)); + } +}; + export const loadAuthActionsAsync = (): ThunkAction => async (dispatch) => { dispatch(authActions.loadServerAuthActions()); try { const promises: Promise[] = [ isReachable(`${cvat.config.backendAPI}/auth/password/change`, 'OPTIONS'), + isReachable(`${cvat.config.backendAPI}/auth/password/reset`, 'OPTIONS'), ]; - const [allowChangePassword] = await Promise.all(promises); + const [allowChangePassword, allowResetPassword] = await Promise.all(promises); - dispatch(authActions.loadServerAuthActionsSuccess(allowChangePassword)); + dispatch(authActions.loadServerAuthActionsSuccess(allowChangePassword, allowResetPassword)); } catch (error) { dispatch(authActions.loadServerAuthActionsFailed(error)); } diff --git a/cvat-ui/src/actions/boundaries-actions.ts b/cvat-ui/src/actions/boundaries-actions.ts index 93350057..0e22f609 100644 --- a/cvat-ui/src/actions/boundaries-actions.ts +++ b/cvat-ui/src/actions/boundaries-actions.ts @@ -2,12 +2,7 @@ // // SPDX-License-Identifier: MIT -import { - ActionUnion, - createAction, - ThunkAction, - ThunkDispatch, -} from 'utils/redux'; +import { ActionUnion, createAction, ThunkAction, ThunkDispatch } from 'utils/redux'; import getCore from 'cvat-core-wrapper'; import { LogType } from 'cvat-logger'; import { computeZRange } from './annotation-actions'; @@ -28,15 +23,16 @@ export const boundariesActions = { minZ: number, maxZ: number, colors: string[], - ) => createAction(BoundariesActionTypes.RESET_AFTER_ERROR, { - job, - states, - frameNumber, - frameData, - minZ, - maxZ, - colors, - }), + ) => + createAction(BoundariesActionTypes.RESET_AFTER_ERROR, { + job, + states, + frameNumber, + frameData, + minZ, + maxZ, + colors, + }), throwResetError: () => createAction(BoundariesActionTypes.THROW_RESET_ERROR), }; @@ -51,33 +47,16 @@ export function resetAfterErrorAsync(): ThunkAction { const { showAllInterpolationTracks } = state.settings.workspace; const frameNumber = Math.max(Math.min(job.stopFrame, currentFrame), job.startFrame); - const states = await job.annotations - .get(frameNumber, showAllInterpolationTracks, []); + const states = await job.annotations.get(frameNumber, showAllInterpolationTracks, []); const frameData = await job.frames.get(frameNumber); const [minZ, maxZ] = computeZRange(states); const colors = [...cvat.enums.colors]; await job.logger.log(LogType.restoreJob); - dispatch(boundariesActions.resetAfterError( - job, - states, - frameNumber, - frameData, - minZ, - maxZ, - colors, - )); + dispatch(boundariesActions.resetAfterError(job, states, frameNumber, frameData, minZ, maxZ, colors)); } else { - dispatch(boundariesActions.resetAfterError( - null, - [], - 0, - null, - 0, - 0, - [], - )); + dispatch(boundariesActions.resetAfterError(null, [], 0, null, 0, 0, [])); } } catch (error) { dispatch(boundariesActions.throwResetError()); @@ -85,4 +64,4 @@ export function resetAfterErrorAsync(): ThunkAction { }; } -export type boundariesActions = ActionUnion; +export type BoundariesActions = ActionUnion; diff --git a/cvat-ui/src/actions/formats-actions.ts b/cvat-ui/src/actions/formats-actions.ts index 0644d26b..a8c7a158 100644 --- a/cvat-ui/src/actions/formats-actions.ts +++ b/cvat-ui/src/actions/formats-actions.ts @@ -15,14 +15,11 @@ export enum FormatsActionTypes { const formatsActions = { getFormats: () => createAction(FormatsActionTypes.GET_FORMATS), - getFormatsSuccess: (annotationFormats: any) => ( + getFormatsSuccess: (annotationFormats: any) => createAction(FormatsActionTypes.GET_FORMATS_SUCCESS, { annotationFormats, - }) - ), - getFormatsFailed: (error: any) => ( - createAction(FormatsActionTypes.GET_FORMATS_FAILED, { error }) - ), + }), + getFormatsFailed: (error: any) => createAction(FormatsActionTypes.GET_FORMATS_FAILED, { error }), }; export type FormatsActions = ActionUnion; @@ -35,9 +32,7 @@ export function getFormatsAsync(): ThunkAction { try { annotationFormats = await cvat.server.formats(); - dispatch( - formatsActions.getFormatsSuccess(annotationFormats), - ); + dispatch(formatsActions.getFormatsSuccess(annotationFormats)); } catch (error) { dispatch(formatsActions.getFormatsFailed(error)); } diff --git a/cvat-ui/src/actions/models-actions.ts b/cvat-ui/src/actions/models-actions.ts index 1f2afe14..8b31d1a7 100644 --- a/cvat-ui/src/actions/models-actions.ts +++ b/cvat-ui/src/actions/models-actions.ts @@ -10,11 +10,6 @@ export enum ModelsActionTypes { GET_MODELS = 'GET_MODELS', GET_MODELS_SUCCESS = 'GET_MODELS_SUCCESS', GET_MODELS_FAILED = 'GET_MODELS_FAILED', - DELETE_MODEL = 'DELETE_MODEL', - CREATE_MODEL = 'CREATE_MODEL', - CREATE_MODEL_SUCCESS = 'CREATE_MODEL_SUCCESS', - CREATE_MODEL_FAILED = 'CREATE_MODEL_FAILED', - CREATE_MODEL_STATUS_UPDATED = 'CREATE_MODEL_STATUS_UPDATED', START_INFERENCE_FAILED = 'START_INFERENCE_FAILED', GET_INFERENCE_STATUS_SUCCESS = 'GET_INFERENCE_STATUS_SUCCESS', GET_INFERENCE_STATUS_FAILED = 'GET_INFERENCE_STATUS_FAILED', @@ -27,52 +22,44 @@ export enum ModelsActionTypes { export const modelsActions = { getModels: () => createAction(ModelsActionTypes.GET_MODELS), - getModelsSuccess: (models: Model[]) => createAction( - ModelsActionTypes.GET_MODELS_SUCCESS, { + getModelsSuccess: (models: Model[]) => + createAction(ModelsActionTypes.GET_MODELS_SUCCESS, { models, - }, - ), - getModelsFailed: (error: any) => createAction( - ModelsActionTypes.GET_MODELS_FAILED, { + }), + getModelsFailed: (error: any) => + createAction(ModelsActionTypes.GET_MODELS_FAILED, { error, - }, - ), + }), fetchMetaFailed: (error: any) => createAction(ModelsActionTypes.FETCH_META_FAILED, { error }), - getInferenceStatusSuccess: (taskID: number, activeInference: ActiveInference) => createAction( - ModelsActionTypes.GET_INFERENCE_STATUS_SUCCESS, { + getInferenceStatusSuccess: (taskID: number, activeInference: ActiveInference) => + createAction(ModelsActionTypes.GET_INFERENCE_STATUS_SUCCESS, { taskID, activeInference, - }, - ), - getInferenceStatusFailed: (taskID: number, error: any) => createAction( - ModelsActionTypes.GET_INFERENCE_STATUS_FAILED, { + }), + getInferenceStatusFailed: (taskID: number, error: any) => + createAction(ModelsActionTypes.GET_INFERENCE_STATUS_FAILED, { taskID, error, - }, - ), - startInferenceFailed: (taskID: number, error: any) => createAction( - ModelsActionTypes.START_INFERENCE_FAILED, { + }), + startInferenceFailed: (taskID: number, error: any) => + createAction(ModelsActionTypes.START_INFERENCE_FAILED, { taskID, error, - }, - ), - cancelInferenceSuccess: (taskID: number) => createAction( - ModelsActionTypes.CANCEL_INFERENCE_SUCCESS, { + }), + cancelInferenceSuccess: (taskID: number) => + createAction(ModelsActionTypes.CANCEL_INFERENCE_SUCCESS, { taskID, - }, - ), - cancelInferenceFailed: (taskID: number, error: any) => createAction( - ModelsActionTypes.CANCEL_INFERENCE_FAILED, { + }), + cancelInferenceFailed: (taskID: number, error: any) => + createAction(ModelsActionTypes.CANCEL_INFERENCE_FAILED, { taskID, error, - }, - ), + }), closeRunModelDialog: () => createAction(ModelsActionTypes.CLOSE_RUN_MODEL_DIALOG), - showRunModelDialog: (taskInstance: any) => createAction( - ModelsActionTypes.SHOW_RUN_MODEL_DIALOG, { + showRunModelDialog: (taskInstance: any) => + createAction(ModelsActionTypes.SHOW_RUN_MODEL_DIALOG, { taskInstance, - }, - ), + }), }; export type ModelsActions = ActionUnion; @@ -84,8 +71,7 @@ export function getModelsAsync(): ThunkAction { dispatch(modelsActions.getModels()); try { - const models = (await core.lambda.list()) - .filter((model: Model) => ['detector', 'reid'].includes(model.type)); + const models = await core.lambda.list(); dispatch(modelsActions.getModelsSuccess(models)); } catch (error) { dispatch(modelsActions.getModelsFailed(error)); @@ -93,43 +79,45 @@ export function getModelsAsync(): ThunkAction { }; } - interface InferenceMeta { taskID: number; requestID: string; } -function listen( - inferenceMeta: InferenceMeta, - dispatch: (action: ModelsActions) => void, -): void { +function listen(inferenceMeta: InferenceMeta, dispatch: (action: ModelsActions) => void): void { const { taskID, requestID } = inferenceMeta; - core.lambda.listen(requestID, (status: RQStatus, progress: number, message: string) => { - if (status === RQStatus.failed || status === RQStatus.unknown) { - dispatch(modelsActions.getInferenceStatusFailed( - taskID, - new Error( - `Inference status for the task ${taskID} is ${status}. ${message}`, - ), - )); - - return; - } - - dispatch(modelsActions.getInferenceStatusSuccess(taskID, { - status, - progress, - error: message, - id: requestID, - })); - }).catch((error: Error) => { - dispatch(modelsActions.getInferenceStatusFailed(taskID, { - status: 'unknown', - progress: 0, - error: error.toString(), - id: requestID, - })); - }); + core.lambda + .listen(requestID, (status: RQStatus, progress: number, message: string) => { + if (status === RQStatus.failed || status === RQStatus.unknown) { + dispatch( + modelsActions.getInferenceStatusFailed( + taskID, + new Error(`Inference status for the task ${taskID} is ${status}. ${message}`), + ), + ); + + return; + } + + dispatch( + modelsActions.getInferenceStatusSuccess(taskID, { + status, + progress, + error: message, + id: requestID, + }), + ); + }) + .catch((error: Error) => { + dispatch( + modelsActions.getInferenceStatusFailed(taskID, { + status: 'unknown', + progress: 0, + error: error.toString(), + id: requestID, + }), + ); + }); } export function getInferenceStatusAsync(): ThunkAction { @@ -154,23 +142,21 @@ export function getInferenceStatusAsync(): ThunkAction { }; } -export function startInferenceAsync( - taskInstance: any, - model: Model, - body: object, -): ThunkAction { +export function startInferenceAsync(taskInstance: any, model: Model, body: object): ThunkAction { return async (dispatch): Promise => { try { const requestID: string = await core.lambda.run(taskInstance, model, body); - const dispatchCallback = (action: ModelsActions): void => { dispatch(action); }; - listen({ - taskID: taskInstance.id, - requestID, - }, dispatchCallback); + listen( + { + taskID: taskInstance.id, + requestID, + }, + dispatchCallback, + ); } catch (error) { dispatch(modelsActions.startInferenceFailed(taskInstance.id, error)); } diff --git a/cvat-ui/src/actions/plugins-actions.ts b/cvat-ui/src/actions/plugins-actions.ts index 6b5ca2c9..20e5c850 100644 --- a/cvat-ui/src/actions/plugins-actions.ts +++ b/cvat-ui/src/actions/plugins-actions.ts @@ -3,46 +3,31 @@ // SPDX-License-Identifier: MIT import { ActionUnion, createAction, ThunkAction } from 'utils/redux'; -import { SupportedPlugins } from 'reducers/interfaces'; -import PluginChecker from 'utils/plugin-checker'; +import { PluginsList } from 'reducers/interfaces'; +import getCore from '../cvat-core-wrapper'; + +const core = getCore(); export enum PluginsActionTypes { - CHECK_PLUGINS = 'CHECK_PLUGINS', - CHECKED_ALL_PLUGINS = 'CHECKED_ALL_PLUGINS', + GET_PLUGINS = 'GET_PLUGINS', + GET_PLUGINS_SUCCESS = 'GET_PLUGINS_SUCCESS', + GET_PLUGINS_FAILED = 'GET_PLUGINS_FAILED', } -type PluginObjects = Record; - const pluginActions = { - checkPlugins: () => createAction(PluginsActionTypes.CHECK_PLUGINS), - checkedAllPlugins: (list: PluginObjects) => ( - createAction(PluginsActionTypes.CHECKED_ALL_PLUGINS, { - list, - }) - ), + checkPlugins: () => createAction(PluginsActionTypes.GET_PLUGINS), + checkPluginsSuccess: (list: PluginsList) => createAction(PluginsActionTypes.GET_PLUGINS_SUCCESS, { list }), + checkPluginsFailed: (error: any) => createAction(PluginsActionTypes.GET_PLUGINS_FAILED, { error }), }; export type PluginActions = ActionUnion; -export function checkPluginsAsync(): ThunkAction { - return async (dispatch): Promise => { - dispatch(pluginActions.checkPlugins()); - const plugins: PluginObjects = { - ANALYTICS: false, - GIT_INTEGRATION: false, - DEXTR_SEGMENTATION: false, - }; - - const promises: Promise[] = [ - // check must return true/false with no exceptions - PluginChecker.check(SupportedPlugins.ANALYTICS), - PluginChecker.check(SupportedPlugins.GIT_INTEGRATION), - PluginChecker.check(SupportedPlugins.DEXTR_SEGMENTATION), - ]; - - const values = await Promise.all(promises); - [plugins.ANALYTICS, plugins.GIT_INTEGRATION, - plugins.DEXTR_SEGMENTATION] = values; - dispatch(pluginActions.checkedAllPlugins(plugins)); - }; -} +export const getPluginsAsync = (): ThunkAction => async (dispatch): Promise => { + dispatch(pluginActions.checkPlugins()); + try { + const list: PluginsList = await core.server.installedApps(); + dispatch(pluginActions.checkPluginsSuccess(list)); + } catch (error) { + dispatch(pluginActions.checkPluginsFailed(error)); + } +}; diff --git a/cvat-ui/src/actions/projects-actions.ts b/cvat-ui/src/actions/projects-actions.ts new file mode 100644 index 00000000..d2794db3 --- /dev/null +++ b/cvat-ui/src/actions/projects-actions.ts @@ -0,0 +1,173 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import { Dispatch, ActionCreator } from 'redux'; + +import { ActionUnion, createAction, ThunkAction } from 'utils/redux'; +import { ProjectsQuery, CombinedState } from 'reducers/interfaces'; +import { getTasksSuccess, updateTaskSuccess } from 'actions/tasks-actions'; +import { getCVATStore } from 'cvat-store'; +import getCore from 'cvat-core-wrapper'; + +const cvat = getCore(); + +export enum ProjectsActionTypes { + UPDATE_PROJECTS_GETTING_QUERY = 'UPDATE_PROJECTS_GETTING_QUERY', + GET_PROJECTS = 'GET_PROJECTS', + GET_PROJECTS_SUCCESS = 'GET_PROJECTS_SUCCESS', + GET_PROJECTS_FAILED = 'GET_PROJECTS_FAILED', + CREATE_PROJECT = 'CREATE_PROJECT', + CREATE_PROJECT_SUCCESS = 'CREATE_PROJECT_SUCCESS', + CREATE_PROJECT_FAILED = 'CREATE_PROJECT_FAILED', + UPDATE_PROJECT = 'UPDATE_PROJECT', + UPDATE_PROJECT_SUCCESS = 'UPDATE_PROJECT_SUCCESS', + UPDATE_PROJECT_FAILED = 'UPDATE_PROJECT_FAILED', + DELETE_PROJECT = 'DELETE_PROJECT', + DELETE_PROJECT_SUCCESS = 'DELETE_PROJECT_SUCCESS', + DELETE_PROJECT_FAILED = 'DELETE_PROJECT_FAILED', +} + +// prettier-ignore +const projectActions = { + getProjects: () => createAction(ProjectsActionTypes.GET_PROJECTS), + getProjectsSuccess: (array: any[], count: number) => ( + createAction(ProjectsActionTypes.GET_PROJECTS_SUCCESS, { array, count }) + ), + getProjectsFailed: (error: any) => createAction(ProjectsActionTypes.GET_PROJECTS_FAILED, { error }), + updateProjectsGettingQuery: (query: Partial) => ( + createAction(ProjectsActionTypes.UPDATE_PROJECTS_GETTING_QUERY, { query }) + ), + createProject: () => createAction(ProjectsActionTypes.CREATE_PROJECT), + createProjectSuccess: (projectId: number) => ( + createAction(ProjectsActionTypes.CREATE_PROJECT_SUCCESS, { projectId }) + ), + createProjectFailed: (error: any) => createAction(ProjectsActionTypes.CREATE_PROJECT_FAILED, { error }), + updateProject: () => createAction(ProjectsActionTypes.UPDATE_PROJECT), + updateProjectSuccess: (project: any) => createAction(ProjectsActionTypes.UPDATE_PROJECT_SUCCESS, { project }), + updateProjectFailed: (project: any, error: any) => ( + createAction(ProjectsActionTypes.UPDATE_PROJECT_FAILED, { project, error }) + ), + deleteProject: (projectId: number) => createAction(ProjectsActionTypes.DELETE_PROJECT, { projectId }), + deleteProjectSuccess: (projectId: number) => ( + createAction(ProjectsActionTypes.DELETE_PROJECT_SUCCESS, { projectId }) + ), + deleteProjectFailed: (projectId: number, error: any) => ( + createAction(ProjectsActionTypes.DELETE_PROJECT_FAILED, { projectId, error }) + ), +}; + +export type ProjectActions = ActionUnion; + +export function getProjectsAsync(query: Partial): ThunkAction { + return async (dispatch: ActionCreator): Promise => { + dispatch(projectActions.getProjects()); + dispatch(projectActions.updateProjectsGettingQuery(query)); + + // Clear query object from null fields + const filteredQuery: Partial = { + page: 1, + ...query, + }; + for (const key in filteredQuery) { + if (filteredQuery[key] === null || typeof filteredQuery[key] === 'undefined') { + delete filteredQuery[key]; + } + } + + let result = null; + try { + result = await cvat.projects.get(filteredQuery); + } catch (error) { + dispatch(projectActions.getProjectsFailed(error)); + return; + } + + const array = Array.from(result); + + const tasks: any[] = []; + const taskPreviewPromises: Promise[] = []; + + for (const project of array) { + taskPreviewPromises.push( + ...(project as any).tasks.map((task: any): string => { + tasks.push(task); + return (task as any).frames.preview().catch(() => ''); + }), + ); + } + + const taskPreviews = await Promise.all(taskPreviewPromises); + + dispatch(projectActions.getProjectsSuccess(array, result.count)); + + const store = getCVATStore(); + const state: CombinedState = store.getState(); + + if (!state.tasks.fetching) { + dispatch( + getTasksSuccess(tasks, taskPreviews, tasks.length, { + page: 1, + assignee: null, + id: null, + mode: null, + name: null, + owner: null, + search: null, + status: null, + }), + ); + } + }; +} + +export function createProjectAsync(data: any): ThunkAction { + return async (dispatch: ActionCreator): Promise => { + const projectInstance = new cvat.classes.Project(data); + + dispatch(projectActions.createProject()); + try { + const savedProject = await projectInstance.save(); + dispatch(projectActions.createProjectSuccess(savedProject.id)); + } catch (error) { + dispatch(projectActions.createProjectFailed(error)); + } + }; +} + +export function updateProjectAsync(projectInstance: any): ThunkAction { + return async (dispatch: ActionCreator): Promise => { + try { + dispatch(projectActions.updateProject()); + await projectInstance.save(); + const [project] = await cvat.projects.get({ id: projectInstance.id }); + // TODO: Check case when a project is not available anymore after update + // (assignee changes assignee and project is not public) + dispatch(projectActions.updateProjectSuccess(project)); + project.tasks.forEach((task: any) => { + dispatch(updateTaskSuccess(task, task.id)); + }); + } catch (error) { + let project = null; + try { + [project] = await cvat.projects.get({ id: projectInstance.id }); + } catch (fetchError) { + dispatch(projectActions.updateProjectFailed(projectInstance, error)); + return; + } + dispatch(projectActions.updateProjectFailed(project, error)); + } + }; +} + +export function deleteProjectAsync(projectInstance: any): ThunkAction { + return async (dispatch: ActionCreator): Promise => { + dispatch(projectActions.deleteProject(projectInstance.id)); + try { + await projectInstance.delete(); + dispatch(projectActions.deleteProjectSuccess(projectInstance.id)); + } catch (error) { + dispatch(projectActions.deleteProjectFailed(projectInstance.id, error)); + } + }; +} diff --git a/cvat-ui/src/actions/review-actions.ts b/cvat-ui/src/actions/review-actions.ts new file mode 100644 index 00000000..b433d968 --- /dev/null +++ b/cvat-ui/src/actions/review-actions.ts @@ -0,0 +1,203 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import { ActionUnion, createAction, ThunkAction } from 'utils/redux'; +import getCore from 'cvat-core-wrapper'; +import { updateTaskSuccess } from './tasks-actions'; + +const cvat = getCore(); + +export enum ReviewActionTypes { + INITIALIZE_REVIEW_SUCCESS = 'INITIALIZE_REVIEW_SUCCESS', + INITIALIZE_REVIEW_FAILED = 'INITIALIZE_REVIEW_FAILED', + CREATE_ISSUE = 'CREATE_ISSUE', + START_ISSUE = 'START_ISSUE', + FINISH_ISSUE_SUCCESS = 'FINISH_ISSUE_SUCCESS', + FINISH_ISSUE_FAILED = 'FINISH_ISSUE_FAILED', + CANCEL_ISSUE = 'CANCEL_ISSUE', + RESOLVE_ISSUE = 'RESOLVE_ISSUE', + RESOLVE_ISSUE_SUCCESS = 'RESOLVE_ISSUE_SUCCESS', + RESOLVE_ISSUE_FAILED = 'RESOLVE_ISSUE_FAILED', + REOPEN_ISSUE = 'REOPEN_ISSUE', + REOPEN_ISSUE_SUCCESS = 'REOPEN_ISSUE_SUCCESS', + REOPEN_ISSUE_FAILED = 'REOPEN_ISSUE_FAILED', + COMMENT_ISSUE = 'COMMENT_ISSUE', + COMMENT_ISSUE_SUCCESS = 'COMMENT_ISSUE_SUCCESS', + COMMENT_ISSUE_FAILED = 'COMMENT_ISSUE_FAILED', + SUBMIT_REVIEW = 'SUBMIT_REVIEW', + SUBMIT_REVIEW_SUCCESS = 'SUBMIT_REVIEW_SUCCESS', + SUBMIT_REVIEW_FAILED = 'SUBMIT_REVIEW_FAILED', + SWITCH_ISSUES_HIDDEN_FLAG = 'SWITCH_ISSUES_HIDDEN_FLAG', +} + +export const reviewActions = { + initializeReviewSuccess: (reviewInstance: any, frame: number) => + createAction(ReviewActionTypes.INITIALIZE_REVIEW_SUCCESS, { reviewInstance, frame }), + initializeReviewFailed: (error: any) => createAction(ReviewActionTypes.INITIALIZE_REVIEW_FAILED, { error }), + createIssue: () => createAction(ReviewActionTypes.CREATE_ISSUE, {}), + startIssue: (position: number[]) => + createAction(ReviewActionTypes.START_ISSUE, { position: cvat.classes.Issue.hull(position) }), + finishIssueSuccess: (frame: number, issue: any) => + createAction(ReviewActionTypes.FINISH_ISSUE_SUCCESS, { frame, issue }), + finishIssueFailed: (error: any) => createAction(ReviewActionTypes.FINISH_ISSUE_FAILED, { error }), + cancelIssue: () => createAction(ReviewActionTypes.CANCEL_ISSUE), + commentIssue: (issueId: number) => createAction(ReviewActionTypes.COMMENT_ISSUE, { issueId }), + commentIssueSuccess: () => createAction(ReviewActionTypes.COMMENT_ISSUE_SUCCESS), + commentIssueFailed: (error: any) => createAction(ReviewActionTypes.COMMENT_ISSUE_FAILED, { error }), + resolveIssue: (issueId: number) => createAction(ReviewActionTypes.RESOLVE_ISSUE, { issueId }), + resolveIssueSuccess: () => createAction(ReviewActionTypes.RESOLVE_ISSUE_SUCCESS), + resolveIssueFailed: (error: any) => createAction(ReviewActionTypes.RESOLVE_ISSUE_FAILED, { error }), + reopenIssue: (issueId: number) => createAction(ReviewActionTypes.REOPEN_ISSUE, { issueId }), + reopenIssueSuccess: () => createAction(ReviewActionTypes.REOPEN_ISSUE_SUCCESS), + reopenIssueFailed: (error: any) => createAction(ReviewActionTypes.REOPEN_ISSUE_FAILED, { error }), + submitReview: (reviewId: number) => createAction(ReviewActionTypes.SUBMIT_REVIEW, { reviewId }), + submitReviewSuccess: () => createAction(ReviewActionTypes.SUBMIT_REVIEW_SUCCESS), + submitReviewFailed: (error: any) => createAction(ReviewActionTypes.SUBMIT_REVIEW_FAILED, { error }), + switchIssuesHiddenFlag: (hidden: boolean) => createAction(ReviewActionTypes.SWITCH_ISSUES_HIDDEN_FLAG, { hidden }), +}; + +export type ReviewActions = ActionUnion; + +export const initializeReviewAsync = (): ThunkAction => async (dispatch, getState) => { + try { + const state = getState(); + const { + annotation: { + job: { instance: jobInstance }, + player: { + frame: { number: frame }, + }, + }, + } = state; + + const reviews = await jobInstance.reviews(); + const count = reviews.length; + let reviewInstance = null; + if (count && reviews[count - 1].id < 0) { + reviewInstance = reviews[count - 1]; + } else { + reviewInstance = new cvat.classes.Review({ job: jobInstance.id }); + } + + dispatch(reviewActions.initializeReviewSuccess(reviewInstance, frame)); + } catch (error) { + dispatch(reviewActions.initializeReviewFailed(error)); + } +}; + +export const finishIssueAsync = (message: string): ThunkAction => async (dispatch, getState) => { + const state = getState(); + const { + auth: { user }, + annotation: { + player: { + frame: { number: frameNumber }, + }, + }, + review: { activeReview, newIssuePosition }, + } = state; + + try { + const issue = await activeReview.openIssue({ + frame: frameNumber, + position: newIssuePosition, + owner: user, + comment_set: [ + { + message, + author: user, + }, + ], + }); + await activeReview.toLocalStorage(); + dispatch(reviewActions.finishIssueSuccess(frameNumber, issue)); + } catch (error) { + dispatch(reviewActions.finishIssueFailed(error)); + } +}; + +export const commentIssueAsync = (id: number, message: string): ThunkAction => async (dispatch, getState) => { + const state = getState(); + const { + auth: { user }, + review: { frameIssues, activeReview }, + } = state; + + try { + dispatch(reviewActions.commentIssue(id)); + const [issue] = frameIssues.filter((_issue: any): boolean => _issue.id === id); + await issue.comment({ + message, + author: user, + }); + if (activeReview && activeReview.issues.includes(issue)) { + await activeReview.toLocalStorage(); + } + dispatch(reviewActions.commentIssueSuccess()); + } catch (error) { + dispatch(reviewActions.commentIssueFailed(error)); + } +}; + +export const resolveIssueAsync = (id: number): ThunkAction => async (dispatch, getState) => { + const state = getState(); + const { + auth: { user }, + review: { frameIssues, activeReview }, + } = state; + + try { + dispatch(reviewActions.resolveIssue(id)); + const [issue] = frameIssues.filter((_issue: any): boolean => _issue.id === id); + await issue.resolve(user); + if (activeReview && activeReview.issues.includes(issue)) { + await activeReview.toLocalStorage(); + } + + dispatch(reviewActions.resolveIssueSuccess()); + } catch (error) { + dispatch(reviewActions.resolveIssueFailed(error)); + } +}; + +export const reopenIssueAsync = (id: number): ThunkAction => async (dispatch, getState) => { + const state = getState(); + const { + auth: { user }, + review: { frameIssues, activeReview }, + } = state; + + try { + dispatch(reviewActions.reopenIssue(id)); + const [issue] = frameIssues.filter((_issue: any): boolean => _issue.id === id); + await issue.reopen(user); + if (activeReview && activeReview.issues.includes(issue)) { + await activeReview.toLocalStorage(); + } + + dispatch(reviewActions.reopenIssueSuccess()); + } catch (error) { + dispatch(reviewActions.reopenIssueFailed(error)); + } +}; + +export const submitReviewAsync = (review: any): ThunkAction => async (dispatch, getState) => { + const state = getState(); + const { + annotation: { + job: { instance: jobInstance }, + }, + } = state; + + try { + dispatch(reviewActions.submitReview(review.id)); + await review.submit(jobInstance.id); + + const [task] = await cvat.tasks.get({ id: jobInstance.task.id }); + dispatch(updateTaskSuccess(task, jobInstance.task.id)); + dispatch(reviewActions.submitReviewSuccess()); + } catch (error) { + dispatch(reviewActions.submitReviewFailed(error)); + } +}; diff --git a/cvat-ui/src/actions/settings-actions.ts b/cvat-ui/src/actions/settings-actions.ts index 9108b02a..981deae9 100644 --- a/cvat-ui/src/actions/settings-actions.ts +++ b/cvat-ui/src/actions/settings-actions.ts @@ -3,10 +3,7 @@ // SPDX-License-Identifier: MIT import { AnyAction } from 'redux'; -import { - GridColor, - ColorBy, -} from 'reducers/interfaces'; +import { GridColor, ColorBy } from 'reducers/interfaces'; export enum SettingsActionTypes { SWITCH_ROTATE_ALL = 'SWITCH_ROTATE_ALL', @@ -17,7 +14,7 @@ export enum SettingsActionTypes { CHANGE_SHAPES_OPACITY = 'CHANGE_SHAPES_OPACITY', CHANGE_SELECTED_SHAPES_OPACITY = 'CHANGE_SELECTED_SHAPES_OPACITY', CHANGE_SHAPES_COLOR_BY = 'CHANGE_SHAPES_COLOR_BY', - CHANGE_SHAPES_BLACK_BORDERS = 'CHANGE_SHAPES_BLACK_BORDERS', + CHANGE_SHAPES_OUTLINED_BORDERS = 'CHANGE_SHAPES_OUTLINED_BORDERS', CHANGE_SHAPES_SHOW_PROJECTIONS = 'CHANGE_SHAPES_SHOW_PROJECTIONS', CHANGE_SHOW_UNLABELED_REGIONS = 'CHANGE_SHOW_UNLABELED_REGIONS', CHANGE_FRAME_STEP = 'CHANGE_FRAME_STEP', @@ -63,11 +60,12 @@ export function changeShapesColorBy(colorBy: ColorBy): AnyAction { }; } -export function changeShapesBlackBorders(blackBorders: boolean): AnyAction { +export function changeShapesOutlinedBorders(outlined: boolean, color: string): AnyAction { return { - type: SettingsActionTypes.CHANGE_SHAPES_BLACK_BORDERS, + type: SettingsActionTypes.CHANGE_SHAPES_OUTLINED_BORDERS, payload: { - blackBorders, + outlined, + color, }, }; } diff --git a/cvat-ui/src/actions/share-actions.ts b/cvat-ui/src/actions/share-actions.ts index 51d9a053..b2947ad4 100644 --- a/cvat-ui/src/actions/share-actions.ts +++ b/cvat-ui/src/actions/share-actions.ts @@ -17,24 +17,17 @@ export enum ShareActionTypes { const shareActions = { loadShareData: () => createAction(ShareActionTypes.LOAD_SHARE_DATA), - loadShareDataSuccess: (values: ShareFileInfo[], directory: string) => ( + loadShareDataSuccess: (values: ShareFileInfo[], directory: string) => createAction(ShareActionTypes.LOAD_SHARE_DATA_SUCCESS, { values, directory, - }) - ), - loadShareDataFailed: (error: any) => ( - createAction(ShareActionTypes.LOAD_SHARE_DATA_FAILED, { error }) - ), + }), + loadShareDataFailed: (error: any) => createAction(ShareActionTypes.LOAD_SHARE_DATA_FAILED, { error }), }; export type ShareActions = ActionUnion; -export function loadShareDataAsync( - directory: string, - success: () => void, - failure: () => void, -): ThunkAction { +export function loadShareDataAsync(directory: string, success: () => void, failure: () => void): ThunkAction { return async (dispatch): Promise => { try { dispatch(shareActions.loadShareData()); diff --git a/cvat-ui/src/actions/shortcuts-actions.ts b/cvat-ui/src/actions/shortcuts-actions.ts index 86d83e6d..2d793cc6 100644 --- a/cvat-ui/src/actions/shortcuts-actions.ts +++ b/cvat-ui/src/actions/shortcuts-actions.ts @@ -1,3 +1,6 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT import { ActionUnion, createAction } from 'utils/redux'; export enum ShortcutsActionsTypes { diff --git a/cvat-ui/src/actions/tasks-actions.ts b/cvat-ui/src/actions/tasks-actions.ts index c61c12d7..bd0fd450 100644 --- a/cvat-ui/src/actions/tasks-actions.ts +++ b/cvat-ui/src/actions/tasks-actions.ts @@ -4,10 +4,7 @@ import { AnyAction, Dispatch, ActionCreator } from 'redux'; import { ThunkAction } from 'redux-thunk'; -import { - TasksQuery, - CombinedState, -} from 'reducers/interfaces'; +import { TasksQuery, CombinedState } from 'reducers/interfaces'; import { getCVATStore } from 'cvat-store'; import getCore from 'cvat-core-wrapper'; import { getInferenceStatusAsync } from './models-actions'; @@ -49,8 +46,7 @@ function getTasks(): AnyAction { return action; } -function getTasksSuccess(array: any[], previews: string[], - count: number, query: TasksQuery): AnyAction { +export function getTasksSuccess(array: any[], previews: string[], count: number, query: TasksQuery): AnyAction { const action = { type: TasksActionTypes.GET_TASKS_SUCCESS, payload: { @@ -76,8 +72,7 @@ function getTasksFailed(error: any, query: TasksQuery): AnyAction { return action; } -export function getTasksAsync(query: TasksQuery): -ThunkAction, {}, {}, AnyAction> { +export function getTasksAsync(query: TasksQuery): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { dispatch(getTasks()); @@ -98,26 +93,11 @@ ThunkAction, {}, {}, AnyAction> { } const array = Array.from(result); - const previews = []; - const promises = array - .map((task): string => (task as any).frames.preview()); + const promises = array.map((task): string => (task as any).frames.preview().catch(() => '')); dispatch(getInferenceStatusAsync()); - for (const promise of promises) { - try { - // a tricky moment - // await is okay in loop in this case, there aren't any performance bottleneck - // because all server requests have been already sent in parallel - - // eslint-disable-next-line no-await-in-loop - previews.push(await promise); - } catch (error) { - previews.push(''); - } - } - - dispatch(getTasksSuccess(array, previews, result.count, query)); + dispatch(getTasksSuccess(array, await Promise.all(promises), result.count, query)); }; } @@ -158,13 +138,12 @@ function dumpAnnotationFailed(task: any, dumper: any, error: any): AnyAction { return action; } -export function dumpAnnotationsAsync(task: any, dumper: any): -ThunkAction, {}, {}, AnyAction> { +export function dumpAnnotationsAsync(task: any, dumper: any): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { try { dispatch(dumpAnnotation(task, dumper)); const url = await task.annotations.dump(dumper); - const downloadAnchor = (window.document.getElementById('downloadAnchor') as HTMLAnchorElement); + const downloadAnchor = window.document.getElementById('downloadAnchor') as HTMLAnchorElement; downloadAnchor.href = url; downloadAnchor.click(); } catch (error) { @@ -211,8 +190,11 @@ function loadAnnotationsFailed(task: any, error: any): AnyAction { return action; } -export function loadAnnotationsAsync(task: any, loader: any, file: File): -ThunkAction, {}, {}, AnyAction> { +export function loadAnnotationsAsync( + task: any, + loader: any, + file: File, +): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { try { const store = getCVATStore(); @@ -268,14 +250,13 @@ function exportDatasetFailed(task: any, exporter: any, error: any): AnyAction { return action; } -export function exportDatasetAsync(task: any, exporter: any): -ThunkAction, {}, {}, AnyAction> { +export function exportDatasetAsync(task: any, exporter: any): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { dispatch(exportDataset(task, exporter)); try { const url = await task.annotations.exportDataset(exporter.name); - const downloadAnchor = (window.document.getElementById('downloadAnchor') as HTMLAnchorElement); + const downloadAnchor = window.document.getElementById('downloadAnchor') as HTMLAnchorElement; downloadAnchor.href = url; downloadAnchor.click(); } catch (error) { @@ -320,8 +301,7 @@ function deleteTaskFailed(taskID: number, error: any): AnyAction { return action; } -export function deleteTaskAsync(taskInstance: any): -ThunkAction, {}, {}, AnyAction> { +export function deleteTaskAsync(taskInstance: any): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { try { dispatch(deleteTask(taskInstance.id)); @@ -377,17 +357,19 @@ function createTaskUpdateStatus(status: string): AnyAction { return action; } -export function createTaskAsync(data: any): -ThunkAction, {}, {}, AnyAction> { +export function createTaskAsync(data: any): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { const description: any = { name: data.basic.name, labels: data.labels, - z_order: data.advanced.zOrder, image_quality: 70, use_zip_chunks: data.advanced.useZipChunks, + use_cache: data.advanced.useCache, }; + if (data.projectId) { + description.project_id = data.projectId; + } if (data.advanced.bugTracker) { description.bug_tracker = data.advanced.bugTracker; } @@ -412,6 +394,9 @@ ThunkAction, {}, {}, AnyAction> { if (data.advanced.dataChunkSize) { description.data_chunk_size = data.advanced.dataChunkSize; } + if (data.advanced.copyData) { + description.copy_data = data.advanced.copyData; + } const taskInstance = new cvat.classes.Task(description); taskInstance.clientFiles = data.files.local; @@ -419,9 +404,7 @@ ThunkAction, {}, {}, AnyAction> { taskInstance.remoteFiles = data.files.remote; if (data.advanced.repository) { - const [gitPlugin] = (await cvat.plugins.list()).filter( - (plugin: any): boolean => plugin.name === 'Git', - ); + const [gitPlugin] = (await cvat.plugins.list()).filter((plugin: any): boolean => plugin.name === 'Git'); if (gitPlugin) { gitPlugin.callbacks.onStatusChange = (status: string): void => { @@ -454,12 +437,10 @@ function updateTask(): AnyAction { return action; } -function updateTaskSuccess(task: any): AnyAction { +export function updateTaskSuccess(task: any, taskID: number): AnyAction { const action = { type: TasksActionTypes.UPDATE_TASK_SUCCESS, - payload: { - task, - }, + payload: { task, taskID }, }; return action; @@ -468,23 +449,24 @@ function updateTaskSuccess(task: any): AnyAction { function updateTaskFailed(error: any, task: any): AnyAction { const action = { type: TasksActionTypes.UPDATE_TASK_FAILED, - payload: { - error, - task, - }, + payload: { error, task }, }; return action; } -export function updateTaskAsync(taskInstance: any): -ThunkAction, {}, {}, AnyAction> { - return async (dispatch: ActionCreator): Promise => { +export function updateTaskAsync(taskInstance: any): ThunkAction, CombinedState, {}, AnyAction> { + return async (dispatch: ActionCreator, getState: () => CombinedState): Promise => { try { dispatch(updateTask()); + const currentUser = getState().auth.user; await taskInstance.save(); - const [task] = await cvat.tasks.get({ id: taskInstance.id }); - dispatch(updateTaskSuccess(task)); + const nextUser = getState().auth.user; + const userFetching = getState().auth.fetching; + if (!userFetching && nextUser && currentUser.username === nextUser.username) { + const [task] = await cvat.tasks.get({ id: taskInstance.id }); + dispatch(updateTaskSuccess(task, taskInstance.id)); + } } catch (error) { // try abort all changes let task = null; @@ -502,14 +484,13 @@ ThunkAction, {}, {}, AnyAction> { // a job is a part of a task, so for simplify we consider // updating the job as updating a task -export function updateJobAsync(jobInstance: any): -ThunkAction, {}, {}, AnyAction> { +export function updateJobAsync(jobInstance: any): ThunkAction, {}, {}, AnyAction> { return async (dispatch: ActionCreator): Promise => { try { dispatch(updateTask()); await jobInstance.save(); const [task] = await cvat.tasks.get({ id: jobInstance.task.id }); - dispatch(updateTaskSuccess(task)); + dispatch(updateTaskSuccess(task, jobInstance.task.id)); } catch (error) { // try abort all changes let task = null; diff --git a/cvat-ui/src/actions/useragreements-actions.ts b/cvat-ui/src/actions/useragreements-actions.ts index 95ec7003..e58dffe7 100644 --- a/cvat-ui/src/actions/useragreements-actions.ts +++ b/cvat-ui/src/actions/useragreements-actions.ts @@ -16,12 +16,10 @@ export enum UserAgreementsActionTypes { const userAgreementsActions = { getUserAgreements: () => createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS), - getUserAgreementsSuccess: (userAgreements: UserAgreement[]) => ( - createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_SUCCESS, userAgreements) - ), - getUserAgreementsFailed: (error: any) => ( - createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_FAILED, { error }) - ), + getUserAgreementsSuccess: (userAgreements: UserAgreement[]) => + createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_SUCCESS, userAgreements), + getUserAgreementsFailed: (error: any) => + createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_FAILED, { error }), }; export type UserAgreementsActions = ActionUnion; @@ -31,9 +29,7 @@ export const getUserAgreementsAsync = (): ThunkAction => async (dispatch): Promi try { const userAgreements = await core.server.userAgreements(); - dispatch( - userAgreementsActions.getUserAgreementsSuccess(userAgreements), - ); + dispatch(userAgreementsActions.getUserAgreementsSuccess(userAgreements)); } catch (error) { dispatch(userAgreementsActions.getUserAgreementsFailed(error)); } diff --git a/cvat-ui/src/actions/users-actions.ts b/cvat-ui/src/actions/users-actions.ts deleted file mode 100644 index 53756739..00000000 --- a/cvat-ui/src/actions/users-actions.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// -// SPDX-License-Identifier: MIT - -import { ActionUnion, createAction, ThunkAction } from 'utils/redux'; -import getCore from 'cvat-core-wrapper'; - -const core = getCore(); - -export enum UsersActionTypes { - GET_USERS = 'GET_USERS', - GET_USERS_SUCCESS = 'GET_USERS_SUCCESS', - GET_USERS_FAILED = 'GET_USERS_FAILED', -} - -const usersActions = { - getUsers: () => createAction(UsersActionTypes.GET_USERS), - getUsersSuccess: (users: any[]) => createAction(UsersActionTypes.GET_USERS_SUCCESS, { users }), - getUsersFailed: (error: any) => createAction(UsersActionTypes.GET_USERS_FAILED, { error }), -}; - -export type UsersActions = ActionUnion; - -export function getUsersAsync(): ThunkAction { - return async (dispatch): Promise => { - dispatch(usersActions.getUsers()); - - try { - const users = await core.users.get(); - const wrappedUsers = users - .map((userData: any): any => new core.classes.User(userData)); - dispatch(usersActions.getUsersSuccess(wrappedUsers)); - } catch (error) { - dispatch(usersActions.getUsersFailed(error)); - } - }; -} diff --git a/cvat-ui/src/assets/ai-tools-icon.svg b/cvat-ui/src/assets/ai-tools-icon.svg new file mode 100644 index 00000000..c8b4f304 --- /dev/null +++ b/cvat-ui/src/assets/ai-tools-icon.svg @@ -0,0 +1,18 @@ + + + + + diff --git a/cvat-ui/src/assets/next-empty-icon.svg b/cvat-ui/src/assets/next-empty-icon.svg new file mode 100644 index 00000000..4beef76a --- /dev/null +++ b/cvat-ui/src/assets/next-empty-icon.svg @@ -0,0 +1,3 @@ + diff --git a/cvat-ui/src/assets/next-filtered-icon.svg b/cvat-ui/src/assets/next-filtered-icon.svg new file mode 100644 index 00000000..2fcbaf5b --- /dev/null +++ b/cvat-ui/src/assets/next-filtered-icon.svg @@ -0,0 +1,3 @@ + diff --git a/cvat-ui/src/assets/previous-empty-icon.svg b/cvat-ui/src/assets/previous-empty-icon.svg new file mode 100644 index 00000000..72eb7298 --- /dev/null +++ b/cvat-ui/src/assets/previous-empty-icon.svg @@ -0,0 +1,3 @@ + diff --git a/cvat-ui/src/assets/previous-filtered-icon.svg b/cvat-ui/src/assets/previous-filtered-icon.svg new file mode 100644 index 00000000..2c131896 --- /dev/null +++ b/cvat-ui/src/assets/previous-filtered-icon.svg @@ -0,0 +1,3 @@ + diff --git a/cvat-ui/src/base.scss b/cvat-ui/src/base.scss index 75b561ca..9ef0e0ac 100644 --- a/cvat-ui/src/base.scss +++ b/cvat-ui/src/base.scss @@ -2,6 +2,15 @@ // // SPDX-License-Identifier: MIT +$grid-unit-size: 8px; + +$header-height: $grid-unit-size * 7; + +$layout-sm-grid-size: $grid-unit-size / 2; +$layout-lg-grid-size: $grid-unit-size * 2; +$layout-sm-grid-color: rgba(0, 0, 0, 0.15); +$layout-lg-grid-color: rgba(0, 0, 0, 0.15); + $header-color: #d8d8d8; $text-color: #303030; $hover-menu-color: rgba(24, 144, 255, 0.05); @@ -9,7 +18,7 @@ $completed-progress-color: #61c200; $inprogress-progress-color: #1890ff; $pending-progress-color: #c1c1c1; $border-color-1: #c3c3c3; -$border-color-2: #d9d9d9; +$border-color-2: rgb(240, 240, 240); $border-color-3: #242424; $border-color-hover: #40a9ff; $background-color-1: white; @@ -18,11 +27,16 @@ $transparent-color: rgba(0, 0, 0, 0); $player-slider-color: #979797; $player-buttons-color: #242424; $danger-icon-color: #ff4136; +$ok-icon-color: #61c200; $info-icon-color: #0074d9; $objects-bar-tabs-color: #bebebe; $objects-bar-icons-color: #242424; // #6e6e6e $active-label-background-color: #d8ecff; -$object-item-border-color: #000; +$object-item-border-color: rgba(0, 0, 0, 0.7); $slider-color: #1890ff; -$monospaced-fonts-stack: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace; +$box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), + 0 9px 28px 8px rgba(0, 0, 0, 0.05); + +$monospaced-fonts-stack: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, + Courier New, monospace; diff --git a/cvat-ui/src/components/actions-menu/actions-menu.tsx b/cvat-ui/src/components/actions-menu/actions-menu.tsx index d51560e2..723bf68e 100644 --- a/cvat-ui/src/components/actions-menu/actions-menu.tsx +++ b/cvat-ui/src/components/actions-menu/actions-menu.tsx @@ -4,9 +4,10 @@ import './styles.scss'; import React from 'react'; -import Menu, { ClickParam } from 'antd/lib/menu'; +import Menu from 'antd/lib/menu'; import Modal from 'antd/lib/modal'; - +// eslint-disable-next-line import/no-extraneous-dependencies +import { MenuInfo } from 'rc-menu/lib/interface'; import DumpSubmenu from './dump-submenu'; import LoadSubmenu from './load-submenu'; import ExportSubmenu from './export-submenu'; @@ -22,7 +23,7 @@ interface Props { exportActivities: string[] | null; inferenceIsActive: boolean; - onClickMenu: (params: ClickParam, file?: File) => void; + onClickMenu: (params: MenuInfo, file?: File) => void; } export enum Actions { @@ -48,8 +49,8 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { loadActivity, } = props; - let latestParams: ClickParam | null = null; - function onClickMenuWrapper(params: ClickParam | null, file?: File): void { + let latestParams: MenuInfo | null = null; + function onClickMenuWrapper(params: MenuInfo | null, file?: File): void { const copyParams = params || latestParams; if (!copyParams) { return; @@ -67,7 +68,8 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { onClickMenu(copyParams, file); }, okButtonProps: { - type: 'danger', + type: 'primary', + danger: true, }, okText: 'Update', }); @@ -83,7 +85,8 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { onClickMenu(copyParams); }, okButtonProps: { - type: 'danger', + type: 'primary', + danger: true, }, okText: 'Delete', }); @@ -93,41 +96,28 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { } return ( - - { - DumpSubmenu({ - taskMode, - dumpers, - dumpActivities, - menuKey: Actions.DUMP_TASK_ANNO, - }) - } - { - LoadSubmenu({ - loaders, - loadActivity, - onFileUpload: (file: File): void => { - onClickMenuWrapper(null, file); - }, - menuKey: Actions.LOAD_TASK_ANNO, - }) - } - { - ExportSubmenu({ - exporters: dumpers, - exportActivities, - menuKey: Actions.EXPORT_TASK_DATASET, - }) - } + + {DumpSubmenu({ + taskMode, + dumpers, + dumpActivities, + menuKey: Actions.DUMP_TASK_ANNO, + })} + {LoadSubmenu({ + loaders, + loadActivity, + onFileUpload: (file: File): void => { + onClickMenuWrapper(null, file); + }, + menuKey: Actions.LOAD_TASK_ANNO, + })} + {ExportSubmenu({ + exporters: dumpers, + exportActivities, + menuKey: Actions.EXPORT_TASK_DATASET, + })} {!!bugTracker && Open bug tracker} - + Automatic annotation
    diff --git a/cvat-ui/src/components/actions-menu/dump-submenu.tsx b/cvat-ui/src/components/actions-menu/dump-submenu.tsx index f88cc62e..5f71273f 100644 --- a/cvat-ui/src/components/actions-menu/dump-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/dump-submenu.tsx @@ -4,12 +4,14 @@ import React from 'react'; import Menu from 'antd/lib/menu'; -import Icon from 'antd/lib/icon'; +import { DownloadOutlined, LoadingOutlined } from '@ant-design/icons'; import Text from 'antd/lib/typography/Text'; function isDefaultFormat(dumperName: string, taskMode: string): boolean { - return (dumperName === 'CVAT for video 1.1' && taskMode === 'interpolation') - || (dumperName === 'CVAT for images 1.1' && taskMode === 'annotation'); + return ( + (dumperName === 'CVAT for video 1.1' && taskMode === 'interpolation') || + (dumperName === 'CVAT for images 1.1' && taskMode === 'annotation') + ); } interface Props { @@ -20,35 +22,28 @@ interface Props { } export default function DumpSubmenu(props: Props): JSX.Element { - const { - taskMode, - menuKey, - dumpers, - dumpActivities, - } = props; + const { taskMode, menuKey, dumpers, dumpActivities } = props; return ( - { - dumpers - .sort((a: any, b: any) => a.name.localeCompare(b.name)) - .map((dumper: any): JSX.Element => { + {dumpers + .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .map( + (dumper: any): JSX.Element => { const pending = (dumpActivities || []).includes(dumper.name); const disabled = !dumper.enabled || pending; const isDefault = isDefaultFormat(dumper.name, taskMode); return ( - - - {dumper.name} - {pending && } + + + + {dumper.name} + + {pending && } ); - }) - } + }, + )} ); } diff --git a/cvat-ui/src/components/actions-menu/export-submenu.tsx b/cvat-ui/src/components/actions-menu/export-submenu.tsx index 8f6bb4f3..28affd5f 100644 --- a/cvat-ui/src/components/actions-menu/export-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/export-submenu.tsx @@ -4,8 +4,8 @@ import React from 'react'; import Menu from 'antd/lib/menu'; -import Icon from 'antd/lib/icon'; import Text from 'antd/lib/typography/Text'; +import { ExportOutlined, LoadingOutlined } from '@ant-design/icons'; interface Props { menuKey: string; @@ -14,18 +14,14 @@ interface Props { } export default function ExportSubmenu(props: Props): JSX.Element { - const { - menuKey, - exporters, - exportActivities, - } = props; + const { menuKey, exporters, exportActivities } = props; return ( - { - exporters - .sort((a: any, b: any) => a.name.localeCompare(b.name)) - .map((exporter: any): JSX.Element => { + {exporters + .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .map( + (exporter: any): JSX.Element => { const pending = (exportActivities || []).includes(exporter.name); const disabled = !exporter.enabled || pending; return ( @@ -34,13 +30,13 @@ export default function ExportSubmenu(props: Props): JSX.Element { disabled={disabled} className='cvat-menu-export-submenu-item' > - + {exporter.name} - {pending && } + {pending && }
    ); - }) - } + }, + )} ); } diff --git a/cvat-ui/src/components/actions-menu/load-submenu.tsx b/cvat-ui/src/components/actions-menu/load-submenu.tsx index c167a01b..53bbe3c7 100644 --- a/cvat-ui/src/components/actions-menu/load-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/load-submenu.tsx @@ -4,10 +4,10 @@ import React from 'react'; import Menu from 'antd/lib/menu'; -import Icon from 'antd/lib/icon'; import Upload from 'antd/lib/upload'; import Button from 'antd/lib/button'; import Text from 'antd/lib/typography/Text'; +import { UploadOutlined, LoadingOutlined } from '@ant-design/icons'; interface Props { menuKey: string; @@ -18,18 +18,15 @@ interface Props { export default function LoadSubmenu(props: Props): JSX.Element { const { - menuKey, - loaders, - loadActivity, - onFileUpload, + menuKey, loaders, loadActivity, onFileUpload, } = props; return ( - { - loaders - .sort((a: any, b: any) => a.name.localeCompare(b.name)) - .map((loader: any): JSX.Element => { + {loaders + .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .map( + (loader: any): JSX.Element => { const accept = loader.format .split(',') .map((x: string) => `.${x.trimStart()}`) @@ -37,11 +34,7 @@ export default function LoadSubmenu(props: Props): JSX.Element { const pending = loadActivity === loader.name; const disabled = !loader.enabled || !!loadActivity; return ( - + - ); - }) - } + }, + )} ); } diff --git a/cvat-ui/src/components/actions-menu/styles.scss b/cvat-ui/src/components/actions-menu/styles.scss index b2fc8ded..ccb00306 100644 --- a/cvat-ui/src/components/actions-menu/styles.scss +++ b/cvat-ui/src/components/actions-menu/styles.scss @@ -5,7 +5,7 @@ @import '../../base.scss'; .ant-menu.cvat-actions-menu { - box-shadow: 0 0 17px rgba(0, 0, 0, 0.2); + box-shadow: $box-shadow-base; > li:hover { background-color: $hover-menu-color; @@ -20,7 +20,7 @@ .cvat-menu-load-submenu-item, .cvat-menu-dump-submenu-item, .cvat-menu-export-submenu-item { - > i { + > span[role='img'] { color: $info-icon-color; } diff --git a/cvat-ui/src/components/annotation-page/annotation-page.tsx b/cvat-ui/src/components/annotation-page/annotation-page.tsx index d98d4284..062f83b6 100644 --- a/cvat-ui/src/components/annotation-page/annotation-page.tsx +++ b/cvat-ui/src/components/annotation-page/annotation-page.tsx @@ -12,9 +12,12 @@ import Result from 'antd/lib/result'; import { Workspace } from 'reducers/interfaces'; import AnnotationTopBarContainer from 'containers/annotation-page/top-bar/top-bar'; import StatisticsModalContainer from 'containers/annotation-page/top-bar/statistics-modal'; -import StandardWorkspaceComponent from './standard-workspace/standard-workspace'; -import AttributeAnnotationWorkspace from './attribute-annotation-workspace/attribute-annotation-workspace'; -import TagAnnotationWorkspace from './tag-annotation-workspace/tag-annotation-workspace'; +import StandardWorkspaceComponent from 'components/annotation-page/standard-workspace/standard-workspace'; +import AttributeAnnotationWorkspace from 'components/annotation-page/attribute-annotation-workspace/attribute-annotation-workspace'; +import TagAnnotationWorkspace from 'components/annotation-page/tag-annotation-workspace/tag-annotation-workspace'; +import ReviewAnnotationsWorkspace from 'components/annotation-page/review-workspace/review-workspace'; +import SubmitAnnotationsModal from 'components/annotation-page/request-review-modal'; +import SubmitReviewModal from 'components/annotation-page/review/submit-review-modal'; interface Props { job: any | null | undefined; @@ -27,12 +30,7 @@ interface Props { export default function AnnotationPageComponent(props: Props): JSX.Element { const { - job, - fetching, - getJob, - closeJob, - saveLogs, - workspace, + job, fetching, getJob, closeJob, saveLogs, workspace, } = props; const history = useHistory(); @@ -55,15 +53,17 @@ export default function AnnotationPageComponent(props: Props): JSX.Element { }; }, []); - if (job === null) { - if (!fetching) { + useEffect(() => { + if (job === null && !fetching) { getJob(); } + }, [job, fetching]); + if (job === null) { return ; } - if (typeof (job) === 'undefined') { + if (typeof job === 'undefined') { return ( - { workspace === Workspace.STANDARD && ( + {workspace === Workspace.STANDARD && ( )} - { workspace === Workspace.ATTRIBUTE_ANNOTATION && ( + {workspace === Workspace.ATTRIBUTE_ANNOTATION && ( )} - { workspace === Workspace.TAG_ANNOTATION && ( + {workspace === Workspace.TAG_ANNOTATION && ( )} + {workspace === Workspace.REVIEW_WORKSPACE && ( + + + + )} + + ); } diff --git a/cvat-ui/src/components/annotation-page/annotations-filters-input.tsx b/cvat-ui/src/components/annotation-page/annotations-filters-input.tsx index f11893db..2bd2664c 100644 --- a/cvat-ui/src/components/annotation-page/annotations-filters-input.tsx +++ b/cvat-ui/src/components/annotation-page/annotations-filters-input.tsx @@ -10,7 +10,7 @@ import Text from 'antd/lib/typography/Text'; import Paragraph from 'antd/lib/typography/Paragraph'; import Tooltip from 'antd/lib/tooltip'; import Modal from 'antd/lib/modal'; -import Icon from 'antd/lib/icon'; +import { FilterOutlined } from '@ant-design/icons'; import { changeAnnotationsFilters as changeAnnotationsFiltersAction, @@ -32,14 +32,9 @@ interface DispatchToProps { function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { - annotations: { - filters: annotationsFilters, - filtersHistory: annotationsFiltersHistory, - }, - }, - shortcuts: { - normalizedKeyMap, + annotations: { filters: annotationsFilters, filtersHistory: annotationsFiltersHistory }, }, + shortcuts: { normalizedKeyMap }, } = state; return { @@ -53,13 +48,12 @@ function mapStateToProps(state: CombinedState): StateToProps { function mapDispatchToProps(dispatch: any): DispatchToProps { return { changeAnnotationsFilters(value: SelectValue) { - if (typeof (value) === 'string') { + if (typeof value === 'string') { dispatch(changeAnnotationsFiltersAction([value])); dispatch(fetchAnnotationsAsync()); - } else if (Array.isArray(value) - && value.every((element: string | number | LabeledValue): boolean => ( - typeof (element) === 'string' - )) + } else if ( + Array.isArray(value) && + value.every((element: string | number | LabeledValue): boolean => typeof element === 'string') ) { dispatch(changeAnnotationsFiltersAction(value as string[])); dispatch(fetchAnnotationsAsync()); @@ -68,40 +62,32 @@ function mapDispatchToProps(dispatch: any): DispatchToProps { }; } -function filtersHelpModalContent( - searchForwardShortcut: string, - searchBackwardShortcut: string, -): JSX.Element { +function filtersHelpModalContent(searchForwardShortcut: string, searchBackwardShortcut: string): JSX.Element { return ( <> General - You can use filters to display only subset of objects on a frame - or to search objects that satisfy the filters using hotkeys - - {` ${searchForwardShortcut} `} - + You can use filters to display only subset of objects on a frame or to search objects that satisfy the + filters using hotkeys + {` ${searchForwardShortcut} `} and - - {` ${searchBackwardShortcut} `} - + {` ${searchBackwardShortcut} `} Supported properties: width, height, label, serverID, clientID, type, shape, occluded
    Supported operators: - ==, !=, >, >=, <, <=, (), & and | + ==, !=, >, >=, <, <=, (), & and |
    - If you have double quotes in your query string, - please escape them using back slash: \" (see the latest example) + If you have double quotes in your query string, please escape them using back slash: \" (see + the latest example)
    - All properties and values are case-sensitive. - CVAT uses json queries to perform search. + All properties and values are case-sensitive. CVAT uses json queries to perform search.
    Examples @@ -112,13 +98,12 @@ function filtersHelpModalContent(
  • attr["Attribute 1"] == attr["Attribute 2"]
  • clientID == 50
  • - (label=="car" & attr["parked"]==true) - | (label=="pedestrian" & width > 150) + (label=="car" & attr["parked"]==true) | (label=="pedestrian" + & width > 150)
  • - (( label==["car \"mazda\""]) - & (attr["sunglasses"]==true - | (width > 150 | height > 150 & (clientID == serverID))))) + (( label==["car \"mazda\""]) & (attr["sunglasses"]==true | + (width > 150 | height > 150 & (clientID == serverID)))))
  • @@ -148,17 +133,13 @@ function AnnotationsFiltersInput(props: StateToProps & DispatchToProps): JSX.Ele underCursor ? ( <> - { e.stopPropagation(); Modal.info({ width: 700, title: 'How to use filters?', - content: filtersHelpModalContent( - searchForwardShortcut, - searchBackwardShortcut, - ), + content: filtersHelpModalContent(searchForwardShortcut, searchBackwardShortcut), }); }} /> @@ -166,7 +147,7 @@ function AnnotationsFiltersInput(props: StateToProps & DispatchToProps): JSX.Ele ) : ( <> - + Annotations filters ) @@ -175,15 +156,15 @@ function AnnotationsFiltersInput(props: StateToProps & DispatchToProps): JSX.Ele onMouseEnter={() => setUnderCursor(true)} onMouseLeave={() => setUnderCursor(false)} > - {annotationsFiltersHistory.map((element: string): JSX.Element => ( - {element} - ))} + {annotationsFiltersHistory.map( + (element: string): JSX.Element => ( + + {element} + + ), + )} ); } - -export default connect( - mapStateToProps, - mapDispatchToProps, -)(AnnotationsFiltersInput); +export default connect(mapStateToProps, mapDispatchToProps)(AnnotationsFiltersInput); diff --git a/cvat-ui/src/components/annotation-page/appearance-block.tsx b/cvat-ui/src/components/annotation-page/appearance-block.tsx index 06a060fa..8ea48cf3 100644 --- a/cvat-ui/src/components/annotation-page/appearance-block.tsx +++ b/cvat-ui/src/components/annotation-page/appearance-block.tsx @@ -7,10 +7,12 @@ import { AnyAction } from 'redux'; import { connect } from 'react-redux'; import Text from 'antd/lib/typography/Text'; import Radio, { RadioChangeEvent } from 'antd/lib/radio'; -import Slider, { SliderValue } from 'antd/lib/slider'; +import Slider from 'antd/lib/slider'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Collapse from 'antd/lib/collapse'; +import ColorPicker from 'components/annotation-page/standard-workspace/objects-side-bar/color-picker'; +import { ColorizeIcon } from 'icons'; import { ColorBy, CombinedState } from 'reducers/interfaces'; import { collapseAppearance as collapseAppearanceAction, @@ -20,17 +22,19 @@ import { changeShapesColorBy as changeShapesColorByAction, changeShapesOpacity as changeShapesOpacityAction, changeSelectedShapesOpacity as changeSelectedShapesOpacityAction, - changeShapesBlackBorders as changeShapesBlackBordersAction, + changeShapesOutlinedBorders as changeShapesOutlinedBordersAction, changeShowBitmap as changeShowBitmapAction, changeShowProjections as changeShowProjectionsAction, } from 'actions/settings-actions'; +import Button from 'antd/lib/button'; interface StateToProps { appearanceCollapsed: boolean; colorBy: ColorBy; opacity: number; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; } @@ -38,9 +42,9 @@ interface StateToProps { interface DispatchToProps { collapseAppearance(): void; changeShapesColorBy(event: RadioChangeEvent): void; - changeShapesOpacity(event: SliderValue): void; - changeSelectedShapesOpacity(event: SliderValue): void; - changeShapesBlackBorders(event: CheckboxChangeEvent): void; + changeShapesOpacity(value: number): void; + changeSelectedShapesOpacity(value: number): void; + changeShapesOutlinedBorders(outlined: boolean, color: string): void; changeShowBitmap(event: CheckboxChangeEvent): void; changeShowProjections(event: CheckboxChangeEvent): void; } @@ -48,9 +52,7 @@ interface DispatchToProps { export function computeHeight(): number { const [sidebar] = window.document.getElementsByClassName('cvat-objects-sidebar'); const [appearance] = window.document.getElementsByClassName('cvat-objects-appearance-collapse'); - const [tabs] = Array.from( - window.document.querySelectorAll('.cvat-objects-sidebar-tabs > .ant-tabs-card-bar'), - ); + const [tabs] = Array.from(window.document.querySelectorAll('.cvat-objects-sidebar-tabs > .ant-tabs-nav')); if (sidebar && appearance && tabs) { const maxHeight = sidebar ? sidebar.clientHeight : 0; @@ -64,17 +66,10 @@ export function computeHeight(): number { function mapStateToProps(state: CombinedState): StateToProps { const { - annotation: { - appearanceCollapsed, - }, + annotation: { appearanceCollapsed }, settings: { shapes: { - colorBy, - opacity, - selectedOpacity, - blackBorders, - showBitmap, - showProjections, + colorBy, opacity, selectedOpacity, outlined, outlineColor, showBitmap, showProjections, }, }, } = state; @@ -84,19 +79,18 @@ function mapStateToProps(state: CombinedState): StateToProps { colorBy, opacity, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, }; } - function mapDispatchToProps(dispatch: Dispatch): DispatchToProps { return { collapseAppearance(): void { dispatch(collapseAppearanceAction()); - const [collapser] = window.document - .getElementsByClassName('cvat-objects-appearance-collapse'); + const [collapser] = window.document.getElementsByClassName('cvat-objects-appearance-collapse'); if (collapser) { const listener = (event: Event): void => { @@ -113,14 +107,14 @@ function mapDispatchToProps(dispatch: Dispatch): DispatchToProps { changeShapesColorBy(event: RadioChangeEvent): void { dispatch(changeShapesColorByAction(event.target.value)); }, - changeShapesOpacity(value: SliderValue): void { - dispatch(changeShapesOpacityAction(value as number)); + changeShapesOpacity(value: number): void { + dispatch(changeShapesOpacityAction(value)); }, - changeSelectedShapesOpacity(value: SliderValue): void { - dispatch(changeSelectedShapesOpacityAction(value as number)); + changeSelectedShapesOpacity(value: number): void { + dispatch(changeSelectedShapesOpacityAction(value)); }, - changeShapesBlackBorders(event: CheckboxChangeEvent): void { - dispatch(changeShapesBlackBordersAction(event.target.checked)); + changeShapesOutlinedBorders(outlined: boolean, color: string): void { + dispatch(changeShapesOutlinedBordersAction(outlined, color)); }, changeShowBitmap(event: CheckboxChangeEvent): void { dispatch(changeShowBitmapAction(event.target.checked)); @@ -139,14 +133,15 @@ function AppearanceBlock(props: Props): JSX.Element { colorBy, opacity, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, collapseAppearance, changeShapesColorBy, changeShapesOpacity, changeSelectedShapesOpacity, - changeShapesBlackBorders, + changeShapesOutlinedBorders, changeShowBitmap, changeShowProjections, } = props; @@ -157,21 +152,21 @@ function AppearanceBlock(props: Props): JSX.Element { activeKey={appearanceCollapsed ? [] : ['appearance']} className='cvat-objects-appearance-collapse' > - Appearance - } - key='appearance' - > + Appearance} key='appearance'>
    Color by - + {ColorBy.LABEL} {ColorBy.INSTANCE} {ColorBy.GROUP} Opacity Selected opacity { + changeShapesOutlinedBorders(event.target.checked, outlineColor); + }} + checked={outlined} > - Black borders + Outlined borders + changeShapesOutlinedBorders(outlined, color)} + value={outlineColor} + placement='top' + resetVisible={false} + > + + Show bitmap @@ -208,7 +219,4 @@ function AppearanceBlock(props: Props): JSX.Element { ); } -export default connect( - mapStateToProps, - mapDispatchToProps, -)(React.memo(AppearanceBlock)); +export default connect(mapStateToProps, mapDispatchToProps)(React.memo(AppearanceBlock)); diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx index 71170227..10f0b596 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx @@ -9,7 +9,7 @@ import Layout, { SiderProps } from 'antd/lib/layout'; import { SelectValue } from 'antd/lib/select'; import { Row, Col } from 'antd/lib/grid'; import Text from 'antd/lib/typography/Text'; -import Icon from 'antd/lib/icon'; +import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; import { ThunkDispatch } from 'utils/redux'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -29,7 +29,6 @@ import AttributeSwitcher from './attribute-switcher'; import ObjectBasicsEditor from './object-basics-edtior'; import AttributeEditor from './attribute-editor'; - interface StateToProps { activatedStateID: number | null; activatedAttributeID: number | null; @@ -60,23 +59,12 @@ function mapStateToProps(state: CombinedState): StateToProps { activatedStateID, activatedAttributeID, states, - zLayer: { - cur, - }, - }, - job: { - instance: jobInstance, - labels, - }, - canvas: { - instance: canvasInstance, - ready: canvasIsReady, + zLayer: { cur }, }, + job: { instance: jobInstance, labels }, + canvas: { instance: canvasInstance, ready: canvasIsReady }, }, - shortcuts: { - keyMap, - normalizedKeyMap, - }, + shortcuts: { keyMap, normalizedKeyMap }, } = state; return { @@ -124,9 +112,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. curZLayer, } = props; - const filteredStates = states.filter((state) => !state.outside - && !state.hidden - && state.zOrder <= curZLayer); + const filteredStates = states.filter((state) => !state.outside && !state.hidden && state.zOrder <= curZLayer); const [labelAttrMap, setLabelAttrMap] = useState( labels.reduce((acc, label): LabelAttrMap => { acc[label.id] = label.attributes.length ? label.attributes[0] : null; @@ -137,13 +123,18 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const collapse = (): void => { - const [collapser] = window.document - .getElementsByClassName('attribute-annotation-sidebar'); + const [collapser] = window.document.getElementsByClassName('attribute-annotation-sidebar'); - if (collapser) { - collapser.addEventListener('transitionend', () => { + const listener = (event: TransitionEvent): void => { + if (event.target && event.propertyName === 'width' && event.target === collapser) { canvasInstance.fitCanvas(); - }, { once: true }); + canvasInstance.fit(); + (collapser as HTMLElement).removeEventListener('transitionend', listener as any); + } + }; + + if (collapser) { + (collapser as HTMLElement).addEventListener('transitionend', listener as any); } setSidebarCollapsed(!sidebarCollapsed); @@ -151,12 +142,10 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. const indexes = filteredStates.map((state) => state.clientID); const activatedIndex = indexes.indexOf(activatedStateID); - const activeObjectState = activatedStateID === null || activatedIndex === -1 - ? null : filteredStates[activatedIndex]; + const activeObjectState = + activatedStateID === null || activatedIndex === -1 ? null : filteredStates[activatedIndex]; - const activeAttribute = activeObjectState - ? labelAttrMap[activeObjectState.label.id] - : null; + const activeAttribute = activeObjectState ? labelAttrMap[activeObjectState.label.id] : null; if (canvasIsReady) { if (activeObjectState) { @@ -275,8 +264,8 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. NEXT_KEY_FRAME: (event: KeyboardEvent | undefined) => { preventDefault(event); if (activeObjectState && activeObjectState.objectType === ObjectType.TRACK) { - const frame = typeof (activeObjectState.keyframes.next) === 'number' - ? activeObjectState.keyframes.next : null; + const frame = + typeof activeObjectState.keyframes.next === 'number' ? activeObjectState.keyframes.next : null; if (frame !== null && canvasInstance.isAbleToChangeFrame()) { changeFrame(frame); } @@ -285,8 +274,8 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. PREV_KEY_FRAME: (event: KeyboardEvent | undefined) => { preventDefault(event); if (activeObjectState && activeObjectState.objectType === ObjectType.TRACK) { - const frame = typeof (activeObjectState.keyframes.prev) === 'number' - ? activeObjectState.keyframes.prev : null; + const frame = + typeof activeObjectState.keyframes.prev === 'number' ? activeObjectState.keyframes.prev : null; if (frame !== null && canvasInstance.isAbleToChangeFrame()) { changeFrame(frame); } @@ -304,12 +293,11 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. ant-layout-sider-zero-width-trigger-left`} onClick={collapse} > - {sidebarCollapsed ? - : } + {sidebarCollapsed ? : } - - + + @@ -327,58 +315,51 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. labels={labels} changeLabel={(value: SelectValue): void => { const labelName = value as string; - const [newLabel] = labels - .filter((_label): boolean => _label.name === labelName); + const [newLabel] = labels.filter((_label): boolean => _label.name === labelName); activeObjectState.label = newLabel; updateAnnotations([activeObjectState]); }} /> - { - activeAttribute - ? ( - <> - - { - const { attributes } = activeObjectState; - jobInstance.logger.log( - LogType.changeAttribute, { - id: activeAttribute.id, - object_id: activeObjectState.clientID, - value, - }, - ); - attributes[activeAttribute.id] = value; - activeObjectState.attributes = attributes; - updateAnnotations([activeObjectState]); - }} - /> - - - ) : ( -
    - No attributes found -
    - ) - } - - { !sidebarCollapsed && } + {activeAttribute ? ( + <> + + { + const { attributes } = activeObjectState; + jobInstance.logger.log(LogType.changeAttribute, { + id: activeAttribute.id, + object_id: activeObjectState.clientID, + value, + }); + attributes[activeAttribute.id] = value; + activeObjectState.attributes = attributes; + updateAnnotations([activeObjectState]); + }} + /> + + ) : ( +
    + No attributes found +
    + )} + + {!sidebarCollapsed && } ); } @@ -392,11 +373,10 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. ant-layout-sider-zero-width-trigger-left`} onClick={collapse} > - {sidebarCollapsed ? - : } + {sidebarCollapsed ? : } - - + + @@ -407,8 +387,4 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. ); } - -export default connect( - mapStateToProps, - mapDispatchToProps, -)(AttributeAnnotationSidebar); +export default connect(mapStateToProps, mapDispatchToProps)(AttributeAnnotationSidebar); diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx index 2f0b4c00..808cee83 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx @@ -23,12 +23,7 @@ interface InputElementParameters { function renderInputElement(parameters: InputElementParameters): JSX.Element { const { - inputType, - attrID, - clientID, - values, - currentValue, - onChange, + inputType, attrID, clientID, values, currentValue, onChange, } = parameters; const renderCheckbox = (): JSX.Element => ( @@ -36,9 +31,7 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element { Checkbox:
    ( - onChange(event.target.checked ? 'true' : 'false') - )} + onChange={(event: CheckboxChangeEvent): void => onChange(event.target.checked ? 'true' : 'false')} checked={currentValue === 'true'} />
    @@ -52,16 +45,15 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element {
    @@ -71,28 +63,21 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element { <> Values:
    - ( - onChange(event.target.value) + onChange(event.target.value)}> + {values.map( + (value: string): JSX.Element => ( + + {value === consts.UNDEFINED_ATTRIBUTE_VALUE ? consts.NO_BREAK_SPACE : value} + + ), )} - > - {values.map((value: string): JSX.Element => ( - - {value === consts.UNDEFINED_ATTRIBUTE_VALUE - ? consts.NO_BREAK_SPACE : value} - - ))}
    ); const handleKeydown = (event: React.KeyboardEvent): void => { - if (['ArrowDown', 'ArrowUp', 'ArrowLeft', - 'ArrowRight', 'Tab', 'Shift', 'Control'] - .includes(event.key) - ) { + if (['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Tab', 'Shift', 'Control'].includes(event.key)) { event.preventDefault(); const copyEvent = new KeyboardEvent('keydown', event); window.document.dispatchEvent(copyEvent); @@ -137,11 +122,7 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element { element = renderText(); } - return ( -
    - {element} -
    - ); + return
    {element}
    ; } interface ListParameters { @@ -203,8 +184,7 @@ function renderList(parameters: ListParameters): JSX.Element | null { [key: string]: (keyEvent?: KeyboardEvent) => void; } = {}; - const filteredValues = values - .filter((value: string): boolean => value !== consts.UNDEFINED_ATTRIBUTE_VALUE); + const filteredValues = values.filter((value: string): boolean => value !== consts.UNDEFINED_ATTRIBUTE_VALUE); filteredValues.slice(0, 10).forEach((value: string, index: number): void => { const key = `SET_${index}_VALUE`; keyMap[key] = { @@ -226,12 +206,14 @@ function renderList(parameters: ListParameters): JSX.Element | null { return (
    - {filteredValues.map((value: string, index: number): JSX.Element => ( -
    - {`${index}:`} - {` ${value}`} -
    - ))} + {filteredValues.map( + (value: string, index: number): JSX.Element => ( +
    + {`${index}:`} + {` ${value}`} +
    + ), + )}
    ); } @@ -267,10 +249,7 @@ interface Props { function AttributeEditor(props: Props): JSX.Element { const { - attribute, - currentValue, - onChange, - clientID, + attribute, currentValue, onChange, clientID, } = props; const { inputType, values, id: attrID } = attribute; diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-switcher.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-switcher.tsx index 66357b2f..2632b6a6 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-switcher.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-switcher.tsx @@ -3,10 +3,10 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; import Text from 'antd/lib/typography/Text'; import Tooltip from 'antd/lib/tooltip'; import Button from 'antd/lib/button'; +import { LeftOutlined, RightOutlined } from '@ant-design/icons'; interface Props { currentAttribute: string; @@ -18,19 +18,15 @@ interface Props { function AttributeSwitcher(props: Props): JSX.Element { const { - currentAttribute, - currentIndex, - attributesCount, - nextAttribute, - normalizedKeyMap, + currentAttribute, currentIndex, attributesCount, nextAttribute, normalizedKeyMap, } = props; const title = `${currentAttribute} [${currentIndex + 1}/${attributesCount}]`; return ( -
    +
    - @@ -38,8 +34,8 @@ function AttributeSwitcher(props: Props): JSX.Element { {` [${currentIndex + 1}/${attributesCount}]`} -
    diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-basics-edtior.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-basics-edtior.tsx index ea9db335..48c3f13e 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-basics-edtior.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-basics-edtior.tsx @@ -15,16 +15,15 @@ function ObjectBasicsEditor(props: Props): JSX.Element { const { currentLabel, labels, changeLabel } = props; return ( -
    +
    ); diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx index 5d69834d..f371a287 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx @@ -3,10 +3,10 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; import Text from 'antd/lib/typography/Text'; import Tooltip from 'antd/lib/tooltip'; import Button from 'antd/lib/button'; +import { LeftOutlined, RightOutlined } from '@ant-design/icons'; interface Props { currentLabel: string; @@ -20,21 +20,15 @@ interface Props { function ObjectSwitcher(props: Props): JSX.Element { const { - currentLabel, - clientID, - objectsCount, - currentIndex, - nextObject, - normalizedKeyMap, + currentLabel, clientID, objectsCount, currentIndex, nextObject, normalizedKeyMap, } = props; - const title = `${currentLabel} ${clientID} [${currentIndex + 1}/${objectsCount}]`; return ( -
    +
    - @@ -43,8 +37,8 @@ function ObjectSwitcher(props: Props): JSX.Element { {`[${currentIndex + 1}/${objectsCount}]`} -
    diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-workspace.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-workspace.tsx index d4e5fd8d..5cd8a079 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-workspace.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-workspace.tsx @@ -6,7 +6,7 @@ import './styles.scss'; import React from 'react'; import Layout from 'antd/lib/layout'; -import CanvasWrapperContainer from 'containers/annotation-page/standard-workspace/canvas-wrapper'; +import CanvasWrapperContainer from 'containers/annotation-page/canvas/canvas-wrapper'; import AttributeAnnotationSidebar from './attribute-annotation-sidebar/attribute-annotation-sidebar'; export default function AttributeAnnotationWorkspace(): JSX.Element { diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/styles.scss b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/styles.scss index fbbd2e07..ce685436 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/styles.scss +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/styles.scss @@ -13,8 +13,8 @@ padding: 5px; } -.attribute-annotation-sidebar-object-switcher, -.attribute-annotation-sidebar-attribute-switcher { +.cvat-attribute-annotation-sidebar-object-switcher, +.cvat-attribute-annotation-sidebar-attribute-switcher { display: flex; align-items: center; justify-content: space-between; @@ -27,12 +27,12 @@ overflow: hidden; } - > button > i { + > button > span[role='img'] { color: $objects-bar-icons-color; } } -.attribute-annotation-sidebar-basics-editor { +.cvat-attribute-annotation-sidebar-basics-editor { display: flex; align-items: center; justify-content: space-between; @@ -58,7 +58,7 @@ justify-content: space-around; } -.attribute-annotation-sidebar-attr-editor { +.cvat-attribute-annotation-sidebar-attr-editor { display: flex; align-items: center; justify-content: space-around; diff --git a/cvat-ui/src/components/annotation-page/canvas/canvas-context-menu.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-context-menu.tsx new file mode 100644 index 00000000..c85cffd1 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-context-menu.tsx @@ -0,0 +1,142 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import ReactDOM from 'react-dom'; +import Menu from 'antd/lib/menu'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { MenuInfo } from 'rc-menu/lib/interface'; + +import ObjectItemContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/object-item'; +import { Workspace } from 'reducers/interfaces'; +import consts from 'consts'; + +interface Props { + readonly: boolean; + workspace: Workspace; + contextMenuClientID: number | null; + objectStates: any[]; + visible: boolean; + left: number; + top: number; + onStartIssue(position: number[]): void; + openIssue(position: number[], message: string): void; + latestComments: string[]; +} + +interface ReviewContextMenuProps { + top: number; + left: number; + latestComments: string[]; + onClick: (param: MenuInfo) => void; +} + +enum ReviewContextMenuKeys { + OPEN_ISSUE = 'open_issue', + QUICK_ISSUE_POSITION = 'quick_issue_position', + QUICK_ISSUE_ATTRIBUTE = 'quick_issue_attribute', + QUICK_ISSUE_FROM_LATEST = 'quick_issue_from_latest', +} + +function ReviewContextMenu({ + top, left, latestComments, onClick, +}: ReviewContextMenuProps): JSX.Element { + return ( + + + Open an issue ... + + + Quick issue: incorrect position + + + Quick issue: incorrect attribute + + {latestComments.length ? ( + + {latestComments.map( + (comment: string, id: number): JSX.Element => ( + + {comment} + + ), + )} + + ) : null} + + ); +} + +export default function CanvasContextMenu(props: Props): JSX.Element | null { + const { + contextMenuClientID, + objectStates, + visible, + left, + top, + readonly, + workspace, + latestComments, + onStartIssue, + openIssue, + } = props; + + if (!visible || contextMenuClientID === null) { + return null; + } + + if (workspace === Workspace.REVIEW_WORKSPACE) { + return ReactDOM.createPortal( + { + const [state] = objectStates.filter( + (_state: any): boolean => _state.clientID === contextMenuClientID, + ); + if (param.key === ReviewContextMenuKeys.OPEN_ISSUE) { + if (state) { + onStartIssue(state.points); + } + } else if (param.key === ReviewContextMenuKeys.QUICK_ISSUE_POSITION) { + if (state) { + openIssue(state.points, consts.QUICK_ISSUE_INCORRECT_POSITION_TEXT); + } + } else if (param.key === ReviewContextMenuKeys.QUICK_ISSUE_ATTRIBUTE) { + if (state) { + openIssue(state.points, consts.QUICK_ISSUE_INCORRECT_ATTRIBUTE_TEXT); + } + } else if ( + param.keyPath.length === 2 && + param.keyPath[1] === ReviewContextMenuKeys.QUICK_ISSUE_FROM_LATEST + ) { + if (state) { + openIssue(state.points, latestComments[+param.keyPath[0]]); + } + } + }} + />, + window.document.body, + ); + } + + return ReactDOM.createPortal( +
    + +
    , + window.document.body, + ); +} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-point-context-menu.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx similarity index 72% rename from cvat-ui/src/components/annotation-page/standard-workspace/canvas-point-context-menu.tsx rename to cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx index 9d6f56c0..04ecd78c 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-point-context-menu.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx @@ -6,6 +6,7 @@ import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import Button from 'antd/lib/button'; import Tooltip from 'antd/lib/tooltip'; +import { DeleteOutlined, EnvironmentOutlined } from '@ant-design/icons'; import { connect } from 'react-redux'; import { CombinedState, ContextMenuType } from 'reducers/interfaces'; @@ -23,25 +24,20 @@ interface StateToProps { function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { - annotations: { - states, - activatedStateID, - }, + annotations: { states, activatedStateID }, canvas: { contextMenu: { - visible, - top, - left, - type, - pointID: selectedPoint, + visible, top, left, type, pointID: selectedPoint, }, }, }, } = state; return { - activatedState: activatedStateID === null - ? null : states.filter((_state) => _state.clientID === activatedStateID)[0] || null, + activatedState: + activatedStateID === null ? + null : + states.filter((_state) => _state.clientID === activatedStateID)[0] || null, selectedPoint, visible, left, @@ -70,13 +66,7 @@ type Props = StateToProps & DispatchToProps; function CanvasPointContextMenu(props: Props): React.ReactPortal | null { const { - onCloseContextMenu, - onUpdateAnnotations, - activatedState, - visible, - type, - top, - left, + onCloseContextMenu, onUpdateAnnotations, activatedState, visible, type, top, left, } = props; const [contextMenuFor, setContextMenuFor] = useState(activatedState); @@ -91,7 +81,8 @@ function CanvasPointContextMenu(props: Props): React.ReactPortal | null { const onPointDelete = (): void => { const { selectedPoint } = props; if (contextMenuFor && selectedPoint !== null) { - contextMenuFor.points = contextMenuFor.points.slice(0, selectedPoint * 2) + contextMenuFor.points = contextMenuFor.points + .slice(0, selectedPoint * 2) .concat(contextMenuFor.points.slice(selectedPoint * 2 + 2)); onUpdateAnnotations([contextMenuFor]); onCloseContextMenu(); @@ -101,32 +92,31 @@ function CanvasPointContextMenu(props: Props): React.ReactPortal | null { const onSetStartPoint = (): void => { const { selectedPoint } = props; if (contextMenuFor && selectedPoint !== null && contextMenuFor.shapeType === 'polygon') { - contextMenuFor.points = contextMenuFor.points.slice(selectedPoint * 2) + contextMenuFor.points = contextMenuFor.points + .slice(selectedPoint * 2) .concat(contextMenuFor.points.slice(0, selectedPoint * 2)); onUpdateAnnotations([contextMenuFor]); onCloseContextMenu(); } }; - return visible && contextMenuFor && type === ContextMenuType.CANVAS_SHAPE_POINT - ? (ReactDOM.createPortal( + return visible && contextMenuFor && type === ContextMenuType.CANVAS_SHAPE_POINT ? + ReactDOM.createPortal(
    - - {contextMenuFor && contextMenuFor.shapeType === 'polygon' && ( - )}
    , window.document.body, - )) : null; + ) : + null; } -export default connect( - mapStateToProps, - mapDispatchToProps, -)(CanvasPointContextMenu); +export default connect(mapStateToProps, mapDispatchToProps)(CanvasPointContextMenu); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx similarity index 77% rename from cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx rename to cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx index 14a13014..3c5d03c2 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx @@ -6,22 +6,17 @@ import React from 'react'; import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; import Tooltip from 'antd/lib/tooltip'; -import Icon from 'antd/lib/icon'; -import Layout from 'antd/lib/layout/layout'; -import Slider, { SliderValue } from 'antd/lib/slider'; +import Layout from 'antd/lib/layout'; +import Slider from 'antd/lib/slider'; import { - ColorBy, - GridColor, - ObjectType, - ContextMenuType, - Workspace, - ShapeType, + ColorBy, GridColor, ObjectType, ContextMenuType, Workspace, ShapeType, } from 'reducers/interfaces'; import { LogType } from 'cvat-logger'; import { Canvas } from 'cvat-canvas-wrapper'; import getCore from 'cvat-core-wrapper'; import consts from 'consts'; +import { PlusCircleOutlined } from '@ant-design/icons'; const cvat = getCore(); @@ -35,6 +30,7 @@ interface Props { activatedAttributeID: number | null; selectedStatesID: number[]; annotations: any[]; + frameIssues: any[] | null; frameData: any; frameAngle: number; frameFetching: boolean; @@ -42,7 +38,8 @@ interface Props { opacity: number; colorBy: ColorBy; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; grid: boolean; @@ -82,8 +79,7 @@ interface Props { onSplitAnnotations(sessionInstance: any, frame: number, state: any): void; onActivateObject(activatedStateID: number | null): void; onSelectObjects(selectedStatesID: number[]): void; - onUpdateContextMenu(visible: boolean, left: number, top: number, type: ContextMenuType, - pointID?: number): void; + onUpdateContextMenu(visible: boolean, left: number, top: number, type: ContextMenuType, pointID?: number): void; onAddZLayer(): void; onSwitchZLayer(cur: number): void; onChangeBrightnessLevel(level: number): void; @@ -94,29 +90,30 @@ interface Props { onSwitchGrid(enabled: boolean): void; onSwitchAutomaticBordering(enabled: boolean): void; onFetchAnnotation(): void; + onGetDataFailed(error: any): void; + onStartIssue(position: number[]): void; } export default class CanvasWrapperComponent extends React.PureComponent { public componentDidMount(): void { const { - automaticBordering, - showObjectsTextAlways, - canvasInstance, + automaticBordering, showObjectsTextAlways, canvasInstance, workspace, } = this.props; // It's awful approach from the point of view React // But we do not have another way because cvat-canvas returns regular DOM element - const [wrapper] = window.document - .getElementsByClassName('cvat-canvas-container'); + const [wrapper] = window.document.getElementsByClassName('cvat-canvas-container'); wrapper.appendChild(canvasInstance.html()); canvasInstance.configure({ autoborders: automaticBordering, undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE, displayAllText: showObjectsTextAlways, + forceDisableEditing: workspace === Workspace.REVIEW_WORKSPACE, }); this.initialSetup(); + this.updateIssueRegions(); this.updateCanvas(); } @@ -125,8 +122,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { opacity, colorBy, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, + frameIssues, frameData, frameAngle, annotations, @@ -152,9 +151,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { onFetchAnnotation, } = this.props; - if (prevProps.showObjectsTextAlways !== showObjectsTextAlways - || prevProps.automaticBordering !== automaticBordering - || prevProps.showProjections !== showProjections + if ( + prevProps.showObjectsTextAlways !== showObjectsTextAlways || + prevProps.automaticBordering !== automaticBordering || + prevProps.showProjections !== showProjections ) { canvasInstance.configure({ undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE, @@ -171,14 +171,17 @@ export default class CanvasWrapperComponent extends React.PureComponent { if (prevProps.sidebarCollapsed !== sidebarCollapsed) { const [sidebar] = window.document.getElementsByClassName('cvat-objects-sidebar'); if (sidebar) { - sidebar.addEventListener('transitionend', () => { - canvasInstance.fitCanvas(); - }, { once: true }); + sidebar.addEventListener( + 'transitionend', + () => { + canvasInstance.fitCanvas(); + }, + { once: true }, + ); } } - if (prevProps.activatedStateID !== null - && prevProps.activatedStateID !== activatedStateID) { + if (prevProps.activatedStateID !== null && prevProps.activatedStateID !== activatedStateID) { canvasInstance.activate(null); const el = window.document.getElementById(`cvat_canvas_shape_${prevProps.activatedStateID}`); if (el) { @@ -190,9 +193,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { canvasInstance.grid(gridSize, gridSize); } - if (gridOpacity !== prevProps.gridOpacity - || gridColor !== prevProps.gridColor - || grid !== prevProps.grid) { + if (gridOpacity !== prevProps.gridOpacity || gridColor !== prevProps.gridColor || grid !== prevProps.grid) { const gridElement = window.document.getElementById('cvat_canvas_grid'); const gridPattern = window.document.getElementById('cvat_canvas_grid_pattern'); if (gridElement) { @@ -204,34 +205,48 @@ export default class CanvasWrapperComponent extends React.PureComponent { } } - if (brightnessLevel !== prevProps.brightnessLevel - || contrastLevel !== prevProps.contrastLevel - || saturationLevel !== prevProps.saturationLevel) { + if ( + brightnessLevel !== prevProps.brightnessLevel || + contrastLevel !== prevProps.contrastLevel || + saturationLevel !== prevProps.saturationLevel + ) { const backgroundElement = window.document.getElementById('cvat_canvas_background'); if (backgroundElement) { - backgroundElement.style.filter = `brightness(${brightnessLevel / 100})` - + `contrast(${contrastLevel / 100})` - + `saturate(${saturationLevel / 100})`; + backgroundElement.style.filter = + `brightness(${brightnessLevel / 100})` + + `contrast(${contrastLevel / 100})` + + `saturate(${saturationLevel / 100})`; } } - if (prevProps.annotations !== annotations - || prevProps.frameData !== frameData - || prevProps.curZLayer !== curZLayer) { - this.updateCanvas(); + if (prevProps.frameIssues !== frameIssues) { + this.updateIssueRegions(); } - if (prevProps.frame !== frameData.number - && ((resetZoom && workspace !== Workspace.ATTRIBUTE_ANNOTATION) - || workspace === Workspace.TAG_ANNOTATION) + if ( + prevProps.annotations !== annotations || + prevProps.frameData !== frameData || + prevProps.curZLayer !== curZLayer ) { - canvasInstance.html().addEventListener('canvas.setup', () => { - canvasInstance.fit(); - }, { once: true }); + this.updateCanvas(); + } + + if (prevProps.frame !== frameData.number && resetZoom && workspace !== Workspace.ATTRIBUTE_ANNOTATION) { + canvasInstance.html().addEventListener( + 'canvas.setup', + () => { + canvasInstance.fit(); + }, + { once: true }, + ); } - if (prevProps.opacity !== opacity || prevProps.blackBorders !== blackBorders - || prevProps.selectedOpacity !== selectedOpacity || prevProps.colorBy !== colorBy + if ( + prevProps.opacity !== opacity || + prevProps.outlined !== outlined || + prevProps.outlineColor !== outlineColor || + prevProps.selectedOpacity !== selectedOpacity || + prevProps.colorBy !== colorBy ) { this.updateShapesView(); } @@ -244,6 +259,18 @@ export default class CanvasWrapperComponent extends React.PureComponent { canvasInstance.rotate(frameAngle); } + if (prevProps.workspace !== workspace) { + if (workspace === Workspace.REVIEW_WORKSPACE) { + canvasInstance.configure({ + forceDisableEditing: true, + }); + } else if (prevProps.workspace === Workspace.REVIEW_WORKSPACE) { + canvasInstance.configure({ + forceDisableEditing: false, + }); + } + } + const loadingAnimation = window.document.getElementById('cvat_canvas_loading_animation'); if (loadingAnimation && frameFetching !== prevProps.frameFetching) { if (frameFetching) { @@ -254,7 +281,9 @@ export default class CanvasWrapperComponent extends React.PureComponent { } if (prevProps.canvasBackgroundColor !== canvasBackgroundColor) { - const canvasWrapperElement = window.document.getElementsByClassName('cvat-canvas-container').item(0) as HTMLElement | null; + const canvasWrapperElement = window.document + .getElementsByClassName('cvat-canvas-container') + .item(0) as HTMLElement | null; if (canvasWrapperElement) { canvasWrapperElement.style.backgroundColor = canvasBackgroundColor; } @@ -290,21 +319,24 @@ export default class CanvasWrapperComponent extends React.PureComponent { canvasInstance.html().removeEventListener('canvas.drawn', this.onCanvasShapeDrawn); canvasInstance.html().removeEventListener('canvas.merged', this.onCanvasObjectsMerged); canvasInstance.html().removeEventListener('canvas.groupped', this.onCanvasObjectsGroupped); + canvasInstance.html().removeEventListener('canvas.regionselected', this.onCanvasPositionSelected); canvasInstance.html().removeEventListener('canvas.splitted', this.onCanvasTrackSplitted); canvasInstance.html().removeEventListener('canvas.contextmenu', this.onCanvasPointContextMenu); + canvasInstance.html().removeEventListener('canvas.error', this.onCanvasErrorOccurrence); window.removeEventListener('resize', this.fitCanvas); } + private onCanvasErrorOccurrence = (event: any): void => { + const { exception } = event.detail; + const { onGetDataFailed } = this.props; + onGetDataFailed(exception); + }; + private onCanvasShapeDrawn = (event: any): void => { const { - jobInstance, - activeLabelID, - activeObjectType, - frame, - onShapeDrawn, - onCreateAnnotations, + jobInstance, activeLabelID, activeObjectType, frame, onShapeDrawn, onCreateAnnotations, } = this.props; if (!event.detail.continue) { @@ -320,8 +352,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { } state.objectType = state.objectType || activeObjectType; - state.label = state.label || jobInstance.task.labels - .filter((label: any) => label.id === activeLabelID)[0]; + state.label = state.label || jobInstance.task.labels.filter((label: any) => label.id === activeLabelID)[0]; state.occluded = state.occluded || false; state.frame = frame; const objectState = new cvat.classes.ObjectState(state); @@ -330,10 +361,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasObjectsMerged = (event: any): void => { const { - jobInstance, - frame, - onMergeAnnotations, - onMergeObjects, + jobInstance, frame, onMergeAnnotations, onMergeObjects, } = this.props; onMergeObjects(false); @@ -348,10 +376,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasObjectsGroupped = (event: any): void => { const { - jobInstance, - frame, - onGroupAnnotations, - onGroupObjects, + jobInstance, frame, onGroupAnnotations, onGroupObjects, } = this.props; onGroupObjects(false); @@ -360,12 +385,16 @@ export default class CanvasWrapperComponent extends React.PureComponent { onGroupAnnotations(jobInstance, frame, states); }; + private onCanvasPositionSelected = (event: any): void => { + const { onResetCanvas, onStartIssue } = this.props; + const { points } = event.detail; + onStartIssue(points); + onResetCanvas(); + }; + private onCanvasTrackSplitted = (event: any): void => { const { - jobInstance, - frame, - onSplitAnnotations, - onSplitTrack, + jobInstance, frame, onSplitAnnotations, onSplitTrack, } = this.props; onSplitTrack(false); @@ -382,7 +411,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasMouseDown = (e: MouseEvent): void => { const { workspace, activatedStateID, onActivateObject } = this.props; - if ((e.target as HTMLElement).tagName === 'svg') { + if ((e.target as HTMLElement).tagName === 'svg' && e.button !== 2) { if (activatedStateID !== null && workspace !== Workspace.ATTRIBUTE_ANNOTATION) { onActivateObject(null); } @@ -390,20 +419,18 @@ export default class CanvasWrapperComponent extends React.PureComponent { }; private onCanvasClicked = (): void => { - if (document.activeElement instanceof HTMLElement) { + const { canvasInstance, onUpdateContextMenu } = this.props; + onUpdateContextMenu(false, 0, 0, ContextMenuType.CANVAS_SHAPE); + if (!canvasInstance.html().contains(document.activeElement) && document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } }; private onCanvasContextMenu = (e: MouseEvent): void => { - const { - activatedStateID, - onUpdateContextMenu, - } = this.props; + const { activatedStateID, onUpdateContextMenu } = this.props; if (e.target && !(e.target as HTMLElement).classList.contains('svg_select_points')) { - onUpdateContextMenu(activatedStateID !== null, e.clientX, e.clientY, - ContextMenuType.CANVAS_SHAPE); + onUpdateContextMenu(activatedStateID !== null, e.clientX, e.clientY, ContextMenuType.CANVAS_SHAPE); } }; @@ -431,8 +458,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasShapeClicked = (e: any): void => { const { clientID } = e.detail.state; - const sidebarItem = window.document - .getElementById(`cvat-objects-sidebar-state-item-${clientID}`); + const sidebarItem = window.document.getElementById(`cvat-objects-sidebar-state-item-${clientID}`); if (sidebarItem) { sidebarItem.scrollIntoView(); } @@ -452,21 +478,14 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasCursorMoved = async (event: any): Promise => { const { - jobInstance, - activatedStateID, - workspace, - onActivateObject, + jobInstance, activatedStateID, workspace, onActivateObject, } = this.props; - if (workspace !== Workspace.STANDARD) { + if (![Workspace.STANDARD, Workspace.REVIEW_WORKSPACE].includes(workspace)) { return; } - const result = await jobInstance.annotations.select( - event.detail.states, - event.detail.x, - event.detail.y, - ); + const result = await jobInstance.annotations.select(event.detail.states, event.detail.x, event.detail.y); if (result && result.state) { if (result.state.shapeType === 'polyline' || result.state.shapeType === 'points') { @@ -488,17 +507,11 @@ export default class CanvasWrapperComponent extends React.PureComponent { }; private onCanvasEditDone = (event: any): void => { - const { - onEditShape, - onUpdateAnnotations, - } = this.props; + const { onEditShape, onUpdateAnnotations } = this.props; onEditShape(false); - const { - state, - points, - } = event.detail; + const { state, points } = event.detail; state.points = points; onUpdateAnnotations([state]); }; @@ -538,8 +551,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { private onCanvasFindObject = async (e: any): Promise => { const { jobInstance, canvasInstance } = this.props; - const result = await jobInstance.annotations - .select(e.detail.states, e.detail.x, e.detail.y); + const result = await jobInstance.annotations.select(e.detail.states, e.detail.x, e.detail.y); if (result && result.state) { if (result.state.shapeType === 'polyline' || result.state.shapeType === 'points') { @@ -553,16 +565,17 @@ export default class CanvasWrapperComponent extends React.PureComponent { }; private onCanvasPointContextMenu = (e: any): void => { - const { - activatedStateID, - onUpdateContextMenu, - annotations, - } = this.props; + const { activatedStateID, onUpdateContextMenu, annotations } = this.props; - const [state] = annotations.filter((el: any) => (el.clientID === activatedStateID)); + const [state] = annotations.filter((el: any) => el.clientID === activatedStateID); if (![ShapeType.CUBOID, ShapeType.RECTANGLE].includes(state.shapeType)) { - onUpdateContextMenu(activatedStateID !== null, e.detail.mouseEvent.clientX, - e.detail.mouseEvent.clientY, ContextMenuType.CANVAS_SHAPE_POINT, e.detail.pointID); + onUpdateContextMenu( + activatedStateID !== null, + e.detail.mouseEvent.clientX, + e.detail.mouseEvent.clientY, + ContextMenuType.CANVAS_SHAPE_POINT, + e.detail.pointID, + ); } }; @@ -578,8 +591,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { } = this.props; if (activatedStateID !== null) { - const [activatedState] = annotations - .filter((state: any): boolean => state.clientID === activatedStateID); + const [activatedState] = annotations.filter((state: any): boolean => state.clientID === activatedStateID); if (workspace === Workspace.ATTRIBUTE_ANNOTATION) { if (activatedState.objectType !== ObjectType.TAG) { canvasInstance.focus(activatedStateID, aamZoomMargin); @@ -592,17 +604,14 @@ export default class CanvasWrapperComponent extends React.PureComponent { } const el = window.document.getElementById(`cvat_canvas_shape_${activatedStateID}`); if (el) { - (el as any as SVGElement).setAttribute('fill-opacity', `${selectedOpacity / 100}`); + ((el as any) as SVGElement).setAttribute('fill-opacity', `${selectedOpacity / 100}`); } } } private updateShapesView(): void { const { - annotations, - opacity, - colorBy, - blackBorders, + annotations, opacity, colorBy, outlined, outlineColor, } = this.props; for (const state of annotations) { @@ -625,22 +634,38 @@ export default class CanvasWrapperComponent extends React.PureComponent { } (shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 }); - (shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor }); + (shapeView as any).instance.stroke({ color: outlined ? outlineColor : shapeColor }); } } } + private updateIssueRegions(): void { + const { canvasInstance, frameIssues } = this.props; + if (frameIssues === null) { + canvasInstance.setupIssueRegions({}); + } else { + const regions = frameIssues.reduce((acc: Record, issue: any): Record< + number, + number[] + > => { + acc[issue.id] = issue.position; + return acc; + }, {}); + canvasInstance.setupIssueRegions(regions); + } + } + private updateCanvas(): void { const { - curZLayer, - annotations, - frameData, - canvasInstance, + curZLayer, annotations, frameData, canvasInstance, } = this.props; if (frameData !== null) { - canvasInstance.setup(frameData, annotations - .filter((e) => e.objectType !== ObjectType.TAG), curZLayer); + canvasInstance.setup( + frameData, + annotations.filter((e) => e.objectType !== ObjectType.TAG), + curZLayer, + ); } } @@ -676,22 +701,29 @@ export default class CanvasWrapperComponent extends React.PureComponent { // Filters const backgroundElement = window.document.getElementById('cvat_canvas_background'); if (backgroundElement) { - backgroundElement.style.filter = `brightness(${brightnessLevel / 100})` - + `contrast(${contrastLevel / 100})` - + `saturate(${saturationLevel / 100})`; + backgroundElement.style.filter = + `brightness(${brightnessLevel / 100})` + + `contrast(${contrastLevel / 100})` + + `saturate(${saturationLevel / 100})`; } - const canvasWrapperElement = window.document.getElementsByClassName('cvat-canvas-container').item(0) as HTMLElement | null; + const canvasWrapperElement = window.document + .getElementsByClassName('cvat-canvas-container') + .item(0) as HTMLElement | null; if (canvasWrapperElement) { canvasWrapperElement.style.backgroundColor = canvasBackgroundColor; } // Events - canvasInstance.html().addEventListener('canvas.setup', () => { - const { activatedStateID, activatedAttributeID } = this.props; - canvasInstance.fit(); - canvasInstance.activate(activatedStateID, activatedAttributeID); - }, { once: true }); + canvasInstance.html().addEventListener( + 'canvas.setup', + () => { + const { activatedStateID, activatedAttributeID } = this.props; + canvasInstance.fit(); + canvasInstance.activate(activatedStateID, activatedAttributeID); + }, + { once: true }, + ); canvasInstance.html().addEventListener('mousedown', this.onCanvasMouseDown); canvasInstance.html().addEventListener('click', this.onCanvasClicked); @@ -717,9 +749,11 @@ export default class CanvasWrapperComponent extends React.PureComponent { canvasInstance.html().addEventListener('canvas.drawn', this.onCanvasShapeDrawn); canvasInstance.html().addEventListener('canvas.merged', this.onCanvasObjectsMerged); canvasInstance.html().addEventListener('canvas.groupped', this.onCanvasObjectsGroupped); + canvasInstance.html().addEventListener('canvas.regionselected', this.onCanvasPositionSelected); canvasInstance.html().addEventListener('canvas.splitted', this.onCanvasTrackSplitted); canvasInstance.html().addEventListener('canvas.contextmenu', this.onCanvasPointContextMenu); + canvasInstance.html().addEventListener('canvas.error', this.onCanvasErrorOccurrence); } public render(): JSX.Element { @@ -766,7 +800,6 @@ export default class CanvasWrapperComponent extends React.PureComponent { SWITCH_AUTOMATIC_BORDERING: keyMap.SWITCH_AUTOMATIC_BORDERING, }; - const step = 10; const handlers = { INCREASE_BRIGHTNESS: (event: KeyboardEvent | undefined) => { @@ -835,8 +868,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { }, CHANGE_GRID_COLOR: (event: KeyboardEvent | undefined) => { preventDefault(event); - const colors = [GridColor.Black, GridColor.Blue, - GridColor.Green, GridColor.Red, GridColor.White]; + const colors = [GridColor.Black, GridColor.Blue, GridColor.Green, GridColor.Red, GridColor.White]; const indexOf = colors.indexOf(gridColor) + 1; const color = colors[indexOf >= colors.length ? 0 : indexOf]; onChangeGridColor(color); @@ -874,10 +906,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { vertical reverse defaultValue={0} - onChange={(value: SliderValue): void => onSwitchZLayer(value as number)} + onChange={(value: number): void => onSwitchZLayer(value as number)} /> - +
    diff --git a/cvat-ui/src/components/annotation-page/request-review-modal.tsx b/cvat-ui/src/components/annotation-page/request-review-modal.tsx new file mode 100644 index 00000000..884f1447 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/request-review-modal.tsx @@ -0,0 +1,64 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { useState } from 'react'; +import { AnyAction } from 'redux'; +import { useSelector, useDispatch } from 'react-redux'; +import { useHistory } from 'react-router'; +import Text from 'antd/lib/typography/Text'; +import Title from 'antd/lib/typography/Title'; +import Modal from 'antd/lib/modal'; +import { Row, Col } from 'antd/lib/grid'; + +import UserSelector, { User } from 'components/task-page/user-selector'; +import { CombinedState, TaskStatus } from 'reducers/interfaces'; +import { switchRequestReviewDialog } from 'actions/annotation-actions'; +import { updateJobAsync } from 'actions/tasks-actions'; + +export default function RequestReviewModal(): JSX.Element | null { + const dispatch = useDispatch(); + const history = useHistory(); + const isVisible = useSelector((state: CombinedState): boolean => state.annotation.requestReviewDialogVisible); + const job = useSelector((state: CombinedState): any => state.annotation.job.instance); + const [reviewer, setReviewer] = useState(job.reviewer ? job.reviewer : null); + const close = (): AnyAction => dispatch(switchRequestReviewDialog(false)); + const submitAnnotations = (): void => { + job.reviewer = reviewer; + job.status = TaskStatus.REVIEW; + dispatch(updateJobAsync(job)); + history.push(`/tasks/${job.task.id}`); + }; + + if (!isVisible) { + return null; + } + + return ( + + + + Assign a user who is responsible for review + + + + + Reviewer: + + + + + + + You might not be able to change the job after this action. Continue? + + + ); +} diff --git a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx new file mode 100644 index 00000000..9eb53fa2 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx @@ -0,0 +1,93 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import Layout from 'antd/lib/layout'; + +import { ActiveControl, Rotation } from 'reducers/interfaces'; +import { Canvas } from 'cvat-canvas-wrapper'; + +import RotateControl from 'components/annotation-page/standard-workspace/controls-side-bar/rotate-control'; +import CursorControl from 'components/annotation-page/standard-workspace/controls-side-bar/cursor-control'; +import MoveControl from 'components/annotation-page/standard-workspace/controls-side-bar/move-control'; +import FitControl from 'components/annotation-page/standard-workspace/controls-side-bar/fit-control'; +import ResizeControl from 'components/annotation-page/standard-workspace/controls-side-bar/resize-control'; +import IssueControl from './issue-control'; + +interface Props { + canvasInstance: Canvas; + activeControl: ActiveControl; + keyMap: Record; + normalizedKeyMap: Record; + + rotateFrame(rotation: Rotation): void; + selectIssuePosition(enabled: boolean): void; +} + +export default function ControlsSideBarComponent(props: Props): JSX.Element { + const { + canvasInstance, activeControl, normalizedKeyMap, keyMap, rotateFrame, selectIssuePosition, + } = props; + + const preventDefault = (event: KeyboardEvent | undefined): void => { + if (event) { + event.preventDefault(); + } + }; + + const subKeyMap = { + CANCEL: keyMap.CANCEL, + OPEN_REVIEW_ISSUE: keyMap.OPEN_REVIEW_ISSUE, + }; + + const handlers = { + CANCEL: (event: KeyboardEvent | undefined) => { + preventDefault(event); + if (activeControl !== ActiveControl.CURSOR) { + canvasInstance.cancel(); + } + }, + OPEN_REVIEW_ISSUE: (event: KeyboardEvent | undefined) => { + preventDefault(event); + if (activeControl === ActiveControl.OPEN_ISSUE) { + canvasInstance.selectRegion(false); + selectIssuePosition(false); + } else { + canvasInstance.cancel(); + canvasInstance.selectRegion(true); + selectIssuePosition(true); + } + }, + }; + + return ( + + + + + + +
    + + + + +
    + +
    + ); +} diff --git a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx new file mode 100644 index 00000000..6fe71158 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx @@ -0,0 +1,46 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import Icon from '@ant-design/icons'; +import Tooltip from 'antd/lib/tooltip'; + +import { ActiveControl } from 'reducers/interfaces'; +import { Canvas } from 'cvat-canvas-wrapper'; +import { RectangleIcon } from 'icons'; + +interface Props { + canvasInstance: Canvas; + activeControl: ActiveControl; + selectIssuePosition(enabled: boolean): void; +} + +function ResizeControl(props: Props): JSX.Element { + const { activeControl, canvasInstance, selectIssuePosition } = props; + + return ( + + { + if (activeControl === ActiveControl.OPEN_ISSUE) { + canvasInstance.selectRegion(false); + selectIssuePosition(false); + } else { + canvasInstance.cancel(); + canvasInstance.selectRegion(true); + selectIssuePosition(true); + } + }} + /> + + ); +} + +export default React.memo(ResizeControl); diff --git a/cvat-ui/src/components/annotation-page/review-workspace/review-workspace.tsx b/cvat-ui/src/components/annotation-page/review-workspace/review-workspace.tsx new file mode 100644 index 00000000..095a69c7 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review-workspace/review-workspace.tsx @@ -0,0 +1,50 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import './styles.scss'; +import React, { useEffect } from 'react'; +import Layout from 'antd/lib/layout'; +import { useDispatch, useSelector } from 'react-redux'; + +import { CombinedState } from 'reducers/interfaces'; +import { initializeReviewAsync } from 'actions/review-actions'; + +import CanvasWrapperContainer from 'containers/annotation-page/canvas/canvas-wrapper'; +import ControlsSideBarContainer from 'containers/annotation-page/review-workspace/controls-side-bar/controls-side-bar'; +import ObjectSideBarComponent from 'components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar'; +import ObjectsListContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/objects-list'; +import CanvasContextMenuContainer from 'containers/annotation-page/canvas/canvas-context-menu'; +import IssueAggregatorComponent from 'components/annotation-page/review/issues-aggregator'; + +export default function ReviewWorkspaceComponent(): JSX.Element { + const dispatch = useDispatch(); + const frame = useSelector((state: CombinedState): number => state.annotation.player.frame.number); + const states = useSelector((state: CombinedState): any[] => state.annotation.annotations.states); + const review = useSelector((state: CombinedState): any => state.review.activeReview); + + useEffect(() => { + if (review) { + review.reviewFrame(frame); + review.reviewStates( + states + .map((state: any): number | undefined => state.serverID) + .filter((serverID: number | undefined): boolean => typeof serverID !== 'undefined') + .map((serverID: number | undefined): string => `${frame}_${serverID}`), + ); + } + }, [frame, states, review]); + useEffect(() => { + dispatch(initializeReviewAsync()); + }, []); + + return ( + + + + } /> + + + + ); +} diff --git a/cvat-ui/src/components/annotation-page/review-workspace/styles.scss b/cvat-ui/src/components/annotation-page/review-workspace/styles.scss new file mode 100644 index 00000000..1c9d3348 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review-workspace/styles.scss @@ -0,0 +1,21 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +@import 'base.scss'; + +.cvat-review-workspace.ant-layout { + height: 100%; +} + +.cvat-issue-control { + font-size: 40px; + + &::after { + content: '\FE56'; + font-size: 32px; + position: absolute; + bottom: $grid-unit-size; + right: -$grid-unit-size; + } +} diff --git a/cvat-ui/src/components/annotation-page/review/create-issue-dialog.tsx b/cvat-ui/src/components/annotation-page/review/create-issue-dialog.tsx new file mode 100644 index 00000000..fcd415da --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/create-issue-dialog.tsx @@ -0,0 +1,75 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { ReactPortal } from 'react'; +import ReactDOM from 'react-dom'; +import { useDispatch } from 'react-redux'; +import Form from 'antd/lib/form'; +import Input from 'antd/lib/input'; +import Button from 'antd/lib/button'; +import { Row, Col } from 'antd/lib/grid'; + +import { reviewActions, finishIssueAsync } from 'actions/review-actions'; +import { Store } from 'antd/lib/form/interface'; + +interface FormProps { + top: number; + left: number; + submit(message: string): void; + cancel(): void; +} + +function MessageForm(props: FormProps): JSX.Element { + const { + top, left, submit, cancel, + } = props; + + function handleSubmit(values: Store): void { + submit(values.issue_description); + } + + return ( +
    + + + + + + + + + + + +
    + ); +} + +interface Props { + top: number; + left: number; +} + +export default function CreateIssueDialog(props: Props): ReactPortal { + const dispatch = useDispatch(); + const { top, left } = props; + + return ReactDOM.createPortal( + { + dispatch(finishIssueAsync(message)); + }} + cancel={() => { + dispatch(reviewActions.cancelIssue()); + }} + />, + window.document.getElementById('cvat_canvas_attachment_board') as HTMLElement, + ); +} diff --git a/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx b/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx new file mode 100644 index 00000000..02b5572e --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx @@ -0,0 +1,56 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { ReactPortal, useEffect } from 'react'; +import ReactDOM from 'react-dom'; +import Tag from 'antd/lib/tag'; +import Tooltip from 'antd/lib/tooltip'; +import { CheckOutlined, CloseCircleOutlined } from '@ant-design/icons'; + +interface Props { + id: number; + message: string; + top: number; + left: number; + resolved: boolean; + onClick: () => void; + highlight: () => void; + blur: () => void; +} + +export default function HiddenIssueLabel(props: Props): ReactPortal { + const { + id, message, top, left, resolved, onClick, highlight, blur, + } = props; + + useEffect(() => { + if (!resolved) { + setTimeout(highlight); + } else { + setTimeout(blur); + } + }, [resolved]); + + const elementID = `cvat-hidden-issue-label-${id}`; + return ReactDOM.createPortal( + + + {resolved ? ( + + ) : ( + + )} + {message} + + , + window.document.getElementById('cvat_canvas_attachment_board') as HTMLElement, + ); +} diff --git a/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx b/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx new file mode 100644 index 00000000..8660017d --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx @@ -0,0 +1,143 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { useState, useEffect, useRef } from 'react'; +import ReactDOM from 'react-dom'; +import { Row, Col } from 'antd/lib/grid'; +import { CloseOutlined } from '@ant-design/icons'; +import Comment from 'antd/lib/comment'; +import Text from 'antd/lib/typography/Text'; +import Title from 'antd/lib/typography/Title'; +import Tooltip from 'antd/lib/tooltip'; +import Button from 'antd/lib/button'; +import Input from 'antd/lib/input'; +import moment from 'moment'; + +interface Props { + id: number; + comments: any[]; + left: number; + top: number; + resolved: boolean; + isFetching: boolean; + collapse: () => void; + resolve: () => void; + reopen: () => void; + comment: (message: string) => void; + highlight: () => void; + blur: () => void; +} + +export default function IssueDialog(props: Props): JSX.Element { + const ref = useRef(null); + const [currentText, setCurrentText] = useState(''); + const { + comments, + id, + left, + top, + resolved, + isFetching, + collapse, + resolve, + reopen, + comment, + highlight, + blur, + } = props; + + useEffect(() => { + if (!resolved) { + setTimeout(highlight); + } else { + setTimeout(blur); + } + }, [resolved]); + + const lines = comments.map( + (_comment: any): JSX.Element => { + const created = _comment.createdDate ? moment(_comment.createdDate) : moment(moment.now()); + const diff = created.fromNow(); + + return ( + {_comment.author ? _comment.author.username : 'Unknown'}} + content={

    {_comment.message}

    } + datetime={( + + {diff} + + )} + /> + ); + }, + ); + + const resolveButton = resolved ? ( + + ) : ( + + ); + + return ReactDOM.createPortal( +
    + + + {id >= 0 ? `Issue #${id}` : 'Issue'} + + + + + + + + + {lines} + + + + ) => { + setCurrentText(event.target.value); + }} + onPressEnter={() => { + if (currentText) { + comment(currentText); + setCurrentText(''); + } + }} + /> + + + + + {currentText.length ? ( + + ) : ( + resolveButton + )} + + +
    , + window.document.getElementById('cvat_canvas_attachment_board') as HTMLElement, + ); +} diff --git a/cvat-ui/src/components/annotation-page/review/issues-aggregator.tsx b/cvat-ui/src/components/annotation-page/review/issues-aggregator.tsx new file mode 100644 index 00000000..484e39e2 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/issues-aggregator.tsx @@ -0,0 +1,167 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import './styles.scss'; +import React, { useState, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +import { CombinedState } from 'reducers/interfaces'; +import { Canvas } from 'cvat-canvas/src/typescript/canvas'; + +import { commentIssueAsync, resolveIssueAsync, reopenIssueAsync } from 'actions/review-actions'; + +import CreateIssueDialog from './create-issue-dialog'; +import HiddenIssueLabel from './hidden-issue-label'; +import IssueDialog from './issue-dialog'; + +const scaleHandler = (canvasInstance: Canvas): void => { + const { geometry } = canvasInstance; + const createDialogs = window.document.getElementsByClassName('cvat-create-issue-dialog'); + const hiddenIssues = window.document.getElementsByClassName('cvat-hidden-issue-label'); + const issues = window.document.getElementsByClassName('cvat-issue-dialog'); + for (const element of [...Array.from(createDialogs), ...Array.from(hiddenIssues), ...Array.from(issues)]) { + (element as HTMLSpanElement).style.transform = `scale(${1 / geometry.scale}) rotate(${-geometry.angle}deg)`; + } +}; + +export default function IssueAggregatorComponent(): JSX.Element | null { + const dispatch = useDispatch(); + const [expandedIssue, setExpandedIssue] = useState(null); + const frameIssues = useSelector((state: CombinedState): any[] => state.review.frameIssues); + const canvasInstance = useSelector((state: CombinedState): Canvas => state.annotation.canvas.instance); + const canvasIsReady = useSelector((state: CombinedState): boolean => state.annotation.canvas.ready); + const newIssuePosition = useSelector((state: CombinedState): number[] | null => state.review.newIssuePosition); + const issuesHidden = useSelector((state: CombinedState): any => state.review.issuesHidden); + const issueFetching = useSelector((state: CombinedState): number | null => state.review.fetching.issueId); + const issueLabels: JSX.Element[] = []; + const issueDialogs: JSX.Element[] = []; + + useEffect(() => { + scaleHandler(canvasInstance); + }); + + useEffect(() => { + const regions = frameIssues.reduce((acc: Record, issue: any): Record => { + acc[issue.id] = issue.position; + return acc; + }, {}); + + if (newIssuePosition) { + regions[0] = newIssuePosition; + } + + canvasInstance.setupIssueRegions(regions); + + if (newIssuePosition) { + setExpandedIssue(null); + const element = window.document.getElementById('cvat_canvas_issue_region_0'); + if (element) { + element.style.display = 'block'; + } + } + }, [newIssuePosition]); + + useEffect(() => { + const listener = (): void => scaleHandler(canvasInstance); + + canvasInstance.html().addEventListener('canvas.zoom', listener); + canvasInstance.html().addEventListener('canvas.fit', listener); + + return () => { + canvasInstance.html().removeEventListener('canvas.zoom', listener); + canvasInstance.html().removeEventListener('canvas.fit', listener); + }; + }, []); + + if (!canvasIsReady) { + return null; + } + + const { geometry } = canvasInstance; + for (const issue of frameIssues) { + if (issuesHidden) break; + const issueResolved = !!issue.resolver; + const offset = 15; + const translated = issue.position.map((coord: number): number => coord + geometry.offset); + const minX = Math.min(...translated.filter((_: number, idx: number): boolean => idx % 2 === 0)) + offset; + const minY = Math.min(...translated.filter((_: number, idx: number): boolean => idx % 2 !== 0)) + offset; + const { id } = issue; + const highlight = (): void => { + const element = window.document.getElementById(`cvat_canvas_issue_region_${id}`); + if (element) { + element.style.display = 'block'; + } + }; + + const blur = (): void => { + if (issueResolved) { + const element = window.document.getElementById(`cvat_canvas_issue_region_${id}`); + if (element) { + element.style.display = ''; + } + } + }; + + if (expandedIssue === id) { + issueDialogs.push( + { + setExpandedIssue(null); + }} + resolve={() => { + dispatch(resolveIssueAsync(issue.id)); + setExpandedIssue(null); + }} + reopen={() => { + dispatch(reopenIssueAsync(issue.id)); + }} + comment={(message: string) => { + dispatch(commentIssueAsync(issue.id, message)); + }} + />, + ); + } else if (issue.comments.length) { + issueLabels.push( + { + setExpandedIssue(id); + }} + />, + ); + } + } + + const translated = newIssuePosition ? newIssuePosition.map((coord: number): number => coord + geometry.offset) : []; + const createLeft = translated.length ? + Math.max(...translated.filter((_: number, idx: number): boolean => idx % 2 === 0)) : + null; + const createTop = translated.length ? + Math.min(...translated.filter((_: number, idx: number): boolean => idx % 2 !== 0)) : + null; + + return ( + <> + {createLeft !== null && createTop !== null && } + {issueDialogs} + {issueLabels} + + ); +} diff --git a/cvat-ui/src/components/annotation-page/review/styles.scss b/cvat-ui/src/components/annotation-page/review/styles.scss new file mode 100644 index 00000000..be2381c9 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/styles.scss @@ -0,0 +1,112 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +@import 'base.scss'; + +.cvat-create-issue-dialog { + position: absolute; + pointer-events: auto; + width: $grid-unit-size * 30; + padding: $grid-unit-size; + background: $background-color-2; + z-index: 100; + transform-origin: top left; + box-shadow: $box-shadow-base; + + button { + width: $grid-unit-size * 12; + } +} + +.cvat-hidden-issue-label { + position: absolute; + min-width: 8 * $grid-unit-size; + opacity: 0.8; + z-index: 100; + transition: none; + pointer-events: auto; + max-width: 16 * $grid-unit-size; + overflow: hidden; + text-overflow: ellipsis; + border-radius: 0; + transform-origin: top left; + + &:hover { + opacity: 1; + } +} + +.cvat-issue-dialog { + width: $grid-unit-size * 35; + position: absolute; + z-index: 100; + transition: none; + pointer-events: auto; + background: $background-color-2; + padding: $grid-unit-size; + transform-origin: top left; + box-shadow: $box-shadow-base; + border-radius: 0.5 * $grid-unit-size; + opacity: 0.95; + + .cvat-issue-dialog-chat { + > div { + width: 100%; + } + + .ant-comment { + user-select: auto; + padding: $grid-unit-size; + padding-bottom: 0; + + .ant-comment-content { + line-height: 14px; + } + + .ant-comment-avatar { + margin: 0; + } + } + + border-radius: 0.5 * $grid-unit-size; + background: $background-color-1; + padding: $grid-unit-size; + max-height: $grid-unit-size * 45; + overflow-y: auto; + width: 100%; + } + + .cvat-issue-dialog-input { + background: $background-color-1; + margin-top: $grid-unit-size; + } + + .cvat-issue-dialog-footer { + margin-top: $grid-unit-size; + } + + .ant-comment > .ant-comment-inner { + padding: 0; + } + + &:hover { + opacity: 1; + } +} + +.cvat-hidden-issue-indicator { + margin-right: $grid-unit-size; +} + +.cvat-hidden-issue-resolved-indicator { + @extend .cvat-hidden-issue-indicator; + + color: $ok-icon-color; +} + +.cvat-hidden-issue-unsolved-indicator { + @extend .cvat-hidden-issue-indicator; + + color: $danger-icon-color; +} diff --git a/cvat-ui/src/components/annotation-page/review/submit-review-modal.tsx b/cvat-ui/src/components/annotation-page/review/submit-review-modal.tsx new file mode 100644 index 00000000..7bbfeecf --- /dev/null +++ b/cvat-ui/src/components/annotation-page/review/submit-review-modal.tsx @@ -0,0 +1,149 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { useState, useEffect } from 'react'; +import { AnyAction } from 'redux'; +import { useSelector, useDispatch } from 'react-redux'; +import Text from 'antd/lib/typography/Text'; +import Title from 'antd/lib/typography/Title'; +import Modal from 'antd/lib/modal'; +import Radio, { RadioChangeEvent } from 'antd/lib/radio'; +import RadioButton from 'antd/lib/radio/radioButton'; +import Description from 'antd/lib/descriptions'; +import Rate from 'antd/lib/rate'; +import { Row, Col } from 'antd/lib/grid'; + +import UserSelector, { User } from 'components/task-page/user-selector'; +import { CombinedState, ReviewStatus } from 'reducers/interfaces'; +import { switchSubmitReviewDialog } from 'actions/annotation-actions'; +import { submitReviewAsync } from 'actions/review-actions'; +import { clamp } from 'utils/math'; +import { useHistory } from 'react-router'; + +function computeEstimatedQuality(reviewedStates: number, openedIssues: number): number { + if (reviewedStates === 0 && openedIssues === 0) { + return 5; // corner case + } + + const K = 2; // means how many reviewed states are equivalent to one issue + const quality = reviewedStates / (reviewedStates + K * openedIssues); + return clamp(+(5 * quality).toPrecision(2), 0, 5); +} + +export default function SubmitReviewModal(): JSX.Element | null { + const dispatch = useDispatch(); + const history = useHistory(); + const isVisible = useSelector((state: CombinedState): boolean => state.annotation.submitReviewDialogVisible); + const job = useSelector((state: CombinedState): any => state.annotation.job.instance); + const activeReview = useSelector((state: CombinedState): any => state.review.activeReview); + const reviewIsBeingSubmitted = useSelector((state: CombinedState): any => state.review.fetching.reviewId); + const numberOfIssues = useSelector((state: CombinedState): any => state.review.issues.length); + const [isSubmitting, setIsSubmitting] = useState(false); + const numberOfNewIssues = activeReview ? activeReview.issues.length : 0; + const reviewedFrames = activeReview ? activeReview.reviewedFrames.length : 0; + const reviewedStates = activeReview ? activeReview.reviewedStates.length : 0; + + const [reviewer, setReviewer] = useState(job.reviewer ? job.reviewer : null); + const [reviewStatus, setReviewStatus] = useState(ReviewStatus.ACCEPTED); + const [estimatedQuality, setEstimatedQuality] = useState(0); + + const close = (): AnyAction => dispatch(switchSubmitReviewDialog(false)); + const submitReview = (): void => { + activeReview.estimatedQuality = estimatedQuality; + activeReview.status = reviewStatus; + if (reviewStatus === ReviewStatus.REVIEW_FURTHER) { + activeReview.reviewer = reviewer; + } + dispatch(submitReviewAsync(activeReview)); + }; + + useEffect(() => { + setEstimatedQuality(computeEstimatedQuality(reviewedStates, numberOfNewIssues)); + }, [reviewedStates, numberOfNewIssues]); + useEffect(() => { + if (!isSubmitting && activeReview && activeReview.id === reviewIsBeingSubmitted) { + setIsSubmitting(true); + } else if (isSubmitting && reviewIsBeingSubmitted === null) { + setIsSubmitting(false); + close(); + history.push(`/tasks/${job.task.id}`); + } + }, [reviewIsBeingSubmitted, activeReview]); + + if (!isVisible) { + return null; + } + + return ( + + + + Submitting your review + + + + + + {estimatedQuality} + + {numberOfIssues} + {!!numberOfNewIssues && {` (+${numberOfNewIssues})`}} + + {reviewedFrames} + {reviewedStates} + + + + + + { + if (typeof event.target.value !== 'undefined') { + setReviewStatus(event.target.value); + } + }} + > + Accept + Review next + Reject + + {reviewStatus === ReviewStatus.REVIEW_FURTHER && ( + + + Reviewer: + + + + + + )} + + + { + if (typeof value !== 'undefined') { + setEstimatedQuality(value); + } + }} + /> + + + + + + + + ); +} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-context-menu.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-context-menu.tsx deleted file mode 100644 index 9293318f..00000000 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-context-menu.tsx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// -// SPDX-License-Identifier: MIT - -import React from 'react'; -import ReactDOM from 'react-dom'; - -import ObjectItemContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/object-item'; - -interface Props { - activatedStateID: number | null; - visible: boolean; - left: number; - top: number; -} - -export default function CanvasContextMenu(props: Props): JSX.Element | null { - const { - activatedStateID, - visible, - left, - top, - } = props; - - if (!visible || activatedStateID === null) { - return null; - } - - return ReactDOM.createPortal( -
    - -
    , - window.document.body, - ); -} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx index f6ffeb2a..ad894422 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx @@ -14,6 +14,7 @@ import CursorControl from './cursor-control'; import MoveControl from './move-control'; import FitControl from './fit-control'; import ResizeControl from './resize-control'; +import ToolsControl from './tools-control'; import DrawRectangleControl from './draw-rectangle-control'; import DrawPolygonControl from './draw-polygon-control'; import DrawPolylineControl from './draw-polyline-control'; @@ -82,9 +83,14 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { }, SWITCH_DRAW_MODE: (event: KeyboardEvent | undefined) => { preventDefault(event); - const drawing = [ActiveControl.DRAW_POINTS, ActiveControl.DRAW_POLYGON, - ActiveControl.DRAW_POLYLINE, ActiveControl.DRAW_RECTANGLE, - ActiveControl.DRAW_CUBOID].includes(activeControl); + const drawing = [ + ActiveControl.DRAW_POINTS, + ActiveControl.DRAW_POLYGON, + ActiveControl.DRAW_POLYLINE, + ActiveControl.DRAW_RECTANGLE, + ActiveControl.DRAW_CUBOID, + ActiveControl.AI_TOOLS, + ].includes(activeControl); if (!drawing) { canvasInstance.cancel(); @@ -97,6 +103,12 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { repeatDrawShape(); } } else { + if (activeControl === ActiveControl.AI_TOOLS) { + // separated API method + canvasInstance.interact({ enabled: false }); + return; + } + canvasInstance.draw({ enabled: false }); } }, @@ -154,11 +166,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { }; return ( - +
    - + - +
    diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx index e4f0ec15..9983fd6c 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import { CursorIcon } from 'icons'; @@ -17,23 +17,18 @@ interface Props { } function CursorControl(props: Props): JSX.Element { - const { - canvasInstance, - activeControl, - cursorShortkey, - } = props; + const { canvasInstance, activeControl, cursorShortkey } = props; return ( canvasInstance.cancel() - : undefined + className={ + activeControl === ActiveControl.CURSOR ? + 'cvat-active-canvas-control cvat-cursor-control' : + 'cvat-cursor-control' } + onClick={activeControl !== ActiveControl.CURSOR ? (): void => canvasInstance.cancel() : undefined} /> ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/dextr-plugin.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/dextr-plugin.tsx deleted file mode 100644 index e4ce5043..00000000 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/dextr-plugin.tsx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// -// SPDX-License-Identifier: MIT - -import React, { useState } from 'react'; -import { connect } from 'react-redux'; -import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; -import Tooltip from 'antd/lib/tooltip'; - -import { Canvas } from 'cvat-canvas-wrapper'; -import { CombinedState } from 'reducers/interfaces'; -import { activate as activatePlugin, deactivate as deactivatePlugin } from 'utils/dextr-utils'; - - -interface StateToProps { - pluginEnabled: boolean; - canvasInstance: Canvas; -} - -interface DispatchToProps { - activate(canvasInstance: Canvas): void; - deactivate(canvasInstance: Canvas): void; -} - -function mapStateToProps(state: CombinedState): StateToProps { - const { - plugins: { - list, - }, - annotation: { - canvas: { - instance: canvasInstance, - }, - }, - } = state; - - return { - canvasInstance, - pluginEnabled: list.DEXTR_SEGMENTATION, - }; -} - -function mapDispatchToProps(): DispatchToProps { - return { - activate(canvasInstance: Canvas): void { - activatePlugin(canvasInstance); - }, - deactivate(canvasInstance: Canvas): void { - deactivatePlugin(canvasInstance); - }, - }; -} - -function DEXTRPlugin(props: StateToProps & DispatchToProps): JSX.Element | null { - const { - pluginEnabled, - canvasInstance, - activate, - deactivate, - } = props; - const [pluginActivated, setActivated] = useState(false); - - return ( - pluginEnabled ? ( - - { - setActivated(event.target.checked); - if (event.target.checked) { - activate(canvasInstance); - } else { - deactivate(canvasInstance); - } - }} - > - Make AI polygon - - - ) : null - ); -} - -export default connect( - mapStateToProps, - mapDispatchToProps, -)(DEXTRPlugin); - -// TODO: Add dialog window with cancel button diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-cuboid-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-cuboid-control.tsx index b813a3aa..958b208b 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-cuboid-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-cuboid-control.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { ShapeType } from 'reducers/interfaces'; @@ -12,6 +12,7 @@ import { ShapeType } from 'reducers/interfaces'; import { CubeIcon } from 'icons'; import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -19,39 +20,37 @@ interface Props { } function DrawPolygonControl(props: Props): JSX.Element { - const { - canvasInstance, - isDrawing, - } = props; - - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; - - const dynamicIconProps = isDrawing ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.draw({ enabled: false }); - }, - } : {}; + const { canvasInstance, isDrawing } = props; + const CustomPopover = withVisibilityHandling(Popover, 'draw-cuboid'); + + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isDrawing ? + { + className: 'cvat-draw-cuboid-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.draw({ enabled: false }); + }, + } : + { + className: 'cvat-draw-cuboid-control', + }; return ( - - )} + content={} > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-points-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-points-control.tsx index e034956a..8127059d 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-points-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-points-control.tsx @@ -4,13 +4,14 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { PointIcon } from 'icons'; import { ShapeType } from 'reducers/interfaces'; import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -19,35 +20,36 @@ interface Props { function DrawPointsControl(props: Props): JSX.Element { const { canvasInstance, isDrawing } = props; - - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; - - const dynamicIconProps = isDrawing ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.draw({ enabled: false }); - }, - } : {}; + const CustomPopover = withVisibilityHandling(Popover, 'draw-points'); + + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isDrawing ? + { + className: 'cvat-draw-points-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.draw({ enabled: false }); + }, + } : + { + className: 'cvat-draw-points-control', + }; return ( - - )} + content={} > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polygon-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polygon-control.tsx index 3b80a54c..23f5e754 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polygon-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polygon-control.tsx @@ -4,13 +4,14 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { PolygonIcon } from 'icons'; import { ShapeType } from 'reducers/interfaces'; import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -19,35 +20,36 @@ interface Props { function DrawPolygonControl(props: Props): JSX.Element { const { canvasInstance, isDrawing } = props; - - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; - - const dynamicIconProps = isDrawing ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.draw({ enabled: false }); - }, - } : {}; + const CustomPopover = withVisibilityHandling(Popover, 'draw-polygon'); + + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isDrawing ? + { + className: 'cvat-draw-polygon-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.draw({ enabled: false }); + }, + } : + { + className: 'cvat-draw-polygon-control', + }; return ( - - )} + content={} > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polyline-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polyline-control.tsx index f09d26e6..2139ad4d 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polyline-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-polyline-control.tsx @@ -4,13 +4,14 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { PolylineIcon } from 'icons'; import { ShapeType } from 'reducers/interfaces'; import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -19,35 +20,36 @@ interface Props { function DrawPolylineControl(props: Props): JSX.Element { const { canvasInstance, isDrawing } = props; - - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; - - const dynamicIconProps = isDrawing ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.draw({ enabled: false }); - }, - } : {}; + const CustomPopover = withVisibilityHandling(Popover, 'draw-polyline'); + + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isDrawing ? + { + className: 'cvat-draw-polyline-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.draw({ enabled: false }); + }, + } : + { + className: 'cvat-draw-polyline-control', + }; return ( - - )} + content={} > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-rectangle-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-rectangle-control.tsx index 60e852b6..50efd518 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-rectangle-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-rectangle-control.tsx @@ -4,13 +4,14 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { RectangleIcon } from 'icons'; import { ShapeType } from 'reducers/interfaces'; import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -19,37 +20,36 @@ interface Props { function DrawRectangleControl(props: Props): JSX.Element { const { canvasInstance, isDrawing } = props; - - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; - - const dynamicIconProps = isDrawing ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.draw({ enabled: false }); - }, - } : {}; + const CustomPopover = withVisibilityHandling(Popover, 'draw-rectangle'); + + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isDrawing ? + { + className: 'cvat-draw-rectangle-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.draw({ enabled: false }); + }, + } : + { + className: 'cvat-draw-rectangle-control', + }; return ( - - )} + content={} > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx index 5edfc758..a8a7ff42 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx @@ -4,7 +4,6 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Select, { OptionProps } from 'antd/lib/select'; import Button from 'antd/lib/button'; import InputNumber from 'antd/lib/input-number'; import Radio, { RadioChangeEvent } from 'antd/lib/radio'; @@ -14,7 +13,7 @@ import Text from 'antd/lib/typography/Text'; import { RectDrawingMethod, CuboidDrawingMethod } from 'cvat-canvas-wrapper'; import { ShapeType } from 'reducers/interfaces'; import { clamp } from 'utils/math'; -import DEXTRPlugin from './dextr-plugin'; +import LabelSelector from 'components/label-selector/label-selector'; interface Props { shapeType: ShapeType; @@ -23,7 +22,7 @@ interface Props { rectDrawingMethod?: RectDrawingMethod; cuboidDrawingMethod?: CuboidDrawingMethod; numberOfPoints?: number; - selectedLabeID: number; + selectedLabelID: number; repeatShapeShortcut: string; onChangeLabel(value: string): void; onChangePoints(value: number | undefined): void; @@ -38,7 +37,7 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { labels, shapeType, minimumPoints, - selectedLabeID, + selectedLabelID, numberOfPoints, rectDrawingMethod, cuboidDrawingMethod, @@ -53,150 +52,107 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { return (
    - + {`Draw new ${shapeType}`} - + Label - + - + /> - { shapeType === ShapeType.POLYGON && } - { - shapeType === ShapeType.RECTANGLE && ( - <> - - - Drawing method - - - - - - - By 2 Points - - - By 4 Points - - - - - - ) - } - { - shapeType === ShapeType.CUBOID && ( - <> - - - Drawing method - - - - - - - From rectangle - - - By 4 Points - - - - - - ) - } - { - shapeType !== ShapeType.RECTANGLE && shapeType !== ShapeType.CUBOID && ( - - - Number of points: + {shapeType === ShapeType.RECTANGLE && ( + <> + + + Drawing method + + + + + + + By 2 Points + + + By 4 Points + + - - { - if (typeof (value) === 'number') { - onChangePoints(Math.floor( - clamp(value, minimumPoints, Number.MAX_SAFE_INTEGER), - )); - } else if (!value) { - onChangePoints(undefined); - } - }} - className='cvat-draw-shape-popover-points-selector' - min={minimumPoints} - value={numberOfPoints} - step={1} - /> + + + )} + {shapeType === ShapeType.CUBOID && ( + <> + + + Drawing method + + + + + + + From rectangle + + + By 4 Points + + - ) - } - + + )} + {shapeType !== ShapeType.RECTANGLE && shapeType !== ShapeType.CUBOID && ( + + + Number of points: + + + { + if (typeof value !== 'undefined') { + onChangePoints(Math.floor(clamp(+value, minimumPoints, Number.MAX_SAFE_INTEGER))); + } else if (!value) { + onChangePoints(undefined); + } + }} + className='cvat-draw-shape-popover-points-selector' + min={minimumPoints} + value={numberOfPoints} + step={1} + /> + + + )} + - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx index 0ad4e788..e8f10f29 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import { FitIcon } from 'icons'; @@ -14,13 +14,11 @@ interface Props { } function FitControl(props: Props): JSX.Element { - const { - canvasInstance, - } = props; + const { canvasInstance } = props; return ( - canvasInstance.fit()} /> + canvasInstance.fit()} /> ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx index 15cf9be1..fb05e3f9 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Tooltip from 'antd/lib/tooltip'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { GroupIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -19,22 +19,17 @@ interface Props { } function GroupControl(props: Props): JSX.Element { - const { - switchGroupShortcut, - resetGroupShortcut, - activeControl, - canvasInstance, - groupObjects, - } = props; + const { switchGroupShortcut, resetGroupShortcut, activeControl, canvasInstance, groupObjects } = props; - const dynamicIconProps = activeControl === ActiveControl.GROUP - ? { - className: 'cvat-active-canvas-control', + const dynamicIconProps = + activeControl === ActiveControl.GROUP ? { + className: 'cvat-group-control cvat-active-canvas-control', onClick: (): void => { canvasInstance.group({ enabled: false }); groupObjects(false); }, } : { + className: 'cvat-group-control', onClick: (): void => { canvasInstance.cancel(); canvasInstance.group({ enabled: true }); @@ -42,8 +37,8 @@ function GroupControl(props: Props): JSX.Element { }, }; - const title = `Group shapes/tracks ${switchGroupShortcut}.` - + ` Select and press ${resetGroupShortcut} to reset a group`; + const title = + `Group shapes/tracks ${switchGroupShortcut}.` + ` Select and press ${resetGroupShortcut} to reset a group`; return ( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx new file mode 100644 index 00000000..c9de255d --- /dev/null +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx @@ -0,0 +1,41 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { useState } from 'react'; +import Popover, { PopoverProps } from 'antd/lib/popover'; + +export default function withVisibilityHandling(WrappedComponent: typeof Popover, popoverType: string) { + return (props: PopoverProps): JSX.Element => { + const [initialized, setInitialized] = useState(false); + const [visible, setVisible] = useState(false); + let { overlayClassName } = props; + if (typeof overlayClassName !== 'string') overlayClassName = ''; + + overlayClassName += ` cvat-${popoverType}-popover`; + if (visible) { + overlayClassName += ` cvat-${popoverType}-popover-visible`; + } + + const callback = (event: Event): void => { + if ((event as AnimationEvent).animationName === 'antZoomBigIn') { + setVisible(true); + } + }; + + return ( + { + if (!_visible) setVisible(false); + if (!initialized) { + const self = window.document.getElementsByClassName(`cvat-${popoverType}-popover`)[0]; + self?.addEventListener('animationend', callback); + setInitialized(true); + } + }} + /> + ); + }; +} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx index 2ac9f432..b00c9eb5 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Tooltip from 'antd/lib/tooltip'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { MergeIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -18,21 +18,17 @@ interface Props { } function MergeControl(props: Props): JSX.Element { - const { - switchMergeShortcut, - activeControl, - canvasInstance, - mergeObjects, - } = props; + const { switchMergeShortcut, activeControl, canvasInstance, mergeObjects } = props; - const dynamicIconProps = activeControl === ActiveControl.MERGE - ? { - className: 'cvat-active-canvas-control', + const dynamicIconProps = + activeControl === ActiveControl.MERGE ? { + className: 'cvat-merge-control cvat-active-canvas-control', onClick: (): void => { canvasInstance.merge({ enabled: false }); mergeObjects(false); }, } : { + className: 'cvat-merge-control', onClick: (): void => { canvasInstance.cancel(); canvasInstance.merge({ enabled: true }); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx index 1a25f2bf..05b38556 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import { MoveIcon } from 'icons'; @@ -22,8 +22,11 @@ function MoveControl(props: Props): JSX.Element { { if (activeControl === ActiveControl.DRAG_CANVAS) { canvasInstance.dragCanvas(false); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx index beec7e02..47d216d7 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import { ZoomIcon } from 'icons'; @@ -16,17 +16,17 @@ interface Props { } function ResizeControl(props: Props): JSX.Element { - const { - activeControl, - canvasInstance, - } = props; + const { activeControl, canvasInstance } = props; return ( { if (activeControl === ActiveControl.ZOOM_CANVAS) { canvasInstance.zoomCanvas(false); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx index e5aa8691..380e6b55 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx @@ -3,13 +3,15 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import Popover from 'antd/lib/popover'; import { RotateIcon } from 'icons'; import { Rotation } from 'reducers/interfaces'; +import withVisibilityHandling from './handle-popover-visibility'; + interface Props { clockwiseShortcut: string; anticlockwiseShortcut: string; @@ -17,26 +19,30 @@ interface Props { } function RotateControl(props: Props): JSX.Element { - const { - anticlockwiseShortcut, - clockwiseShortcut, - rotateFrame, - } = props; + const { anticlockwiseShortcut, clockwiseShortcut, rotateFrame } = props; + const CustomPopover = withVisibilityHandling(Popover, 'rotate-canvas'); return ( - - + rotateFrame(Rotation.ANTICLOCKWISE90)} component={RotateIcon} /> - + rotateFrame(Rotation.CLOCKWISE90)} @@ -47,8 +53,8 @@ function RotateControl(props: Props): JSX.Element { )} trigger='hover' > - - + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-control.tsx index 0d580da7..fcc4ea39 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-control.tsx @@ -4,12 +4,13 @@ import React from 'react'; import Popover from 'antd/lib/popover'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { TagIcon } from 'icons'; import SetupTagPopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover'; +import withVisibilityHandling from './handle-popover-visibility'; interface Props { canvasInstance: Canvas; @@ -17,29 +18,21 @@ interface Props { } function SetupTagControl(props: Props): JSX.Element { - const { - isDrawing, - } = props; + const { isDrawing } = props; + const CustomPopover = withVisibilityHandling(Popover, 'setup-tag'); - const dynamcPopoverPros = isDrawing ? { - overlayStyle: { - display: 'none', - }, - } : {}; + const dynamcPopoverPros = isDrawing ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; return ( - - )} - > - - + }> + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx index 11c1c1f6..a0e31a60 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx @@ -4,67 +4,52 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Select from 'antd/lib/select'; import Button from 'antd/lib/button'; import Tooltip from 'antd/lib/tooltip'; import Text from 'antd/lib/typography/Text'; +import LabelSelector from 'components/label-selector/label-selector'; interface Props { labels: any[]; - selectedLabeID: number; + selectedLabelID: number; repeatShapeShortcut: string; onChangeLabel(value: string): void; - onSetup( - labelID: number, - ): void; + onSetup(labelID: number): void; } function SetupTagPopover(props: Props): JSX.Element { const { - labels, - selectedLabeID, - repeatShapeShortcut, - onChangeLabel, - onSetup, + labels, selectedLabelID, repeatShapeShortcut, onChangeLabel, onSetup, } = props; return ( -
    - +
    + - Setup tag + + Setup tag + - + Label - + - + /> - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx index e700d287..43625fd6 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Tooltip from 'antd/lib/tooltip'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import { SplitIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -19,26 +19,26 @@ interface Props { function SplitControl(props: Props): JSX.Element { const { - switchSplitShortcut, - activeControl, - canvasInstance, - splitTrack, + switchSplitShortcut, activeControl, canvasInstance, splitTrack, } = props; - const dynamicIconProps = activeControl === ActiveControl.SPLIT - ? { - className: 'cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.split({ enabled: false }); - splitTrack(false); - }, - } : { - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.split({ enabled: true }); - splitTrack(true); - }, - }; + const dynamicIconProps = + activeControl === ActiveControl.SPLIT ? + { + className: 'cvat-split-track-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.split({ enabled: false }); + splitTrack(false); + }, + } : + { + className: 'cvat-split-track-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.split({ enabled: true }); + splitTrack(true); + }, + }; return ( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/tools-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/tools-control.tsx new file mode 100644 index 00000000..28da997b --- /dev/null +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/tools-control.tsx @@ -0,0 +1,794 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { MutableRefObject } from 'react'; +import { connect } from 'react-redux'; +import Icon, { LoadingOutlined } from '@ant-design/icons'; +import Popover from 'antd/lib/popover'; +import Select from 'antd/lib/select'; +import Button from 'antd/lib/button'; +import Modal from 'antd/lib/modal'; +import Text from 'antd/lib/typography/Text'; +import Tabs from 'antd/lib/tabs'; +import { Row, Col } from 'antd/lib/grid'; +import notification from 'antd/lib/notification'; +import Progress from 'antd/lib/progress'; +import InputNumber from 'antd/lib/input-number'; + +import { AIToolsIcon } from 'icons'; +import { Canvas } from 'cvat-canvas-wrapper'; +import range from 'utils/range'; +import getCore from 'cvat-core-wrapper'; +import { + CombinedState, ActiveControl, Model, ObjectType, ShapeType, +} from 'reducers/interfaces'; +import { + interactWithCanvas, + fetchAnnotationsAsync, + updateAnnotationsAsync, + createAnnotationsAsync, +} from 'actions/annotation-actions'; +import { InteractionResult } from 'cvat-canvas/src/typescript/canvas'; +import DetectorRunner from 'components/model-runner-modal/detector-runner'; +import LabelSelector from 'components/label-selector/label-selector'; +import withVisibilityHandling from './handle-popover-visibility'; + +interface StateToProps { + canvasInstance: Canvas; + labels: any[]; + states: any[]; + activeLabelID: number; + jobInstance: any; + isActivated: boolean; + frame: number; + interactors: Model[]; + detectors: Model[]; + trackers: Model[]; + curZOrder: number; + aiToolsRef: MutableRefObject; +} + +interface DispatchToProps { + onInteractionStart(activeInteractor: Model, activeLabelID: number): void; + updateAnnotations(statesToUpdate: any[]): void; + createAnnotations(sessionInstance: any, frame: number, statesToCreate: any[]): void; + fetchAnnotations(): void; +} + +const core = getCore(); + +function mapStateToProps(state: CombinedState): StateToProps { + const { annotation } = state; + const { number: frame } = annotation.player.frame; + const { instance: jobInstance } = annotation.job; + const { instance: canvasInstance, activeControl } = annotation.canvas; + const { models } = state; + const { interactors, detectors, trackers } = models; + + return { + interactors, + detectors, + trackers, + isActivated: activeControl === ActiveControl.AI_TOOLS, + activeLabelID: annotation.drawing.activeLabelID, + labels: annotation.job.labels, + states: annotation.annotations.states, + canvasInstance, + jobInstance, + frame, + curZOrder: annotation.annotations.zLayer.cur, + aiToolsRef: annotation.aiToolsRef, + }; +} + +const mapDispatchToProps = { + onInteractionStart: interactWithCanvas, + updateAnnotations: updateAnnotationsAsync, + fetchAnnotations: fetchAnnotationsAsync, + createAnnotations: createAnnotationsAsync, +}; + +function convertShapesForInteractor(shapes: InteractionResult[]): number[][] { + const reducer = (acc: number[][], _: number, index: number, array: number[]): number[][] => { + if (!(index % 2)) { + // 0, 2, 4 + acc.push([array[index], array[index + 1]]); + } + return acc; + }; + + return shapes + .filter((shape: InteractionResult): boolean => shape.shapeType === 'points' && shape.button === 0) + .map((shape: InteractionResult): number[] => shape.points) + .flat() + .reduce(reducer, []); +} + +type Props = StateToProps & DispatchToProps; +interface State { + activeInteractor: Model | null; + activeLabelID: number; + interactiveStateID: number | null; + activeTracker: Model | null; + trackingProgress: number | null; + trackingFrames: number; + fetching: boolean; + mode: 'detection' | 'interaction' | 'tracking'; +} + +export class ToolsControlComponent extends React.PureComponent { + private interactionIsAborted: boolean; + + private interactionIsDone: boolean; + + public constructor(props: Props) { + super(props); + this.state = { + activeInteractor: props.interactors.length ? props.interactors[0] : null, + activeTracker: props.trackers.length ? props.trackers[0] : null, + activeLabelID: props.labels[0].id, + interactiveStateID: null, + trackingProgress: null, + trackingFrames: 10, + fetching: false, + mode: 'interaction', + }; + + this.interactionIsAborted = false; + this.interactionIsDone = false; + } + + public componentDidMount(): void { + const { canvasInstance, aiToolsRef } = this.props; + aiToolsRef.current = this; + canvasInstance.html().addEventListener('canvas.interacted', this.interactionListener); + canvasInstance.html().addEventListener('canvas.canceled', this.cancelListener); + } + + public componentDidUpdate(prevProps: Props): void { + const { isActivated } = this.props; + if (prevProps.isActivated && !isActivated) { + window.removeEventListener('contextmenu', this.contextmenuDisabler); + } else if (!prevProps.isActivated && isActivated) { + // reset flags when start interaction/tracking + this.interactionIsDone = false; + this.interactionIsAborted = false; + window.addEventListener('contextmenu', this.contextmenuDisabler); + } + } + + public componentWillUnmount(): void { + const { canvasInstance, aiToolsRef } = this.props; + aiToolsRef.current = undefined; + canvasInstance.html().removeEventListener('canvas.interacted', this.interactionListener); + canvasInstance.html().removeEventListener('canvas.canceled', this.cancelListener); + } + + private getInteractiveState(): any | null { + const { states } = this.props; + const { interactiveStateID } = this.state; + return states.filter((_state: any): boolean => _state.clientID === interactiveStateID)[0] || null; + } + + private contextmenuDisabler = (e: MouseEvent): void => { + if ( + e.target && + (e.target as Element).classList && + (e.target as Element).classList.toString().includes('ant-modal') + ) { + e.preventDefault(); + } + }; + + private cancelListener = async (): Promise => { + const { + isActivated, jobInstance, frame, fetchAnnotations, + } = this.props; + const { interactiveStateID, fetching } = this.state; + + if (isActivated) { + if (fetching && !this.interactionIsDone) { + // user pressed ESC + this.setState({ fetching: false }); + this.interactionIsAborted = true; + } + + if (interactiveStateID !== null) { + const state = this.getInteractiveState(); + this.setState({ interactiveStateID: null }); + await state.delete(frame); + fetchAnnotations(); + } + + await jobInstance.actions.freeze(false); + } + }; + + private onInteraction = async (e: Event): Promise => { + const { + frame, + labels, + curZOrder, + jobInstance, + isActivated, + activeLabelID, + fetchAnnotations, + updateAnnotations, + } = this.props; + const { activeInteractor, interactiveStateID, fetching } = this.state; + + try { + if (!isActivated) { + throw Error('Canvas raises event "canvas.interacted" when interaction with it is off'); + } + + if (fetching) { + this.interactionIsDone = (e as CustomEvent).detail.isDone; + return; + } + + const interactor = activeInteractor as Model; + + let result = []; + if ((e as CustomEvent).detail.shapesUpdated) { + this.setState({ fetching: true }); + try { + result = await core.lambda.call(jobInstance.task, interactor, { + frame, + points: convertShapesForInteractor((e as CustomEvent).detail.shapes), + }); + + if (this.interactionIsAborted) { + // while the server request + // user has cancelled interaction (for example pressed ESC) + return; + } + } finally { + this.setState({ fetching: false }); + } + } + + if (this.interactionIsDone) { + // while the server request, user has done interaction (for example pressed N) + const object = new core.classes.ObjectState({ + frame, + objectType: ObjectType.SHAPE, + label: labels.filter((label: any) => label.id === activeLabelID)[0], + shapeType: ShapeType.POLYGON, + points: result.flat(), + occluded: false, + zOrder: curZOrder, + }); + + await jobInstance.annotations.put([object]); + fetchAnnotations(); + } else { + // no shape yet, then create it and save to collection + if (interactiveStateID === null) { + // freeze history for interaction time + // (points updating shouldn't cause adding new actions to history) + await jobInstance.actions.freeze(true); + const object = new core.classes.ObjectState({ + frame, + objectType: ObjectType.SHAPE, + label: labels.filter((label: any) => label.id === activeLabelID)[0], + shapeType: ShapeType.POLYGON, + points: result.flat(), + occluded: false, + zOrder: curZOrder, + }); + // need a clientID of a created object to interact with it further + // so, we do not use createAnnotationAction + const [clientID] = await jobInstance.annotations.put([object]); + + // update annotations on a canvas + fetchAnnotations(); + this.setState({ interactiveStateID: clientID }); + return; + } + + const state = this.getInteractiveState(); + if ((e as CustomEvent).detail.isDone) { + const finalObject = new core.classes.ObjectState({ + frame: state.frame, + objectType: state.objectType, + label: state.label, + shapeType: state.shapeType, + points: result.length ? result.flat() : state.points, + occluded: state.occluded, + zOrder: state.zOrder, + }); + this.setState({ interactiveStateID: null }); + await state.delete(frame); + await jobInstance.actions.freeze(false); + await jobInstance.annotations.put([finalObject]); + fetchAnnotations(); + } else { + state.points = result.flat(); + updateAnnotations([state]); + fetchAnnotations(); + } + } + } catch (err) { + notification.error({ + description: err.toString(), + message: 'Interaction error occured', + }); + } + }; + + private onTracking = async (e: Event): Promise => { + const { + isActivated, jobInstance, frame, curZOrder, fetchAnnotations, + } = this.props; + const { activeLabelID } = this.state; + const [label] = jobInstance.task.labels.filter((_label: any): boolean => _label.id === activeLabelID); + + if (!(e as CustomEvent).detail.isDone) { + return; + } + + this.interactionIsDone = true; + try { + if (!isActivated) { + throw Error('Canvas raises event "canvas.interacted" when interaction with it is off'); + } + + const { points } = (e as CustomEvent).detail.shapes[0]; + const state = new core.classes.ObjectState({ + shapeType: ShapeType.RECTANGLE, + objectType: ObjectType.TRACK, + zOrder: curZOrder, + label, + points, + frame, + occluded: false, + source: 'auto', + attributes: {}, + }); + + const [clientID] = await jobInstance.annotations.put([state]); + + // update annotations on a canvas + fetchAnnotations(); + + const states = await jobInstance.annotations.get(frame); + const [objectState] = states.filter((_state: any): boolean => _state.clientID === clientID); + await this.trackState(objectState); + } catch (err) { + notification.error({ + description: err.toString(), + message: 'Tracking error occured', + }); + } + }; + + private interactionListener = async (e: Event): Promise => { + const { mode } = this.state; + + if (mode === 'interaction') { + await this.onInteraction(e); + } + + if (mode === 'tracking') { + await this.onTracking(e); + } + }; + + private setActiveInteractor = (value: string): void => { + const { interactors } = this.props; + this.setState({ + activeInteractor: interactors.filter((interactor: Model) => interactor.id === value)[0], + }); + }; + + private setActiveTracker = (value: string): void => { + const { trackers } = this.props; + this.setState({ + activeTracker: trackers.filter((tracker: Model) => tracker.id === value)[0], + }); + }; + + public async trackState(state: any): Promise { + const { jobInstance, frame } = this.props; + const { activeTracker, trackingFrames } = this.state; + const { clientID, points } = state; + + const tracker = activeTracker as Model; + try { + this.setState({ trackingProgress: 0, fetching: true }); + let response = await core.lambda.call(jobInstance.task, tracker, { + task: jobInstance.task, + frame, + shape: points, + }); + + for (const offset of range(1, trackingFrames + 1)) { + /* eslint-disable no-await-in-loop */ + const states = await jobInstance.annotations.get(frame + offset); + const [objectState] = states.filter((_state: any): boolean => _state.clientID === clientID); + response = await core.lambda.call(jobInstance.task, tracker, { + task: jobInstance.task, + frame: frame + offset, + shape: response.points, + state: response.state, + }); + + const reduced = response.shape.reduce( + (acc: number[], value: number, index: number): number[] => { + if (index % 2) { + // y + acc[1] = Math.min(acc[1], value); + acc[3] = Math.max(acc[3], value); + } else { + // x + acc[0] = Math.min(acc[0], value); + acc[2] = Math.max(acc[2], value); + } + return acc; + }, + [ + Number.MAX_SAFE_INTEGER, + Number.MAX_SAFE_INTEGER, + Number.MIN_SAFE_INTEGER, + Number.MIN_SAFE_INTEGER, + ], + ); + + objectState.points = reduced; + await objectState.save(); + + this.setState({ trackingProgress: offset / trackingFrames }); + } + } finally { + this.setState({ trackingProgress: null, fetching: false }); + } + } + + public trackingAvailable(): boolean { + const { activeTracker, trackingFrames } = this.state; + const { trackers } = this.props; + + return !!trackingFrames && !!trackers.length && activeTracker !== null; + } + + private renderLabelBlock(): JSX.Element { + const { labels } = this.props; + const { activeLabelID } = this.state; + return ( + <> + + + Label + + + + + this.setState({ activeLabelID: value.id })} + /> + + + + ); + } + + private renderTrackerBlock(): JSX.Element { + const { + trackers, canvasInstance, jobInstance, frame, onInteractionStart, + } = this.props; + const { + activeTracker, activeLabelID, fetching, trackingFrames, + } = this.state; + + if (!trackers.length) { + return ( + + + + No available trackers found + + + + ); + } + + return ( + <> + + + Tracker + + + + + + + + + + Tracking frames + + + { + if (typeof value !== 'undefined') { + this.setState({ + trackingFrames: +value, + }); + } + }} + /> + + + + + + + + + ); + } + + private renderInteractorBlock(): JSX.Element { + const { interactors, canvasInstance, onInteractionStart } = this.props; + const { activeInteractor, activeLabelID, fetching } = this.state; + + if (!interactors.length) { + return ( + + + + No available interactors found + + + + ); + } + + return ( + <> + + + Interactor + + + + + + + + + + + + + + ); + } + + private renderDetectorBlock(): JSX.Element { + const { + jobInstance, detectors, curZOrder, frame, fetchAnnotations, + } = this.props; + + if (!detectors.length) { + return ( + + + + No available detectors found + + + + ); + } + + return ( + { + try { + this.setState({ + mode: 'detection', + }); + + this.setState({ fetching: true }); + const result = await core.lambda.call(task, model, { + ...body, + frame, + }); + + const states = result.map( + (data: any): any => + new core.classes.ObjectState({ + shapeType: data.type, + label: task.labels.filter((label: any): boolean => label.name === data.label)[0], + points: data.points, + objectType: ObjectType.SHAPE, + frame, + occluded: false, + source: 'auto', + attributes: {}, + zOrder: curZOrder, + }), + ); + + await jobInstance.annotations.put(states); + fetchAnnotations(); + } catch (error) { + notification.error({ + description: error.toString(), + message: 'Detection error occured', + }); + } finally { + this.setState({ fetching: false }); + } + }} + /> + ); + } + + private renderPopoverContent(): JSX.Element { + return ( +
    + + + + AI Tools + + + + + + {this.renderLabelBlock()} + {this.renderInteractorBlock()} + + + {this.renderDetectorBlock()} + + + {this.renderLabelBlock()} + {this.renderTrackerBlock()} + + +
    + ); + } + + public render(): JSX.Element | null { + const { + interactors, detectors, trackers, isActivated, canvasInstance, + } = this.props; + const { fetching, trackingProgress } = this.state; + + if (![...interactors, ...detectors, ...trackers].length) return null; + const CustomPopover = withVisibilityHandling(Popover, 'tools-control'); + + const dynamcPopoverPros = isActivated ? + { + overlayStyle: { + display: 'none', + }, + } : + {}; + + const dynamicIconProps = isActivated ? + { + className: 'cvat-active-canvas-control cvat-tools-control', + onClick: (): void => { + canvasInstance.interact({ enabled: false }); + }, + } : + { + className: 'cvat-tools-control', + }; + + return ( + <> + + Waiting for a server response.. + + {trackingProgress !== null && ( + + )} + + + + + + ); + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(ToolsControlComponent); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx index 8247749c..e877af6c 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx @@ -3,7 +3,8 @@ // SPDX-License-Identifier: MIT import React, { useState } from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; + +import { CloseOutlined } from '@ant-design/icons'; import Button from 'antd/lib/button'; import Popover from 'antd/lib/popover'; import Text from 'antd/lib/typography/Text'; @@ -21,18 +22,24 @@ interface Props { resetVisible?: boolean; onChange?: (value: string) => void; onVisibleChange?: (visible: boolean) => void; - placement?: 'left' | 'top' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom' | undefined; + placement?: + | 'left' + | 'top' + | 'right' + | 'bottom' + | 'topLeft' + | 'topRight' + | 'bottomLeft' + | 'bottomRight' + | 'leftTop' + | 'leftBottom' + | 'rightTop' + | 'rightBottom'; } function ColorPicker(props: Props, ref: React.Ref): JSX.Element { const { - children, - value, - visible, - resetVisible, - onChange, - onVisibleChange, - placement, + children, value, visible, resetVisible, onChange, onVisibleChange, placement, } = props; const [colorState, setColorState] = useState(value); @@ -96,11 +103,9 @@ function ColorPicker(props: Props, ref: React.Ref): JSX.Element { )} title={( - + - - Select color - + Select color @@ -110,12 +115,11 @@ function ColorPicker(props: Props, ref: React.Ref): JSX.Element { changeVisible(false); }} > - + - )} placement={placement || 'left'} overlayClassName='cvat-label-color-picker' diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx new file mode 100644 index 00000000..31a65ad2 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx @@ -0,0 +1,126 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { CombinedState } from 'reducers/interfaces'; +import { + LeftOutlined, RightOutlined, EyeInvisibleFilled, EyeOutlined, +} from '@ant-design/icons'; +import Tooltip from 'antd/lib/tooltip'; +import Alert from 'antd/lib/alert'; +import { Row, Col } from 'antd/lib/grid'; + +import { changeFrameAsync } from 'actions/annotation-actions'; +import { reviewActions } from 'actions/review-actions'; + +export default function LabelsListComponent(): JSX.Element { + const dispatch = useDispatch(); + const tabContentHeight = useSelector((state: CombinedState) => state.annotation.tabContentHeight); + const frame = useSelector((state: CombinedState): number => state.annotation.player.frame.number); + const frameIssues = useSelector((state: CombinedState): any[] => state.review.frameIssues); + const issues = useSelector((state: CombinedState): any[] => state.review.issues); + const activeReview = useSelector((state: CombinedState): any => state.review.activeReview); + const issuesHidden = useSelector((state: CombinedState): any => state.review.issuesHidden); + const combinedIssues = activeReview ? issues.concat(activeReview.issues) : issues; + const frames = combinedIssues.map((issue: any): number => issue.frame).sort((a: number, b: number) => +a - +b); + const nearestLeft = frames.filter((_frame: number): boolean => _frame < frame).reverse()[0]; + const dinamicLeftProps: any = Number.isInteger(nearestLeft) ? + { + onClick: () => dispatch(changeFrameAsync(nearestLeft)), + } : + { + style: { + pointerEvents: 'none', + opacity: 0.5, + }, + }; + + const nearestRight = frames.filter((_frame: number): boolean => _frame > frame)[0]; + const dinamicRightProps: any = Number.isInteger(nearestRight) ? + { + onClick: () => dispatch(changeFrameAsync(nearestRight)), + } : + { + style: { + pointerEvents: 'none', + opacity: 0.5, + }, + }; + + return ( +
    +
    + + + + + + + + + + + + + + {issuesHidden ? ( + dispatch(reviewActions.switchIssuesHiddenFlag(false))} + /> + ) : ( + dispatch(reviewActions.switchIssuesHiddenFlag(true))} + /> + )} + + + +
    +
    + {frameIssues.map( + (frameIssue: any): JSX.Element => ( +
    { + const element = window.document.getElementById( + `cvat_canvas_issue_region_${frameIssue.id}`, + ); + if (element) { + element.setAttribute('fill', 'url(#cvat_issue_region_pattern_2)'); + } + }} + onMouseLeave={() => { + const element = window.document.getElementById( + `cvat_canvas_issue_region_${frameIssue.id}`, + ); + if (element) { + element.setAttribute('fill', 'url(#cvat_issue_region_pattern_1)'); + } + }} + > + {frameIssue.resolver ? ( + {`By ${frameIssue.resolver.username}`}} + message='Resolved' + type='success' + showIcon + /> + ) : ( + {`By ${frameIssue.owner.username}`}} + message='Opened' + type='warning' + showIcon + /> + )} +
    + ), + )} +
    +
    + ); +} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx index e5067658..fc038b39 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx @@ -4,10 +4,11 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; import Button from 'antd/lib/button'; import Text from 'antd/lib/typography/Text'; - +import { + LockFilled, UnlockOutlined, EyeInvisibleFilled, EyeOutlined, +} from '@ant-design/icons'; interface Props { labelName: string; @@ -34,29 +35,47 @@ function LabelItemComponent(props: Props): JSX.Element { unlockStates, } = props; + const classes = { + lock: { + enabled: { className: 'cvat-label-item-button-lock cvat-label-item-button-lock-enabled' }, + disabled: { className: 'cvat-label-item-button-lock' }, + }, + hidden: { + enabled: { className: 'cvat-label-item-button-hidden cvat-label-item-button-hidden-enabled' }, + disabled: { className: 'cvat-label-item-button-hidden' }, + }, + }; + return ( - - {labelName} + + {labelName} + - { statesLocked - ? - : } + {statesLocked ? ( + + ) : ( + + )} - { statesHidden - ? - : } + {statesHidden ? ( + + ) : ( + + )} ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx index 10191bae..827ff3e7 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx @@ -12,18 +12,15 @@ interface Props { } export default function LabelsListComponent(props: Props): JSX.Element { - const { - listHeight, - labelIDs, - } = props; + const { listHeight, labelIDs } = props; return (
    - { - labelIDs.map((labelID: number): JSX.Element => ( + {labelIDs.map( + (labelID: number): JSX.Element => ( - )) - } + ), + )}
    ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-attribute.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-attribute.tsx index 29965919..1d4d8dc1 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-attribute.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-attribute.tsx @@ -15,6 +15,7 @@ import consts from 'consts'; import { clamp } from 'utils/math'; interface Props { + readonly: boolean; attrInputType: string; attrValues: string[]; attrValue: string; @@ -23,27 +24,22 @@ interface Props { changeAttribute(attrID: number, value: string): void; } -function attrIsTheSame( - prevProps: Props, - nextProps: Props, -): boolean { - return nextProps.attrID === prevProps.attrID - && nextProps.attrValue === prevProps.attrValue - && nextProps.attrName === prevProps.attrName - && nextProps.attrInputType === prevProps.attrInputType - && nextProps.attrValues +function attrIsTheSame(prevProps: Props, nextProps: Props): boolean { + return ( + nextProps.readonly === prevProps.readonly && + nextProps.attrID === prevProps.attrID && + nextProps.attrValue === prevProps.attrValue && + nextProps.attrName === prevProps.attrName && + nextProps.attrInputType === prevProps.attrInputType && + nextProps.attrValues .map((value: string, id: number): boolean => prevProps.attrValues[id] === value) - .every((value: boolean): boolean => value); + .every((value: boolean): boolean => value) + ); } function ItemAttributeComponent(props: Props): JSX.Element { const { - attrInputType, - attrValues, - attrValue, - attrName, - attrID, - changeAttribute, + attrInputType, attrValues, attrValue, attrName, attrID, readonly, changeAttribute, } = props; const attrNameStyle: React.CSSProperties = { wordBreak: 'break-word', lineHeight: '1em' }; @@ -54,6 +50,7 @@ function ItemAttributeComponent(props: Props): JSX.Element { { const value = event.target.checked ? 'true' : 'false'; changeAttribute(attrID, value); @@ -72,21 +69,25 @@ function ItemAttributeComponent(props: Props): JSX.Element {
    - {attrName} + + {attrName} + { changeAttribute(attrID, event.target.value); }} > - { attrValues.map((value: string): JSX.Element => ( - - {value === consts.UNDEFINED_ATTRIBUTE_VALUE - ? consts.NO_BREAK_SPACE : value} - - )) } + {attrValues.map( + (value: string): JSX.Element => ( + + {value === consts.UNDEFINED_ATTRIBUTE_VALUE ? consts.NO_BREAK_SPACE : value} + + ), + )}
    @@ -97,12 +98,11 @@ function ItemAttributeComponent(props: Props): JSX.Element { return ( <> - - {attrName} - + {attrName} @@ -127,18 +128,15 @@ function ItemAttributeComponent(props: Props): JSX.Element { return ( <> - - {attrName} - + {attrName} { - if (typeof (value) === 'number') { - changeAttribute( - attrID, `${clamp(value, min, max)}`, - ); + onChange={(value: number | undefined | string): void => { + if (typeof value !== 'undefined') { + changeAttribute(attrID, `${clamp(+value, min, max)}`); } }} value={+attrValue} @@ -174,14 +172,13 @@ function ItemAttributeComponent(props: Props): JSX.Element { return ( <> - - {attrName} - + {attrName} ): void => { if (ref.current && ref.current.input) { setSelection({ diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx index bbfc0e03..8aa249ee 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx @@ -4,16 +4,17 @@ import React, { useState } from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; -import Select, { OptionProps } from 'antd/lib/select'; +import { MoreOutlined } from '@ant-design/icons'; import Dropdown from 'antd/lib/dropdown'; import Text from 'antd/lib/typography/Text'; import Tooltip from 'antd/lib/tooltip'; import { ObjectType, ShapeType, ColorBy } from 'reducers/interfaces'; +import LabelSelector from 'components/label-selector/label-selector'; import ItemMenu from './object-item-menu'; interface Props { + readonly: boolean; clientID: number; serverID: number | undefined; labelID: number; @@ -32,7 +33,7 @@ interface Props { toForegroundShortcut: string; removeShortcut: string; changeColor(color: string): void; - changeLabel(labelID: string): void; + changeLabel(label: any): void; copy(): void; remove(): void; propagate(): void; @@ -41,10 +42,12 @@ interface Props { toBackground(): void; toForeground(): void; resetCuboidPerspective(): void; + activateTracking(): void; } function ItemTopComponent(props: Props): JSX.Element { const { + readonly, clientID, serverID, labelID, @@ -72,6 +75,7 @@ function ItemTopComponent(props: Props): JSX.Element { toBackground, toForeground, resetCuboidPerspective, + activateTracking, } = props; const [menuVisible, setMenuVisible] = useState(false); @@ -90,34 +94,24 @@ function ItemTopComponent(props: Props): JSX.Element { }; return ( - + {clientID}
    - {type} + + {type} + - + className='cvat-objects-sidebar-state-item-label-selector' + /> @@ -126,6 +120,7 @@ function ItemTopComponent(props: Props): JSX.Element { onVisibleChange={changeMenuVisible} placement='bottomLeft' overlay={ItemMenu({ + readonly, serverID, locked, shapeType, @@ -150,9 +145,10 @@ function ItemTopComponent(props: Props): JSX.Element { toForeground, resetCuboidPerspective, changeColorPickerVisible, + activateTracking, })} > - +
    diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-buttons.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-buttons.tsx index f5c12697..ea7a046f 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-buttons.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-buttons.tsx @@ -4,19 +4,28 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; +import Icon, { + UnlockOutlined, + LockFilled, + TeamOutlined, + UserOutlined, + PushpinFilled, + PushpinOutlined, + EyeInvisibleFilled, + StarFilled, + SelectOutlined, + StarOutlined, + EyeOutlined, +} from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; +import { ObjectType, ShapeType } from 'reducers/interfaces'; import { - ObjectOutsideIcon, - FirstIcon, - LastIcon, - PreviousIcon, - NextIcon, + ObjectOutsideIcon, FirstIcon, LastIcon, PreviousIcon, NextIcon, } from 'icons'; -import { ObjectType, ShapeType } from 'reducers/interfaces'; interface Props { + readonly: boolean; objectType: ObjectType; shapeType: ShapeType; occluded: boolean; @@ -55,161 +64,234 @@ interface Props { show(): void; } -function ItemButtonsComponent(props: Props): JSX.Element { +const classes = { + firstKeyFrame: { className: 'cvat-object-item-button-first-keyframe' }, + prevKeyFrame: { className: 'cvat-object-item-button-prev-keyframe' }, + nextKeyFrame: { className: 'cvat-object-item-button-next-keyframe' }, + lastKeyFrame: { className: 'cvat-object-item-button-last-keyframe' }, + outside: { + enabled: { className: 'cvat-object-item-button-outside cvat-object-item-button-outside-enabled' }, + disabled: { className: 'cvat-object-item-button-outside' }, + }, + lock: { + enabled: { className: 'cvat-object-item-button-lock cvat-object-item-button-lock-enabled' }, + disabled: { className: 'cvat-object-item-button-lock' }, + }, + occluded: { + enabled: { className: 'cvat-object-item-button-occluded cvat-object-item-button-occluded-enabled' }, + disabled: { className: 'cvat-object-item-button-occluded' }, + }, + pinned: { + enabled: { className: 'cvat-object-item-button-pinned cvat-object-item-button-pinned-enabled' }, + disabled: { className: 'cvat-object-item-button-pinned' }, + }, + hidden: { + enabled: { className: 'cvat-object-item-button-hidden cvat-object-item-button-hidden-enabled' }, + disabled: { className: 'cvat-object-item-button-hidden' }, + }, + keyframe: { + enabled: { className: 'cvat-object-item-button-keyframe cvat-object-item-button-keyframe-enabled' }, + disabled: { className: 'cvat-object-item-button-keyframe' }, + }, +}; + +function NavigateFirstKeyframe(props: Props): JSX.Element { + const { navigateFirstKeyframe } = props; + return navigateFirstKeyframe ? ( + + ) : ( + + ); +} + +function NavigatePrevKeyframe(props: Props): JSX.Element { + const { prevKeyFrameShortcut, navigatePrevKeyframe } = props; + return navigatePrevKeyframe ? ( + + + + ) : ( + + ); +} + +function NavigateNextKeyframe(props: Props): JSX.Element { + const { navigateNextKeyframe, nextKeyFrameShortcut } = props; + return navigateNextKeyframe ? ( + + + + ) : ( + + ); +} + +function NavigateLastKeyframe(props: Props): JSX.Element { + const { navigateLastKeyframe } = props; + return navigateLastKeyframe ? ( + + ) : ( + + ); +} + +function SwitchLock(props: Props): JSX.Element { + const { + locked, switchLockShortcut, lock, unlock, + } = props; + return ( + + {locked ? ( + + ) : ( + + )} + + ); +} + +function SwitchOccluded(props: Props): JSX.Element { const { - objectType, - shapeType, - occluded, - outside, - locked, - pinned, - hidden, - keyframe, - outsideDisabled, - hiddenDisabled, - keyframeDisabled, - switchOccludedShortcut, - switchOutsideShortcut, - switchLockShortcut, - switchHiddenShortcut, - switchKeyFrameShortcut, - nextKeyFrameShortcut, - prevKeyFrameShortcut, + switchOccludedShortcut, occluded, unsetOccluded, setOccluded, + } = props; + return ( + + {occluded ? ( + + ) : ( + + )} + + ); +} + +function SwitchPinned(props: Props): JSX.Element { + const { pinned, pin, unpin } = props; + return ( + + {pinned ? ( + + ) : ( + + )} + + ); +} - navigateFirstKeyframe, - navigatePrevKeyframe, - navigateNextKeyframe, - navigateLastKeyframe, +function SwitchHidden(props: Props): JSX.Element { + const { + switchHiddenShortcut, hidden, hiddenDisabled, show, hide, + } = props; + const hiddenStyle = hiddenDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; + return ( + + ); +} - setOccluded, - unsetOccluded, - setOutside, - unsetOutside, - setKeyframe, - unsetKeyframe, - lock, - unlock, - pin, - unpin, - hide, - show, +function SwitchOutside(props: Props): JSX.Element { + const { + outside, switchOutsideShortcut, outsideDisabled, unsetOutside, setOutside, } = props; + const outsideStyle = outsideDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; + return ( + + {outside ? ( + + ) : ( + + )} + + ); +} - const outsideStyle = outsideDisabled ? { opacity: 0.5, pointerEvents: 'none' as 'none' } : {}; - const hiddenStyle = hiddenDisabled ? { opacity: 0.5, pointerEvents: 'none' as 'none' } : {}; - const keyframeStyle = keyframeDisabled ? { opacity: 0.5, pointerEvents: 'none' as 'none' } : {}; +function SwitchKeyframe(props: Props): JSX.Element { + const { + keyframe, switchKeyFrameShortcut, keyframeDisabled, unsetKeyframe, setKeyframe, + } = props; + const keyframeStyle = keyframeDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; + return ( + + {keyframe ? ( + + ) : ( + + )} + + ); +} +function ItemButtonsComponent(props: Props): JSX.Element { + const { readonly, objectType, shapeType } = props; if (objectType === ObjectType.TRACK) { return ( - + - + - { navigateFirstKeyframe - ? - : } + - { navigatePrevKeyframe - ? ( - - - - ) - : } + - { navigateNextKeyframe - ? ( - - - - ) - : } + - { navigateLastKeyframe - ? - : } + - - - - { outside - ? ( - - ) - : } - - - - - { locked - ? - : } - - - - - { occluded - ? - : } - - - - - - - - { keyframe - ? - : } - - - { - shapeType !== ShapeType.POINTS && ( + {!readonly && ( + + + + + + + + + + + + + + + + + {shapeType !== ShapeType.POINTS && ( - - { pinned - ? - : } - + - ) - } - + )} + + )} ); } + if (readonly) { + return
    ; + } + if (objectType === ObjectType.TAG) { return ( - + - + - - { locked - ? - : } - + @@ -218,41 +300,23 @@ function ItemButtonsComponent(props: Props): JSX.Element { } return ( - + - + - - { locked - ? - : } - + - - { occluded - ? - : } - + - + - { - shapeType !== ShapeType.POINTS && ( - - - { pinned - ? - : } - - - ) - } + {shapeType !== ShapeType.POINTS && ( + + + + )} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-details.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-details.tsx index f2e17d3b..9615d4bf 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-details.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-details.tsx @@ -9,6 +9,7 @@ import Collapse from 'antd/lib/collapse'; import ItemAttribute from './object-item-attribute'; interface Props { + readonly: boolean; collapsed: boolean; attributes: any[]; values: Record; @@ -16,37 +17,31 @@ interface Props { collapse(): void; } -export function attrValuesAreEqual( - next: Record, prev: Record, -): boolean { +export function attrValuesAreEqual(next: Record, prev: Record): boolean { const prevKeys = Object.keys(prev); const nextKeys = Object.keys(next); - return nextKeys.length === prevKeys.length - && nextKeys.map((key: string): boolean => prev[+key] === next[+key]) - .every((value: boolean) => value); + return ( + nextKeys.length === prevKeys.length && + nextKeys.map((key: string): boolean => prev[+key] === next[+key]).every((value: boolean) => value) + ); } -function attrAreTheSame( - prevProps: Props, - nextProps: Props, -): boolean { - return nextProps.collapsed === prevProps.collapsed - && nextProps.attributes === prevProps.attributes - && attrValuesAreEqual(nextProps.values, prevProps.values); +function attrAreTheSame(prevProps: Props, nextProps: Props): boolean { + return ( + nextProps.readonly === prevProps.readonly && + nextProps.collapsed === prevProps.collapsed && + nextProps.attributes === prevProps.attributes && + attrValuesAreEqual(nextProps.values, prevProps.values) + ); } function ItemAttributesComponent(props: Props): JSX.Element { const { - collapsed, - attributes, - values, - changeAttribute, - collapse, + collapsed, attributes, values, readonly, changeAttribute, collapse, } = props; - const sorted = [...attributes] - .sort((a: any, b: any): number => a.inputType.localeCompare(b.inputType)); + const sorted = [...attributes].sort((a: any, b: any): number => a.inputType.localeCompare(b.inputType)); return ( @@ -55,28 +50,27 @@ function ItemAttributesComponent(props: Props): JSX.Element { activeKey={collapsed ? [] : ['details']} onChange={collapse} > - Details} - key='details' - > - { sorted.map((attribute: any): JSX.Element => ( - - - - ))} + Details} key='details'> + {sorted.map( + (attribute: any): JSX.Element => ( + + + + ), + )} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx index 99db3b84..d27aa05b 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx @@ -3,22 +3,26 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Icon from 'antd/lib/icon'; import Menu from 'antd/lib/menu'; import Button from 'antd/lib/button'; import Modal from 'antd/lib/modal'; import Tooltip from 'antd/lib/tooltip'; - +import Icon, { + LinkOutlined, + CopyOutlined, + BlockOutlined, + GatewayOutlined, + RetweetOutlined, + DeleteOutlined, +} from '@ant-design/icons'; import { - BackgroundIcon, - ForegroundIcon, - ResetPerspectiveIcon, - ColorizeIcon, + BackgroundIcon, ForegroundIcon, ResetPerspectiveIcon, ColorizeIcon, } from 'icons'; import { ObjectType, ShapeType, ColorBy } from 'reducers/interfaces'; import ColorPicker from './color-picker'; interface Props { + readonly: boolean; serverID: number | undefined; locked: boolean; shapeType: ShapeType; @@ -33,143 +37,214 @@ interface Props { toBackgroundShortcut: string; toForegroundShortcut: string; removeShortcut: string; - changeColor: (value: string) => void; - copy: (() => void); - remove: (() => void); - propagate: (() => void); - createURL: (() => void); - switchOrientation: (() => void); - toBackground: (() => void); - toForeground: (() => void); - resetCuboidPerspective: (() => void); - changeColorPickerVisible: (visible: boolean) => void; + changeColor(value: string): void; + copy(): void; + remove(): void; + propagate(): void; + createURL(): void; + switchOrientation(): void; + toBackground(): void; + toForeground(): void; + resetCuboidPerspective(): void; + changeColorPickerVisible(visible: boolean): void; + activateTracking(): void; } -export default function ItemMenu(props: Props): JSX.Element { +interface ItemProps { + toolProps: Props; +} + +function CreateURLItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { serverID, createURL } = toolProps; + return ( + + + + ); +} + +function MakeCopyItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { copyShortcut, pasteShortcut, copy } = toolProps; + return ( + + + + + + ); +} + +function PropagateItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { propagateShortcut, propagate } = toolProps; + return ( + + + + + + ); +} + +function TrackingItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { activateTracking } = toolProps; + return ( + + + + + + ); +} + +function SwitchOrientationItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { switchOrientation } = toolProps; + return ( + + + + ); +} + +function ResetPerspectiveItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { resetCuboidPerspective } = toolProps; + return ( + + + + ); +} + +function ToBackgroundItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { toBackgroundShortcut, toBackground } = toolProps; + return ( + + + + + + ); +} + +function ToForegroundItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { toForegroundShortcut, toForeground } = toolProps; + return ( + + + + + + ); +} + +function SwitchColorItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; const { - serverID, - locked, - shapeType, - objectType, color, - colorBy, colorPickerVisible, changeColorShortcut, - copyShortcut, - pasteShortcut, - propagateShortcut, - toBackgroundShortcut, - toForegroundShortcut, - removeShortcut, + colorBy, changeColor, - copy, - remove, - propagate, - createURL, - switchOrientation, - toBackground, - toForeground, - resetCuboidPerspective, changeColorPickerVisible, + } = toolProps; + return ( + + + + + + + + ); +} + +function RemoveItem(props: ItemProps): JSX.Element { + const { toolProps, ...rest } = props; + const { removeShortcut, locked, remove } = toolProps; + return ( + + + + + + ); +} + +export default function ItemMenu(props: Props): JSX.Element { + const { + readonly, shapeType, objectType, colorBy, } = props; return ( - - - - - - - - - - - - - - { [ShapeType.POLYGON, ShapeType.POLYLINE, ShapeType.CUBOID].includes(shapeType) && ( - - - - )} - {shapeType === ShapeType.CUBOID && ( - - - + + {!readonly && } + {!readonly && } + {!readonly && objectType === ObjectType.TRACK && shapeType === ShapeType.RECTANGLE && ( + )} - {objectType !== ObjectType.TAG && ( - - - - - + {!readonly && [ShapeType.POLYGON, ShapeType.POLYLINE, ShapeType.CUBOID].includes(shapeType) && ( + )} - {objectType !== ObjectType.TAG && ( - - - - - - )} - {[ColorBy.INSTANCE, ColorBy.GROUP].includes(colorBy) && ( - - - - - - - - )} - - - - - + {!readonly && shapeType === ShapeType.CUBOID && } + {!readonly && objectType !== ObjectType.TAG && } + {!readonly && objectType !== ObjectType.TAG && } + {[ColorBy.INSTANCE, ColorBy.GROUP].includes(colorBy) && } + {!readonly && } ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx index ce2e7a99..578e239f 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx @@ -5,17 +5,13 @@ import React from 'react'; import ObjectButtonsContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/object-buttons'; -import { - ObjectType, - ShapeType, - ColorBy, -} from 'reducers/interfaces'; +import { ObjectType, ShapeType, ColorBy } from 'reducers/interfaces'; import ItemDetails, { attrValuesAreEqual } from './object-item-details'; import ItemBasics from './object-item-basics'; - interface Props { normalizedKeyMap: Record; + readonly: boolean; activated: boolean; objectType: ObjectType; shapeType: ShapeType; @@ -39,33 +35,38 @@ interface Props { toBackground(): void; toForeground(): void; remove(): void; - changeLabel(labelID: string): void; + changeLabel(label: any): void; changeAttribute(attrID: number, value: string): void; changeColor(color: string): void; collapse(): void; resetCuboidPerspective(): void; + activateTracking(): void; } function objectItemsAreEqual(prevProps: Props, nextProps: Props): boolean { - return nextProps.activated === prevProps.activated - && nextProps.locked === prevProps.locked - && nextProps.labelID === prevProps.labelID - && nextProps.color === prevProps.color - && nextProps.clientID === prevProps.clientID - && nextProps.serverID === prevProps.serverID - && nextProps.objectType === prevProps.objectType - && nextProps.shapeType === prevProps.shapeType - && nextProps.collapsed === prevProps.collapsed - && nextProps.labels === prevProps.labels - && nextProps.attributes === prevProps.attributes - && nextProps.normalizedKeyMap === prevProps.normalizedKeyMap - && nextProps.colorBy === prevProps.colorBy - && attrValuesAreEqual(nextProps.attrValues, prevProps.attrValues); + return ( + nextProps.activated === prevProps.activated && + nextProps.readonly === prevProps.readonly && + nextProps.locked === prevProps.locked && + nextProps.labelID === prevProps.labelID && + nextProps.color === prevProps.color && + nextProps.clientID === prevProps.clientID && + nextProps.serverID === prevProps.serverID && + nextProps.objectType === prevProps.objectType && + nextProps.shapeType === prevProps.shapeType && + nextProps.collapsed === prevProps.collapsed && + nextProps.labels === prevProps.labels && + nextProps.attributes === prevProps.attributes && + nextProps.normalizedKeyMap === prevProps.normalizedKeyMap && + nextProps.colorBy === prevProps.colorBy && + attrValuesAreEqual(nextProps.attrValues, prevProps.attrValues) + ); } function ObjectItemComponent(props: Props): JSX.Element { const { activated, + readonly, objectType, shapeType, clientID, @@ -94,20 +95,21 @@ function ObjectItemComponent(props: Props): JSX.Element { changeColor, collapse, resetCuboidPerspective, + activateTracking, } = props; - const type = objectType === ObjectType.TAG ? ObjectType.TAG.toUpperCase() - : `${shapeType.toUpperCase()} ${objectType.toUpperCase()}`; + const type = + objectType === ObjectType.TAG ? + ObjectType.TAG.toUpperCase() : + `${shapeType.toUpperCase()} ${objectType.toUpperCase()}`; - const className = !activated ? 'cvat-objects-sidebar-state-item' - : 'cvat-objects-sidebar-state-item cvat-objects-sidebar-state-active-item'; + const className = !activated ? + 'cvat-objects-sidebar-state-item' : + 'cvat-objects-sidebar-state-item cvat-objects-sidebar-state-active-item'; return (
    -
    +
    - - { !!attributes.length - && ( - - )} + + {!!attributes.length && ( + + )}
    ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx index 4d9879f7..05c1272a 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx @@ -4,56 +4,22 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; -import Select from 'antd/lib/select'; -import Text from 'antd/lib/typography/Text'; +import { + LockFilled, + UnlockOutlined, + EyeInvisibleFilled, + EyeOutlined, + CaretDownOutlined, + CaretUpFilled, +} from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; import AnnotationsFiltersInput from 'components/annotation-page/annotations-filters-input'; +import StatesOrderingSelector from 'components/annotation-page/standard-workspace/objects-side-bar/states-ordering-selector'; import { StatesOrdering } from 'reducers/interfaces'; - -interface StatesOrderingSelectorComponentProps { - statesOrdering: StatesOrdering; - changeStatesOrdering(value: StatesOrdering): void; -} - -function StatesOrderingSelectorComponent(props: StatesOrderingSelectorComponentProps): JSX.Element { - const { - statesOrdering, - changeStatesOrdering, - } = props; - - return ( - - Sort by - - - ); -} - -const StatesOrderingSelector = React.memo(StatesOrderingSelectorComponent); - interface Props { + readonly: boolean; statesHidden: boolean; statesLocked: boolean; statesCollapsed: boolean; @@ -69,56 +35,70 @@ interface Props { showAllStates(): void; } -function ObjectListHeader(props: Props): JSX.Element { +function LockAllSwitcher(props: Props): JSX.Element { + const { + statesLocked, switchLockAllShortcut, unlockAllStates, lockAllStates, + } = props; + return ( + + + {statesLocked ? : } + + + ); +} + +function HideAllSwitcher(props: Props): JSX.Element { const { - statesHidden, - statesLocked, - statesCollapsed, - statesOrdering, - switchLockAllShortcut, - switchHiddenAllShortcut, - changeStatesOrdering, - lockAllStates, - unlockAllStates, - collapseAllStates, - expandAllStates, - hideAllStates, - showAllStates, + statesHidden, switchHiddenAllShortcut, showAllStates, hideAllStates, } = props; + return ( + + + + ); +} + +function CollapseAllSwitcher(props: Props): JSX.Element { + const { statesCollapsed, expandAllStates, collapseAllStates } = props; + return ( + + + {statesCollapsed ? ( + + ) : ( + + )} + + + ); +} + +function ObjectListHeader(props: Props): JSX.Element { + const { readonly, statesOrdering, changeStatesOrdering } = props; return (
    - + - - - - { statesLocked - ? - : } - - - - - - - - { statesCollapsed - ? - : } - - - + + {!readonly && ( + <> + + + + )} + +
    ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx index f91989ad..abacb02e 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx @@ -9,12 +9,14 @@ import ObjectItemContainer from 'containers/annotation-page/standard-workspace/o import ObjectListHeader from './objects-list-header'; interface Props { + readonly: boolean; listHeight: number; statesHidden: boolean; statesLocked: boolean; - statesCollapsed: boolean; + statesCollapsedAll: boolean; statesOrdering: StatesOrdering; sortedStatesID: number[]; + objectStates: any[]; switchLockAllShortcut: string; switchHiddenAllShortcut: string; changeStatesOrdering(value: StatesOrdering): void; @@ -28,12 +30,14 @@ interface Props { function ObjectListComponent(props: Props): JSX.Element { const { + readonly, listHeight, statesHidden, statesLocked, - statesCollapsed, + statesCollapsedAll, statesOrdering, sortedStatesID, + objectStates, switchLockAllShortcut, switchHiddenAllShortcut, changeStatesOrdering, @@ -48,9 +52,10 @@ function ObjectListComponent(props: Props): JSX.Element { return (
    - { sortedStatesID.map((id: number): JSX.Element => ( - - ))} + {sortedStatesID.map( + (id: number): JSX.Element => ( + + ), + )}
    ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar.tsx index f7928516..c5288a9b 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar.tsx @@ -3,23 +3,27 @@ // SPDX-License-Identifier: MIT import './styles.scss'; -import React, { Dispatch, useEffect } from 'react'; +import React, { Dispatch, useEffect, TransitionEvent } from 'react'; import { AnyAction } from 'redux'; import { connect } from 'react-redux'; +import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; import Text from 'antd/lib/typography/Text'; -import Icon from 'antd/lib/icon'; import Tabs from 'antd/lib/tabs'; import Layout from 'antd/lib/layout'; import { Canvas } from 'cvat-canvas-wrapper'; import { CombinedState } from 'reducers/interfaces'; -import ObjectsListContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/objects-list'; import LabelsListContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/labels-list'; import { collapseSidebar as collapseSidebarAction, updateTabContentHeight as updateTabContentHeightAction, } from 'actions/annotation-actions'; import AppearanceBlock, { computeHeight } from 'components/annotation-page/appearance-block'; +import IssuesListComponent from 'components/annotation-page/standard-workspace/objects-side-bar/issues-list'; + +interface OwnProps { + objectsList: JSX.Element; +} interface StateToProps { sidebarCollapsed: boolean; @@ -35,9 +39,7 @@ function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { sidebarCollapsed, - canvas: { - instance: canvasInstance, - }, + canvas: { instance: canvasInstance }, }, } = state; @@ -59,12 +61,9 @@ function mapDispatchToProps(dispatch: Dispatch): DispatchToProps { }; } -function ObjectsSideBar(props: StateToProps & DispatchToProps): JSX.Element { +function ObjectsSideBar(props: StateToProps & DispatchToProps & OwnProps): JSX.Element { const { - sidebarCollapsed, - canvasInstance, - collapseSidebar, - updateTabContentHeight, + sidebarCollapsed, canvasInstance, collapseSidebar, updateTabContentHeight, objectsList, } = props; useEffect(() => { @@ -82,22 +81,22 @@ function ObjectsSideBar(props: StateToProps & DispatchToProps): JSX.Element { }; }, []); - useEffect(() => { - const listener = (event: Event): void => { - if ((event as TransitionEvent).propertyName === 'width' - && ((event.target as any).classList as DOMTokenList).contains('ant-tabs-tab-prev')) { + const collapse = (): void => { + const [collapser] = window.document.getElementsByClassName('cvat-objects-sidebar'); + const listener = (event: TransitionEvent): void => { + if (event.target && event.propertyName === 'width' && event.target === collapser) { + canvasInstance.fitCanvas(); canvasInstance.fit(); + (collapser as HTMLElement).removeEventListener('transitionend', listener as any); } }; - const [sidebar] = window.document.getElementsByClassName('cvat-objects-sidebar'); - - sidebar.addEventListener('transitionstart', listener); + if (collapser) { + (collapser as HTMLElement).addEventListener('transitionend', listener as any); + } - return () => { - sidebar.removeEventListener('transitionstart', listener); - }; - }, []); + collapseSidebar(); + }; return ( - {sidebarCollapsed ? - : } + {sidebarCollapsed ? : } - Objects} - key='objects' - > - + Objects} key='objects'> + {objectsList} - Labels} - key='labels' - > + Labels} key='labels'> + Issues} key='issues'> + + - { !sidebarCollapsed && } + {!sidebarCollapsed && } ); } -export default connect( - mapStateToProps, - mapDispatchToProps, -)(React.memo(ObjectsSideBar)); +export default connect(mapStateToProps, mapDispatchToProps)(React.memo(ObjectsSideBar)); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/states-ordering-selector.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/states-ordering-selector.tsx new file mode 100644 index 00000000..a7a3a476 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/states-ordering-selector.tsx @@ -0,0 +1,43 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import { Col } from 'antd/lib/grid'; +import Select from 'antd/lib/select'; +import Text from 'antd/lib/typography/Text'; + +import { StatesOrdering } from 'reducers/interfaces'; + +interface StatesOrderingSelectorComponentProps { + statesOrdering: StatesOrdering; + changeStatesOrdering(value: StatesOrdering): void; +} + +function StatesOrderingSelectorComponent(props: StatesOrderingSelectorComponentProps): JSX.Element { + const { statesOrdering, changeStatesOrdering } = props; + + return ( + + Sort by + + + ); +} + +export default React.memo(StatesOrderingSelectorComponent); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss index 06f6e86e..b2c6f710 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss @@ -19,6 +19,10 @@ background: $header-color; border-radius: 0; height: 25px; + + .ant-collapse-arrow { + top: $grid-unit-size; + } } > .ant-collapse-content { @@ -48,7 +52,11 @@ box-sizing: border-box; border: none; - .ant-tabs-card-bar { + .ant-tabs-nav { + &::before { + content: none; + } + border: none; margin-bottom: 0; padding-top: 25px; @@ -68,6 +76,55 @@ } } +.cvat-objects-sidebar-issues-list-header { + background: $objects-bar-tabs-color; + padding: $grid-unit-size; + height: $grid-unit-size * 4; + box-sizing: border-box; + + > div > div { + > span[role='img'] { + font-size: 16px; + color: $objects-bar-icons-color; + + &:hover { + transform: scale(1.1); + opacity: 0.8; + } + + &:active { + transform: scale(1); + opacity: 0.7; + } + } + } +} + +.cvat-objects-sidebar-issues-list { + background-color: $background-color-2; + height: calc(100% - 32px); + overflow-y: auto; + overflow-x: hidden; +} + +.cvat-objects-sidebar-issue-item { + width: 100%; + margin: 1px; + padding: 2px; + + &:hover { + padding: 0; + + > .ant-alert { + border-width: 3px; + } + } + + > .ant-alert.ant-alert-with-description { + padding: $grid-unit-size $grid-unit-size $grid-unit-size $grid-unit-size * 8; + } +} + .cvat-objects-sidebar-states-header { background: $objects-bar-tabs-color; padding: 5px; @@ -78,21 +135,21 @@ } > div:nth-child(2) { - margin-top: 5px; + margin-top: $grid-unit-size; > div { text-align: center; margin: 0 2px; - > i { + > span[role='img'] { @extend .cvat-object-sidebar-icon; } - &:nth-child(4) { + &:last-child { text-align: right; - > .ant-select { - margin-left: 5px; + > .cvat-objects-sidebar-ordering-selector { + margin-left: $grid-unit-size; width: 60%; } } @@ -133,7 +190,7 @@ line-height: 12px; } - > div:nth-child(3) > i { + > div:nth-child(3) > span { @extend .cvat-object-sidebar-icon; font-size: 25px; @@ -149,7 +206,7 @@ margin-top: 5px; } - i { + span[role='img'] { @extend .cvat-object-sidebar-icon; } } @@ -167,6 +224,10 @@ background: inherit; padding-top: 2px; padding-bottom: 2px; + + .ant-collapse-arrow { + top: $grid-unit-size; + } } > .ant-collapse-content { @@ -232,10 +293,10 @@ .cvat-objects-sidebar-label-item { height: 2.5em; - border-bottom: 1px solid $border-color-2; + border-bottom: 1px solid $border-color-1; padding: 5px; - i { + span { @extend .cvat-object-sidebar-icon; } @@ -272,6 +333,12 @@ } } +.cvat-context-menu-item.ant-menu-item { + &:hover { + background: $hover-menu-color; + } +} + .cvat-object-item-menu { > li { padding: 0; @@ -289,3 +356,9 @@ .cvat-label-color-picker .sketch-picker { box-shadow: unset !important; } + +.cvat-states-ordering-selector { + :first-child { + margin-right: $grid-unit-size; + } +} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx index 66bebffa..1ac36d16 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx @@ -52,30 +52,24 @@ export default function PropagateConfirmComponent(props: Props): JSX.Element { size='small' min={minPropagateFrames} value={propagateFrames} - onChange={(value: number | undefined) => { - if (typeof (value) === 'number') { - changePropagateFrames(Math.floor( - clamp(value, minPropagateFrames, Number.MAX_SAFE_INTEGER), - )); + onChange={(value: number | undefined | string) => { + if (typeof value !== 'undefined') { + changePropagateFrames( + Math.floor(clamp(+value, minPropagateFrames, Number.MAX_SAFE_INTEGER)), + ); } }} /> - { - propagateFrames > 1 - ? frames - : frame - } + {propagateFrames > 1 ? frames : frame } up to the { - if (typeof (value) === 'number') { - changeUpToFrame(Math.floor( - clamp(value, frameNumber + 1, stopFrame), - )); + onChange={(value: number | undefined | string) => { + if (typeof value !== 'undefined') { + changeUpToFrame(Math.floor(clamp(+value, frameNumber + 1, stopFrame))); } }} /> diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/standard-workspace.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/standard-workspace.tsx index d57be1ec..75adab15 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/standard-workspace.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/standard-workspace.tsx @@ -6,22 +6,25 @@ import './styles.scss'; import React from 'react'; import Layout from 'antd/lib/layout'; -import CanvasWrapperContainer from 'containers/annotation-page/standard-workspace/canvas-wrapper'; +import CanvasWrapperContainer from 'containers/annotation-page/canvas/canvas-wrapper'; import ControlsSideBarContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar'; import PropagateConfirmContainer from 'containers/annotation-page/standard-workspace/propagate-confirm'; -import CanvasContextMenuContainer from 'containers/annotation-page/standard-workspace/canvas-context-menu'; +import CanvasContextMenuContainer from 'containers/annotation-page/canvas/canvas-context-menu'; +import ObjectsListContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/objects-list'; import ObjectSideBarComponent from 'components/annotation-page/standard-workspace/objects-side-bar/objects-side-bar'; -import CanvasPointContextMenuComponent from 'components/annotation-page/standard-workspace/canvas-point-context-menu'; +import CanvasPointContextMenuComponent from 'components/annotation-page/canvas/canvas-point-context-menu'; +import IssueAggregatorComponent from 'components/annotation-page/review/issues-aggregator'; export default function StandardWorkspaceComponent(): JSX.Element { return ( - + } /> + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss b/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss index a9514add..498a0dac 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss +++ b/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss @@ -8,10 +8,6 @@ height: 100%; } -.cvat-objects-sidebar-filter-input { - width: calc(100% - 35px); -} - .cvat-objects-sidebar-sider { top: 0; right: 0; @@ -34,26 +30,39 @@ .cvat-canvas-controls-sidebar { background-color: $background-color-2; border-right: 1px solid $border-color-1; +} - > div { - > i { - border-radius: 3.3px; - transform: scale(0.65); - padding: 2px; - - &:hover { - background: $header-color; - transform: scale(0.75); - } +.cvat-cursor-control, +.cvat-move-control, +.cvat-rotate-canvas-control, +.cvat-fit-control, +.cvat-resize-control, +.cvat-draw-rectangle-control, +.cvat-draw-polygon-control, +.cvat-draw-polyline-control, +.cvat-draw-points-control, +.cvat-draw-cuboid-control, +.cvat-setup-tag-control, +.cvat-merge-control, +.cvat-group-control, +.cvat-split-track-control, +.cvat-issue-control, +.cvat-tools-control { + border-radius: 3.3px; + transform: scale(0.65); + padding: 2px; - &:active { - transform: scale(0.65); - } + &:hover { + background: $header-color; + transform: scale(0.75); + } - > svg { - transform: scale(0.8); - } - } + &:active { + transform: scale(0.65); + } + + > svg { + transform: scale(0.8); } } @@ -76,24 +85,38 @@ } } -.cvat-rotate-canvas-controls > -.ant-popover-content > -.ant-popover-inner > div > -.ant-popover-inner-content { - padding: 0; +.cvat-rotate-canvas-popover { + .ant-popover-inner-content { + padding: 0; + } } -.cvat-draw-shape-popover > -.ant-popover-content > -.ant-popover-inner > div > -.ant-popover-inner-content { - padding: 0; +.cvat-draw-shape-popover, +.cvat-setup-tag-popover, +.cvat-tools-control-popover { + .ant-popover-inner-content { + padding: 0; + } +} + +.cvat-tools-track-button, +.cvat-tools-interact-button { + width: 100%; + margin-top: 10px; } .cvat-draw-shape-popover-points-selector { width: 100%; } +.cvat-tools-control-popover-content { + width: fit-content; + padding: 10px; + border-radius: 5px; + background: $background-color-2; +} + +.cvat-setup-tag-popover-content, .cvat-draw-shape-popover-content { padding: 10px; border-radius: 5px; diff --git a/cvat-ui/src/components/annotation-page/styles.scss b/cvat-ui/src/components/annotation-page/styles.scss index 4f7aaa8a..c14da8d9 100644 --- a/cvat-ui/src/components/annotation-page/styles.scss +++ b/cvat-ui/src/components/annotation-page/styles.scss @@ -6,6 +6,7 @@ .cvat-annotation-page.ant-layout { height: 100%; + overflow: hidden; } .ant-layout-header.cvat-annotation-header { @@ -37,21 +38,21 @@ align-items: center; margin: 0 3px; - > span { + > span:not([role='img']) { margin-left: 0; font-size: 10px; } - > i { + > span[role='img'] { transform: scale(0.8); padding: 3px; } - &:hover > i { + &:hover > span[role='img'] { transform: scale(0.85); } - &:active > i { + &:active > span[role='img'] { transform: scale(0.8); } @@ -80,7 +81,7 @@ height: 100%; margin-right: 10px; - > i { + > span { font-size: 25px; margin: 0 7px; color: $player-buttons-color; @@ -96,18 +97,17 @@ } .cvat-player-controls { - position: relative; height: 100%; line-height: 27px; > div { - position: relative; height: 50%; } } .cvat-player-slider { width: 350px; + margin: 0; > .ant-slider-rail { background-color: $player-slider-color; @@ -160,15 +160,6 @@ } > div:nth-child(1) { - > div { - > .ant-select, - i { - margin-left: 10px; - } - } - } - - > div:nth-child(2) { > div { > span { font-size: 20px; @@ -176,7 +167,7 @@ } } - > div:nth-child(3) { + > div:nth-child(2) { > div { display: grid; } @@ -204,7 +195,7 @@ } .ant-menu.cvat-annotation-menu { - box-shadow: 0 0 17px rgba(0, 0, 0, 0.2); + box-shadow: $box-shadow-base; > li:hover { background-color: $hover-menu-color; @@ -275,7 +266,7 @@ } } - > i { + > span[role='img'] { opacity: 0.7; color: $objects-bar-icons-color; @@ -300,3 +291,45 @@ } } } + +.cvat-player-previous-inlined-button, +.cvat-player-next-inlined-button, +.cvat-player-previous-filtered-inlined-button, +.cvat-player-next-filtered-inlined-button, +.cvat-player-previous-empty-inlined-button, +.cvat-player-next-empty-inlined-button { + color: $player-buttons-color; + + &:not(:first-child) { + margin-left: 12px; + } + + > svg { + transform: scale(1.8); + } +} + +.cvat-request-review-dialog { + > .ant-modal-content > .ant-modal-body { + > div:nth-child(2) { + margin-top: $grid-unit-size * 2; + } + + > div:nth-child(3) { + margin-top: $grid-unit-size * 2; + } + } +} + +.cvat-submit-review-dialog { + > .ant-modal-content > .ant-modal-body { + > div:nth-child(2) > div:nth-child(2) { + .ant-col { + > div:nth-child(2) { + margin-top: $grid-unit-size * 2; + margin-bottom: $grid-unit-size * 2; + } + } + } + } +} diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss index a647412a..0f15c968 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss @@ -12,7 +12,7 @@ background: $background-color-2; padding: 5px; - > div > .ant-row-flex > .ant-col > .ant-tag { + > div > .ant-row > .ant-col > .ant-tag { margin: 4px; } } @@ -33,7 +33,7 @@ } .cvat-tag-annotation-sidebar-buttons, -.cvat-tag-anntation-sidebar-checkbox-skip-frame { +.cvat-tag-annotation-sidebar-checkbox-skip-frame { padding-bottom: 15px; } diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx index 0955fb37..854f6f36 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx @@ -51,9 +51,10 @@ const ShortcutsSelect = (props: Props): JSX.Element => { setShortcutLabelMap(newShortcutLabelMap); }, []); - - Object.keys(shortcutLabelMap).map((id) => Number.parseInt(id, 10)) - .filter((id) => shortcutLabelMap[id]).forEach((id: number): void => { + Object.keys(shortcutLabelMap) + .map((id) => Number.parseInt(id, 10)) + .filter((id) => shortcutLabelMap[id]) + .forEach((id: number): void => { const [label] = labels.filter((_label) => _label.id === shortcutLabelMap[id]); const key = `SETUP_${id}_TAG`; keyMap[key] = { @@ -86,41 +87,32 @@ const ShortcutsSelect = (props: Props): JSX.Element => { Shortcuts for labels: - { - shift(Object.keys(shortcutLabelMap), 1).slice(0, Math.min(labels.length, 10)) - .map((id) => ( - - - {`Key ${id}:`} - { + onChangeShortcutLabel(value, Number.parseInt(id, 10)); + }} + style={{ width: 200 }} + className='cvat-tag-annotation-label-select' + > + + None + + {(labels as any[]).map((label: any) => ( + + {label.name} - { - (labels as any[]).map((label: any) => ( - - {label.name} - - )) - } - - - - )) - } + ))} + + + + ))}
    ); }; diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx index 4e6c5ae3..b67b07c4 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx @@ -8,12 +8,12 @@ import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; import { Action } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { Row, Col } from 'antd/lib/grid'; +import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; import Layout, { SiderProps } from 'antd/lib/layout'; +import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox/Checkbox'; import Button from 'antd/lib/button/button'; -import Icon from 'antd/lib/icon'; import Text from 'antd/lib/typography/Text'; -import Select from 'antd/lib/select'; -import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox/Checkbox'; +import Tag from 'antd/lib/tag'; import { createAnnotationsAsync, @@ -23,7 +23,7 @@ import { } from 'actions/annotation-actions'; import { Canvas } from 'cvat-canvas-wrapper'; import { CombinedState, ObjectType } from 'reducers/interfaces'; -import Tag from 'antd/lib/tag'; +import LabelSelector from 'components/label-selector/label-selector'; import getCore from 'cvat-core-wrapper'; import ShortcutsSelect from './shortcuts-select'; @@ -50,25 +50,13 @@ function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { player: { - frame: { - number: frameNumber, - }, - }, - annotations: { - states, + frame: { number: frameNumber }, }, - job: { - instance: jobInstance, - labels, - }, - canvas: { - instance: canvasInstance, - }, - }, - shortcuts: { - keyMap, - normalizedKeyMap, + annotations: { states }, + job: { instance: jobInstance, labels }, + canvas: { instance: canvasInstance }, }, + shortcuts: { keyMap, normalizedKeyMap }, } = state; return { @@ -123,7 +111,7 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [frameTags, setFrameTags] = useState([] as any[]); - const [selectedLabelID, setSelectedLabelID] = useState(defaultLabelID); + const [selectedLabelID, setSelectedLabelID] = useState(defaultLabelID); const [skipFrame, setSkipFrame] = useState(false); useEffect(() => { @@ -134,8 +122,10 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen useEffect(() => { const listener = (event: Event): void => { - if ((event as TransitionEvent).propertyName === 'width' - && ((event.target as any).classList as DOMTokenList).contains('cvat-tag-annotation-sidebar')) { + if ( + (event as TransitionEvent).propertyName === 'width' && + ((event.target as any).classList as DOMTokenList).contains('cvat-tag-annotation-sidebar') + ) { canvasInstance.fitCanvas(); canvasInstance.fit(); } @@ -151,9 +141,7 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen }, []); useEffect(() => { - setFrameTags(states.filter( - (objectState: any): boolean => objectState.objectType === ObjectType.TAG, - )); + setFrameTags(states.filter((objectState: any): boolean => objectState.objectType === ObjectType.TAG)); }, [states]); const siderProps: SiderProps = { @@ -167,8 +155,8 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen collapsed: sidebarCollapsed, }; - const onChangeLabel = (value: string): void => { - setSelectedLabelID(Number.parseInt(value, 10)); + const onChangeLabel = (value: any): void => { + setSelectedLabelID(value.id); }; const onRemoveState = (objectState: any): void => { @@ -219,32 +207,15 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen ant-layout-sider-zero-width-trigger-left`} onClick={() => setSidebarCollapsed(!sidebarCollapsed)} > - {sidebarCollapsed ? - : } + {sidebarCollapsed ? : } - + Tag label - + - + @@ -252,7 +223,7 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen - + - + Frame tags:  {frameTags.map((tag: any) => ( { onRemoveState(tag); }} + onClose={() => { + onRemoveState(tag); + }} key={tag.clientID} closable > @@ -284,7 +258,7 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen - + Use  @@ -304,7 +278,4 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen ); } -export default connect( - mapStateToProps, - mapDispatchToProps, -)(TagAnnotationSidebar); +export default connect(mapStateToProps, mapDispatchToProps)(TagAnnotationSidebar); diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-workspace.tsx b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-workspace.tsx index b08d1238..a3bb3907 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-workspace.tsx +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-workspace.tsx @@ -6,7 +6,7 @@ import './styles.scss'; import React from 'react'; import Layout from 'antd/lib/layout'; -import CanvasWrapperContainer from 'containers/annotation-page/standard-workspace/canvas-wrapper'; +import CanvasWrapperContainer from 'containers/annotation-page/canvas/canvas-wrapper'; import TagAnnotationSidebar from './tag-annotation-sidebar/tag-annotation-sidebar'; export default function TagAnnotationWorkspace(): JSX.Element { diff --git a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx index 02d3d748..6871ff29 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx @@ -3,8 +3,10 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Menu, { ClickParam } from 'antd/lib/menu'; +import Menu from 'antd/lib/menu'; import Modal from 'antd/lib/modal'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { MenuInfo } from 'rc-menu/lib/interface'; import DumpSubmenu from 'components/actions-menu/dump-submenu'; import LoadSubmenu from 'components/actions-menu/load-submenu'; @@ -17,8 +19,11 @@ interface Props { loadActivity: string | null; dumpActivities: string[] | null; exportActivities: string[] | null; - taskID: number; - onClickMenu(params: ClickParam, file?: File): void; + isReviewer: boolean; + jobInstance: any; + onClickMenu(params: MenuInfo, file?: File): void; + setForceExitAnnotationFlag(forceExit: boolean): void; + saveAnnotations(jobInstance: any, afterSave?: () => void): void; } export enum Actions { @@ -27,6 +32,10 @@ export enum Actions { EXPORT_TASK_DATASET = 'export_task_dataset', REMOVE_ANNO = 'remove_anno', OPEN_TASK = 'open_task', + REQUEST_REVIEW = 'request_review', + SUBMIT_REVIEW = 'submit_review', + FINISH_JOB = 'finish_job', + RENEW_JOB = 'renew_job', } export default function AnnotationMenuComponent(props: Props): JSX.Element { @@ -34,21 +43,55 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { taskMode, loaders, dumpers, - onClickMenu, loadActivity, dumpActivities, exportActivities, - taskID, + isReviewer, + jobInstance, + onClickMenu, + setForceExitAnnotationFlag, + saveAnnotations, } = props; - let latestParams: ClickParam | null = null; - function onClickMenuWrapper(params: ClickParam | null, file?: File): void { + const jobStatus = jobInstance.status; + const taskID = jobInstance.task.id; + + let latestParams: MenuInfo | null = null; + function onClickMenuWrapper(params: MenuInfo | null, file?: File): void { const copyParams = params || latestParams; if (!copyParams) { return; } latestParams = params; + function checkUnsavedChanges(_copyParams: MenuInfo): void { + if (jobInstance.annotations.hasUnsavedChanges()) { + Modal.confirm({ + title: 'The job has unsaved annotations', + content: 'Would you like to save changes before continue?', + className: 'cvat-modal-content-save-job', + okButtonProps: { + children: 'Save', + }, + cancelButtonProps: { + children: 'No', + }, + onOk: () => { + saveAnnotations(jobInstance, () => onClickMenu(_copyParams)); + }, + onCancel: () => { + // do not ask leave confirmation + setForceExitAnnotationFlag(true); + setTimeout(() => { + onClickMenu(_copyParams); + }); + }, + }); + } else { + onClickMenu(_copyParams); + } + } + if (copyParams.keyPath.length === 2) { const [, action] = copyParams.keyPath; if (action === Actions.LOAD_JOB_ANNO) { @@ -60,7 +103,8 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { onClickMenu(copyParams, file); }, okButtonProps: { - type: 'danger', + type: 'primary', + danger: true, }, okText: 'Update', }); @@ -70,17 +114,44 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { } } else if (copyParams.key === Actions.REMOVE_ANNO) { Modal.confirm({ - title: 'All annotations will be removed', - content: 'You are going to remove all annotations from the client. ' - + 'It will stay on the server till you save a job. Continue?', + title: 'All the annotations will be removed', + content: + 'You are going to remove all the annotations from the client. ' + + 'It will stay on the server till you save the job. Continue?', + className: 'cvat-modal-confirm-remove-annotation', onOk: () => { onClickMenu(copyParams); }, okButtonProps: { - type: 'danger', + type: 'primary', + danger: true, }, okText: 'Delete', }); + } else if ([Actions.REQUEST_REVIEW].includes(copyParams.key as Actions)) { + checkUnsavedChanges(copyParams); + } else if (copyParams.key === Actions.FINISH_JOB) { + Modal.confirm({ + title: 'The job status is going to be switched', + content: 'Status will be changed to "completed". Would you like to continue?', + okText: 'Continue', + cancelText: 'Cancel', + className: 'cvat-modal-content-finish-job', + onOk: () => { + checkUnsavedChanges(copyParams); + }, + }); + } else if (copyParams.key === Actions.RENEW_JOB) { + Modal.confirm({ + title: 'The job status is going to be switched', + content: 'Status will be changed to "annotations". Would you like to continue?', + okText: 'Continue', + cancelText: 'Cancel', + className: 'cvat-modal-content-renew-job', + onOk: () => { + onClickMenu(copyParams); + }, + }); } else { onClickMenu(copyParams); } @@ -88,40 +159,38 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { return ( - { - DumpSubmenu({ - taskMode, - dumpers, - dumpActivities, - menuKey: Actions.DUMP_TASK_ANNO, - }) - } - { - LoadSubmenu({ - loaders, - loadActivity, - onFileUpload: (file: File): void => { - onClickMenuWrapper(null, file); - }, - menuKey: Actions.LOAD_JOB_ANNO, - }) - } - { - ExportSubmenu({ - exporters: dumpers, - exportActivities, - menuKey: Actions.EXPORT_TASK_DATASET, - }) - } + {DumpSubmenu({ + taskMode, + dumpers, + dumpActivities, + menuKey: Actions.DUMP_TASK_ANNO, + })} + {LoadSubmenu({ + loaders, + loadActivity, + onFileUpload: (file: File): void => { + onClickMenuWrapper(null, file); + }, + menuKey: Actions.LOAD_JOB_ANNO, + })} + {ExportSubmenu({ + exporters: dumpers, + exportActivities, + menuKey: Actions.EXPORT_TASK_DATASET, + })} - - Remove annotations - + Remove annotations e.preventDefault()}> Open the task + {jobStatus === 'annotation' && Request a review} + {jobStatus === 'annotation' && Finish the job} + {jobStatus === 'validation' && isReviewer && ( + Submit the review + )} + {jobStatus === 'completed' && Renew the job} ); } diff --git a/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx b/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx index 536edc37..49d9e1ff 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx @@ -4,19 +4,14 @@ import React from 'react'; import { Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Modal from 'antd/lib/modal'; import Button from 'antd/lib/button'; import Timeline from 'antd/lib/timeline'; import Dropdown from 'antd/lib/dropdown'; import AnnotationMenuContainer from 'containers/annotation-page/top-bar/annotation-menu'; -import { - MainMenuIcon, - SaveIcon, - UndoIcon, - RedoIcon, -} from 'icons'; +import { MainMenuIcon, SaveIcon, UndoIcon, RedoIcon } from 'icons'; interface Props { saving: boolean; @@ -57,27 +52,15 @@ function LeftGroup(props: Props): JSX.Element { title={`Save current changes ${saveShortcut}`} onClick={saving ? undefined : onSaveAnnotation} type='link' - className={saving - ? 'cvat-annotation-disabled-header-button' - : 'cvat-annotation-header-button'} + className={saving ? 'cvat-annotation-disabled-header-button' : 'cvat-annotation-header-button'} > - { saving ? 'Saving...' : 'Save' } - + {saving ? 'Saving...' : 'Save'} + - { - savingStatuses.slice(0, -1) - .map(( - status: string, - id: number, - // eslint-disable-next-line react/no-array-index-key - ) => {status}) - } + {savingStatuses.slice(0, -1).map((status: string, id: number) => ( + {status} + ))} diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx index 1737c427..22ca7c97 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx @@ -5,16 +5,21 @@ import React from 'react'; import { Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Tooltip from 'antd/lib/tooltip'; +import Popover from 'antd/lib/popover'; import { FirstIcon, BackJumpIcon, PreviousIcon, + PreviousFilteredIcon, + PreviousEmptyIcon, PlayIcon, PauseIcon, NextIcon, + NextFilteredIcon, + NextEmptyIcon, ForwardJumpIcon, LastIcon, } from 'icons'; @@ -26,6 +31,8 @@ interface Props { previousFrameShortcut: string; forwardShortcut: string; backwardShortcut: string; + prevButtonType: string; + nextButtonType: string; onSwitchPlay(): void; onPrevFrame(): void; onNextFrame(): void; @@ -33,6 +40,8 @@ interface Props { onBackward(): void; onFirstFrame(): void; onLastFrame(): void; + setPrevButton(type: 'regular' | 'filtered' | 'empty'): void; + setNextButton(type: 'regular' | 'filtered' | 'empty'): void; } function PlayerButtons(props: Props): JSX.Element { @@ -43,6 +52,8 @@ function PlayerButtons(props: Props): JSX.Element { previousFrameShortcut, forwardShortcut, backwardShortcut, + prevButtonType, + nextButtonType, onSwitchPlay, onPrevFrame, onNextFrame, @@ -50,8 +61,47 @@ function PlayerButtons(props: Props): JSX.Element { onBackward, onFirstFrame, onLastFrame, + setPrevButton, + setNextButton, } = props; + const prevRegularText = 'Go back'; + const prevFilteredText = 'Go back with a filter'; + const prevEmptyText = 'Go back to an empty frame'; + const nextRegularText = 'Go next'; + const nextFilteredText = 'Go next with a filter'; + const nextEmptyText = 'Go next to an empty frame'; + + let prevButton = ; + let prevButtonTooltipMessage = prevRegularText; + if (prevButtonType === 'filtered') { + prevButton = ( + + ); + prevButtonTooltipMessage = prevFilteredText; + } else if (prevButtonType === 'empty') { + prevButton = ( + + ); + prevButtonTooltipMessage = prevEmptyText; + } + + let nextButton = ; + let nextButtonTooltipMessage = nextRegularText; + if (nextButtonType === 'filtered') { + nextButton = ( + + ); + nextButtonTooltipMessage = nextFilteredText; + } else if (nextButtonType === 'empty') { + nextButton = ; + nextButtonTooltipMessage = nextEmptyText; + } + return ( @@ -60,33 +110,99 @@ function PlayerButtons(props: Props): JSX.Element { - - - - - {!playing - ? ( - - - - ) - : ( - - - + + + { + setPrevButton('regular'); + }} + /> + + + { + setPrevButton('filtered'); + }} + /> + + + { + setPrevButton('empty'); + }} + /> + + )} + > + + {prevButton} + + - - - + {!playing ? ( + + + + ) : ( + + + + )} + + + + { + setNextButton('regular'); + }} + /> + + + { + setNextButton('filtered'); + }} + /> + + + { + setNextButton('empty'); + }} + /> + + + )} + > + + {nextButton} + + diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index f536b081..65ef5130 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -5,10 +5,11 @@ import React, { useState, useEffect } from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; -import Slider, { SliderValue } from 'antd/lib/slider'; +import { LinkOutlined } from '@ant-design/icons'; +import Slider from 'antd/lib/slider'; import Tooltip from 'antd/lib/tooltip'; import InputNumber from 'antd/lib/input-number'; +import Input from 'antd/lib/input'; import Text from 'antd/lib/typography/Text'; import { clamp } from 'utils/math'; @@ -19,8 +20,8 @@ interface Props { frameNumber: number; frameFilename: string; focusFrameInputShortcut: string; - inputFrameRef: React.RefObject; - onSliderChange(value: SliderValue): void; + inputFrameRef: React.RefObject; + onSliderChange(value: number): void; onInputChange(value: number): void; onURLIconClick(): void; } @@ -49,7 +50,7 @@ function PlayerNavigation(props: Props): JSX.Element { return ( <> - + - + {frameFilename} @@ -68,7 +69,7 @@ function PlayerNavigation(props: Props): JSX.Element { - + @@ -76,14 +77,13 @@ function PlayerNavigation(props: Props): JSX.Element { { - if (typeof (value) === 'number') { - setFrameInputValue(Math.floor( - clamp(value, startFrame, stopFrame), - )); + onChange={(value: number | undefined | string) => { + if (typeof value !== 'undefined') { + setFrameInputValue(Math.floor(clamp(+value, startFrame, stopFrame))); } }} onBlur={() => { @@ -92,7 +92,6 @@ function PlayerNavigation(props: Props): JSX.Element { onPressEnter={() => { onInputChange(frameInputValue); }} - ref={inputFrameRef} /> diff --git a/cvat-ui/src/components/annotation-page/top-bar/right-group.tsx b/cvat-ui/src/components/annotation-page/top-bar/right-group.tsx index 54c7723e..ac9be5b4 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/right-group.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/right-group.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; +import Icon from '@ant-design/icons'; import Select from 'antd/lib/select'; import Button from 'antd/lib/button'; @@ -44,6 +44,7 @@ function RightGroup(props: Props): JSX.Element {
    - annotation - validation - completed - - {savingJobStatus && } - - - + Overview - - - Assignee + + + + Assignee + {assignee} - - Start frame + + + Reviewer + + {reviewer} + + + + Start frame + {startFrame} - - Stop frame + + + Stop frame + {stopFrame} - - Frames - {stopFrame - startFrame + 1} - - Z-Order - {zOrder.toString()} + + Frames + + {stopFrame - startFrame + 1} - { !!bugTracker && ( - + {!!bugTracker && ( + - Bug tracker + + Bug tracker + {bugTracker} )} - + Annotations statistics - +
    diff --git a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx index 59464148..cbd0d693 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx @@ -5,8 +5,7 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import InputNumber from 'antd/lib/input-number'; -import { SliderValue } from 'antd/lib/slider'; +import Input from 'antd/lib/input'; import { Workspace } from 'reducers/interfaces'; import LeftGroup from './left-group'; @@ -20,7 +19,7 @@ interface Props { savingStatuses: string[]; frameNumber: number; frameFilename: string; - inputFrameRef: React.RefObject; + inputFrameRef: React.RefObject; startFrame: number; stopFrame: number; undoAction?: string; @@ -34,6 +33,8 @@ interface Props { previousFrameShortcut: string; forwardShortcut: string; backwardShortcut: string; + prevButtonType: string; + nextButtonType: string; focusFrameInputShortcut: string; changeWorkspace(workspace: Workspace): void; showStatistics(): void; @@ -45,7 +46,9 @@ interface Props { onBackward(): void; onFirstFrame(): void; onLastFrame(): void; - onSliderChange(value: SliderValue): void; + setPrevButtonType(type: 'regular' | 'filtered' | 'empty'): void; + setNextButtonType(type: 'regular' | 'filtered' | 'empty'): void; + onSliderChange(value: number): void; onInputChange(value: number): void; onURLIconClick(): void; onUndoClick(): void; @@ -73,6 +76,8 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element { previousFrameShortcut, forwardShortcut, backwardShortcut, + prevButtonType, + nextButtonType, focusFrameInputShortcut, showStatistics, changeWorkspace, @@ -84,6 +89,8 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element { onBackward, onFirstFrame, onLastFrame, + setPrevButtonType, + setNextButtonType, onSliderChange, onInputChange, onURLIconClick, @@ -92,7 +99,7 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element { } = props; return ( - + - + - + ); } diff --git a/cvat-ui/src/components/change-password-modal/change-password-form.tsx b/cvat-ui/src/components/change-password-modal/change-password-form.tsx index f1548daa..fc5a4b1a 100644 --- a/cvat-ui/src/components/change-password-modal/change-password-form.tsx +++ b/cvat-ui/src/components/change-password-modal/change-password-form.tsx @@ -3,12 +3,12 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import Form, { FormComponentProps } from 'antd/lib/form/Form'; +import Form from 'antd/lib/form'; +import { LockOutlined } from '@ant-design/icons'; import Button from 'antd/lib/button'; -import Icon from 'antd/lib/icon'; import Input from 'antd/lib/input'; -import patterns from 'utils/validation-patterns'; +import { validateConfirmation, validatePassword } from 'components/register-page/register-form'; export interface ChangePasswordData { oldPassword: string; @@ -16,151 +16,79 @@ export interface ChangePasswordData { newPassword2: string; } -type ChangePasswordFormProps = { +interface Props { fetching: boolean; onSubmit(loginData: ChangePasswordData): void; -} & FormComponentProps; - -class ChangePasswordFormComponent extends React.PureComponent { - private validateConfirmation = (_: any, value: string, callback: Function): void => { - const { form } = this.props; - if (value && value !== form.getFieldValue('newPassword1')) { - callback('Two passwords that you enter is inconsistent!'); - } else { - callback(); - } - }; - - private validatePassword = (_: any, value: string, callback: Function): void => { - const { form } = this.props; - if (!patterns.validatePasswordLength.pattern.test(value)) { - callback(patterns.validatePasswordLength.message); - } - - if (!patterns.passwordContainsNumericCharacters.pattern.test(value)) { - callback(patterns.passwordContainsNumericCharacters.message); - } - - if (!patterns.passwordContainsUpperCaseCharacter.pattern.test(value)) { - callback(patterns.passwordContainsUpperCaseCharacter.message); - } - - if (!patterns.passwordContainsLowerCaseCharacter.pattern.test(value)) { - callback(patterns.passwordContainsLowerCaseCharacter.message); - } - - if (value) { - form.validateFields(['newPassword2'], { force: true }); - } - callback(); - }; - - private handleSubmit = (e: React.FormEvent): void => { - e.preventDefault(); - const { - form, - onSubmit, - } = this.props; - - form.validateFields((error, values): void => { - if (!error) { - const validatedFields = { - ...values, - confirmations: [], - }; - - onSubmit(validatedFields); - } - }); - }; - - private renderOldPasswordField(): JSX.Element { - const { form } = this.props; +} - return ( - - {form.getFieldDecorator('oldPassword', { - rules: [{ +function ChangePasswordFormComponent({ fetching, onSubmit }: Props): JSX.Element { + return ( +
    + } + }, + ]} + > + } placeholder='Current password' - />)} + /> - ); - } - - private renderNewPasswordField(): JSX.Element { - const { form } = this.props; - return ( - - {form.getFieldDecorator('newPassword1', { - rules: [{ + + } + prefix={} placeholder='New password' - />)} + /> - ); - } - - private renderNewPasswordConfirmationField(): JSX.Element { - const { form } = this.props; - return ( - - {form.getFieldDecorator('newPassword2', { - rules: [{ + + } + prefix={} placeholder='Confirm new password' - />)} + /> - ); - } - - public render(): JSX.Element { - const { fetching } = this.props; - return ( - - {this.renderOldPasswordField()} - {this.renderNewPasswordField()} - {this.renderNewPasswordConfirmationField()} - - - - - - ); - } + + + + + ); } -export default Form.create()(ChangePasswordFormComponent); +export default React.memo(ChangePasswordFormComponent); diff --git a/cvat-ui/src/components/change-password-modal/change-password-modal.tsx b/cvat-ui/src/components/change-password-modal/change-password-modal.tsx index 2f4f538b..2b7b962d 100644 --- a/cvat-ui/src/components/change-password-modal/change-password-modal.tsx +++ b/cvat-ui/src/components/change-password-modal/change-password-modal.tsx @@ -11,17 +11,13 @@ import { changePasswordAsync } from 'actions/auth-actions'; import { CombinedState } from 'reducers/interfaces'; import ChangePasswordForm, { ChangePasswordData } from './change-password-form'; - interface StateToProps { fetching: boolean; visible: boolean; } interface DispatchToProps { - onChangePassword( - oldPassword: string, - newPassword1: string, - newPassword2: string): void; + onChangePassword(oldPassword: string, newPassword1: string, newPassword2: string): void; } interface ChangePasswordPageComponentProps { @@ -39,23 +35,19 @@ function mapStateToProps(state: CombinedState): StateToProps { } function mapDispatchToProps(dispatch: any): DispatchToProps { - return ({ + return { onChangePassword(oldPassword: string, newPassword1: string, newPassword2: string): void { dispatch(changePasswordAsync(oldPassword, newPassword1, newPassword2)); }, - }); + }; } function ChangePasswordComponent(props: ChangePasswordPageComponentProps): JSX.Element { - const { - fetching, - onChangePassword, - visible, - onClose, - } = props; + const { fetching, onChangePassword, visible, onClose } = props; return ( Change password} okType='primary' okText='Submit' @@ -78,7 +70,4 @@ function ChangePasswordComponent(props: ChangePasswordPageComponentProps): JSX.E ); } -export default connect( - mapStateToProps, - mapDispatchToProps, -)(ChangePasswordComponent); +export default connect(mapStateToProps, mapDispatchToProps)(ChangePasswordComponent); diff --git a/cvat-ui/src/components/create-project-page/create-project-content.tsx b/cvat-ui/src/components/create-project-page/create-project-content.tsx new file mode 100644 index 00000000..d67f5db5 --- /dev/null +++ b/cvat-ui/src/components/create-project-page/create-project-content.tsx @@ -0,0 +1,142 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { + useState, useRef, useEffect, RefObject, +} from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useHistory } from 'react-router'; +import { Col, Row } from 'antd/lib/grid'; +import Text from 'antd/lib/typography/Text'; +import Form, { FormInstance } from 'antd/lib/form'; +import Button from 'antd/lib/button'; +import Input from 'antd/lib/input'; +import notification from 'antd/lib/notification'; + +import patterns from 'utils/validation-patterns'; +import { CombinedState } from 'reducers/interfaces'; +import LabelsEditor from 'components/labels-editor/labels-editor'; +import { createProjectAsync } from 'actions/projects-actions'; + +function NameConfigurationForm({ formRef }: { formRef: RefObject }): JSX.Element { + return ( +
    + + + + + ); +} + +function AdvanvedConfigurationForm({ formRef }: { formRef: RefObject }): JSX.Element { + return ( +
    + { + if (value && !patterns.validateURL.pattern.test(value)) { + callback('Issue tracker must be URL'); + } else { + callback(); + } + }, + }, + ]} + > + + + + ); +} + +export default function CreateProjectContent(): JSX.Element { + const [projectLabels, setProjectLabels] = useState([]); + const shouldShowNotification = useRef(false); + const nameFormRef = useRef(null); + const advancedFormRef = useRef(null); + const dispatch = useDispatch(); + const history = useHistory(); + + const newProjectId = useSelector((state: CombinedState) => state.projects.activities.creates.id); + + useEffect(() => { + if (Number.isInteger(newProjectId) && shouldShowNotification.current) { + const btn = ; + + // Clear new project forms + if (nameFormRef.current) nameFormRef.current.resetFields(); + if (advancedFormRef.current) advancedFormRef.current.resetFields(); + setProjectLabels([]); + + notification.info({ + message: 'The project has been created', + btn, + }); + } + + shouldShowNotification.current = true; + }, [newProjectId]); + + const onSumbit = async (): Promise => { + interface Project { + [key: string]: any; + } + + const projectData: Project = {}; + if (nameFormRef.current && advancedFormRef.current) { + const basicValues = await nameFormRef.current.validateFields(); + const advancedValues = await advancedFormRef.current.validateFields(); + projectData.name = basicValues.name; + for (const [field, value] of Object.entries(advancedValues)) { + projectData[field] = value; + } + } + + projectData.labels = projectLabels; + + if (!projectData.name) return; + + dispatch(createProjectAsync(projectData)); + }; + + return ( + +
    + + + + Labels: + { + setProjectLabels(newLabels); + }} + /> + + + + + + + + + ); +} diff --git a/cvat-ui/src/components/create-project-page/create-project-page.tsx b/cvat-ui/src/components/create-project-page/create-project-page.tsx new file mode 100644 index 00000000..1156511e --- /dev/null +++ b/cvat-ui/src/components/create-project-page/create-project-page.tsx @@ -0,0 +1,21 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import './styles.scss'; +import React from 'react'; +import { Row, Col } from 'antd/lib/grid'; +import Text from 'antd/lib/typography/Text'; + +import CreateProjectContent from './create-project-content'; + +export default function CreateProjectPageComponent(): JSX.Element { + return ( + + + Create a new project + + + + ); +} diff --git a/cvat-ui/src/components/create-project-page/styles.scss b/cvat-ui/src/components/create-project-page/styles.scss new file mode 100644 index 00000000..a6fdbd4b --- /dev/null +++ b/cvat-ui/src/components/create-project-page/styles.scss @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +@import '../../base.scss'; + +.cvat-create-project-form-wrapper { + text-align: center; + padding-top: $grid-unit-size * 5; + overflow-y: auto; + height: 90%; + position: fixed; + width: 100%; + + > div > span { + font-size: $grid-unit-size * 4; + } +} + +.cvat-create-project-content { + margin-top: $grid-unit-size * 2; + width: 100%; + height: auto; + border: 1px solid $border-color-1; + border-radius: 3px; + padding: $grid-unit-size * 2; + background: $background-color-1; + text-align: initial; + + > div:not(first-child) { + margin-top: $grid-unit-size; + } + + > div:nth-child(4) { + display: flex; + justify-content: flex-end; + + > button { + width: $grid-unit-size * 15; + } + } +} diff --git a/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx b/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx index b60b16e3..804a8725 100644 --- a/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx +++ b/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx @@ -2,20 +2,20 @@ // // SPDX-License-Identifier: MIT -import React from 'react'; +import React, { RefObject } from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Icon from 'antd/lib/icon'; +import { PercentageOutlined } from '@ant-design/icons'; import Input from 'antd/lib/input'; import Checkbox from 'antd/lib/checkbox'; import Tooltip from 'antd/lib/tooltip'; -import Form, { FormComponentProps } from 'antd/lib/form/Form'; +import Form, { FormInstance, RuleObject, RuleRender } from 'antd/lib/form'; import Text from 'antd/lib/typography/Text'; import patterns from 'utils/validation-patterns'; +import { Store } from 'antd/lib/form/interface'; export interface AdvancedConfiguration { bugTracker?: string; - zOrder: boolean; imageQuality?: number; overlapSize?: number; segmentSize?: number; @@ -26,295 +26,252 @@ export interface AdvancedConfiguration { repository?: string; useZipChunks: boolean; dataChunkSize?: number; + useCache: boolean; + copyData?: boolean; } -type Props = FormComponentProps & { - onSubmit(values: AdvancedConfiguration): void; - installedGit: boolean; +const initialValues: AdvancedConfiguration = { + imageQuality: 70, + lfs: false, + useZipChunks: true, + useCache: true, + copyData: false, }; -function isPositiveInteger(_: any, value: any, callback: any): void { - if (!value) { - callback(); - return; - } +interface Props { + onSubmit(values: AdvancedConfiguration): void; + installedGit: boolean; + activeFileManagerTab: string; +} - const intValue = +value; - if (Number.isNaN(intValue) - || !Number.isInteger(intValue) || intValue < 1) { - callback('Value must be a positive integer'); +function validateURL(_: RuleObject, value: string): Promise { + if (value && !patterns.validateURL.pattern.test(value)) { + return Promise.reject(new Error('URL is not a valid URL')); } - callback(); + return Promise.resolve(); } -function isNonNegativeInteger(_: any, value: any, callback: any): void { - if (!value) { - callback(); - return; +function validateRepositoryPath(_: RuleObject, value: string): Promise { + if (value && !patterns.validatePath.pattern.test(value)) { + return Promise.reject(new Error('Repository path is not a valid path')); } - const intValue = +value; - if (Number.isNaN(intValue) || intValue < 0) { - callback('Value must be a non negative integer'); + return Promise.resolve(); +} + +function validateRepository(_: RuleObject, value: string): Promise<[void, void]> | Promise { + if (value) { + const [url, path] = value.split(/\s+/); + return Promise.all([validateURL(_, url), validateRepositoryPath(_, path)]); } - callback(); + return Promise.resolve(); } -function isIntegerRange(min: number, max: number, _: any, value: any, callback: any): void { - if (!value) { - callback(); - return; +const isInteger = ({ min, max }: { min?: number; max?: number }) => ( + _: RuleObject, + value?: number | string, +): Promise => { + if (typeof value === 'undefined' || value === '') { + return Promise.resolve(); } const intValue = +value; - if (Number.isNaN(intValue) - || !Number.isInteger(intValue) - || intValue < min || intValue > max - ) { - callback(`Value must be an integer [${min}, ${max}]`); + if (Number.isNaN(intValue) || !Number.isInteger(intValue)) { + return Promise.reject(new Error('Value must be a positive integer')); } - callback(); -} + if (typeof min !== 'undefined' && intValue < min) { + return Promise.reject(new Error(`Value must be more than ${min}`)); + } + + if (typeof max !== 'undefined' && intValue > max) { + return Promise.reject(new Error(`Value must be less than ${max}`)); + } + + return Promise.resolve(); +}; + +const validateOverlapSize: RuleRender = ({ getFieldValue }): RuleObject => ({ + validator(_: RuleObject, value?: string | number): Promise { + if (typeof value !== 'undefined' && value !== '') { + const segmentSize = getFieldValue('segmentSize'); + if (typeof segmentSize !== 'undefined' && segmentSize !== '') { + if (+segmentSize <= +value) { + return Promise.reject(new Error('Segment size must be more than overlap size')); + } + } + } + + return Promise.resolve(); + }, +}); + +const validateStopFrame: RuleRender = ({ getFieldValue }): RuleObject => ({ + validator(_: RuleObject, value?: string | number): Promise { + if (typeof value !== 'undefined' && value !== '') { + const startFrame = getFieldValue('startFrame'); + if (typeof startFrame !== 'undefined' && startFrame !== '') { + if (+startFrame > +value) { + return Promise.reject(new Error('Start frame must not be more than stop frame')); + } + } + } + + return Promise.resolve(); + }, +}); class AdvancedConfigurationForm extends React.PureComponent { + private formRef: RefObject; + + public constructor(props: Props) { + super(props); + this.formRef = React.createRef(); + } + public submit(): Promise { - return new Promise((resolve, reject) => { - const { - form, - onSubmit, - } = this.props; - - form.validateFields((error, values): void => { - if (!error) { - const filteredValues = { ...values }; - delete filteredValues.frameStep; - - if (values.overlapSize && +values.segmentSize <= +values.overlapSize) { - reject(new Error('Segment size must be more than overlap size')); - } - - if (typeof (values.startFrame) !== 'undefined' && typeof (values.stopFrame) !== 'undefined' - && +values.stopFrame < +values.startFrame - ) { - reject(new Error('Stop frame must be more or equal start frame')); - } + const { onSubmit } = this.props; + if (this.formRef.current) { + return this.formRef.current.validateFields().then( + (values: Store): Promise => { + const frameFilter = values.frameStep ? `step=${values.frameStep}` : undefined; + const entries = Object.entries(values).filter( + (entry: [string, unknown]): boolean => entry[0] !== frameFilter, + ); onSubmit({ - ...values, - frameFilter: values.frameStep ? `step=${values.frameStep}` : undefined, + ...((Object.fromEntries(entries) as any) as AdvancedConfiguration), + frameFilter, }); - resolve(); - } else { - reject(); - } - }); - }); + return Promise.resolve(); + }, + ); + } + + return Promise.reject(new Error('Form ref is empty')); } public resetFields(): void { - const { form } = this.props; - form.resetFields(); + if (this.formRef.current) { + this.formRef.current.resetFields(); + } } - private renderZOrder(): JSX.Element { - const { form } = this.props; + /* eslint-disable class-methods-use-this */ + private renderCopyDataChechbox(): JSX.Element { return ( - - {form.getFieldDecorator('zOrder', { - initialValue: false, - valuePropName: 'checked', - })( - - - Z-order - - , - )} + + + Copy data into CVAT + ); } private renderImageQuality(): JSX.Element { - const { form } = this.props; - return ( - Image quality}> - - {form.getFieldDecorator('imageQuality', { - initialValue: 70, - rules: [{ + + } - />, - )} - - + }, + { validator: isInteger({ min: 5, max: 100 }) }, + ]} + > + } /> + + ); } private renderOverlap(): JSX.Element { - const { form } = this.props; - return ( - Overlap size}> - - {form.getFieldDecorator('overlapSize', { - rules: [{ - validator: isNonNegativeInteger, - }], - })( - , - )} - - + + + + + ); } private renderSegmentSize(): JSX.Element { - const { form } = this.props; - return ( - Segment size}> - - {form.getFieldDecorator('segmentSize', { - rules: [{ - validator: isPositiveInteger, - }], - })( - , - )} - - + + + + + ); } private renderStartFrame(): JSX.Element { - const { form } = this.props; - return ( - Start frame}> - {form.getFieldDecorator('startFrame', { - rules: [{ - validator: isNonNegativeInteger, - }], - })( - , - )} + + ); } private renderStopFrame(): JSX.Element { - const { form } = this.props; - return ( - Stop frame}> - {form.getFieldDecorator('stopFrame', { - rules: [{ - validator: isNonNegativeInteger, - }], - })( - , - )} + + ); } private renderFrameStep(): JSX.Element { - const { form } = this.props; - return ( - Frame step}> - {form.getFieldDecorator('frameStep', { - rules: [{ - validator: isPositiveInteger, - }], - })( - , - )} + + ); } private renderGitLFSBox(): JSX.Element { - const { form } = this.props; - return ( - - {form.getFieldDecorator('lfs', { - valuePropName: 'checked', - initialValue: false, - })( - - - Use LFS (Large File Support): - - , - )} + + + Use LFS (Large File Support): + ); } private renderGitRepositoryURL(): JSX.Element { - const { form } = this.props; - return ( Dataset repository URL} + name='repository' + label='Dataset repository URL' extra='Attach a repository to store annotations there' + rules={[{ validator: validateRepository }]} > - {form.getFieldDecorator('repository', { - rules: [{ - validator: (_, value, callback): void => { - if (!value) { - callback(); - } else { - const [url, path] = value.split(/\s+/); - if (!patterns.validateURL.pattern.test(url)) { - callback('Git URL is not a valid'); - } - - if (path && !patterns.validatePath.pattern.test(path)) { - callback('Git path is not a valid'); - } - - callback(); - } - }, - }], - })( - , - )} + ); } @@ -323,121 +280,98 @@ class AdvancedConfigurationForm extends React.PureComponent { return ( <> - - {this.renderGitRepositoryURL()} - + {this.renderGitRepositoryURL()} - - {this.renderGitLFSBox()} - + {this.renderGitLFSBox()} ); } private renderBugTracker(): JSX.Element { - const { form } = this.props; - return ( Issue tracker} + name='bugTracker' + label='Issue tracker' extra='Attach issue tracker where the task is described' + rules={[{ validator: validateURL }]} > - {form.getFieldDecorator('bugTracker', { - rules: [{ - validator: (_, value, callback): void => { - if (value && !patterns.validateURL.pattern.test(value)) { - callback('Issue tracker must be URL'); - } else { - callback(); - } - }, - }], - })( - , - )} + ); } private renderUzeZipChunks(): JSX.Element { - const { form } = this.props; return ( - - {form.getFieldDecorator('useZipChunks', { - initialValue: true, - valuePropName: 'checked', - })( - - - Use zip chunks - - , - )} + + + Use zip chunks + ); } - private renderChunkSize(): JSX.Element { - const { form } = this.props; - + private renderCreateTaskMethod(): JSX.Element { return ( - Chunk size}> - - Defines a number of frames to be packed in - a chunk when send from client to server. - Server defines automatically if empty. -
    - Recommended values: -
    - 1080p or less: 36 -
    - 2k or less: 8 - 16 -
    - 4k or less: 4 - 8 -
    - More: 1 - 4 - - )} - mouseLeaveDelay={0} - > - {form.getFieldDecorator('dataChunkSize', { - rules: [{ - validator: isPositiveInteger, - }], - })( - , - )} -
    + + + Use cache + ); } - public render(): JSX.Element { - const { installedGit } = this.props; + private renderChunkSize(): JSX.Element { + return ( + + Defines a number of frames to be packed in a chunk when send from client to server. Server + defines automatically if empty. +
    + Recommended values: +
    + 1080p or less: 36 +
    + 2k or less: 8 - 16 +
    + 4k or less: 4 - 8 +
    + More: 1 - 4 + + )} + mouseLeaveDelay={0} + > + + + +
    + ); + } + public render(): JSX.Element { + const { installedGit, activeFileManagerTab } = this.props; return ( -
    + + {activeFileManagerTab === 'share' ? ( + +
    {this.renderCopyDataChechbox()} + + ) : null} - - {this.renderZOrder()} - + {this.renderUzeZipChunks()} - - - {this.renderUzeZipChunks()} - + {this.renderCreateTaskMethod()} - - - - {this.renderImageQuality()} - + + {this.renderImageQuality()}{this.renderOverlap()} @@ -446,10 +380,8 @@ class AdvancedConfigurationForm extends React.PureComponent { - - - {this.renderStartFrame()} - + + {this.renderStartFrame()}{this.renderStopFrame()} @@ -458,22 +390,18 @@ class AdvancedConfigurationForm extends React.PureComponent { - - - {this.renderChunkSize()} - + + {this.renderChunkSize()} - { installedGit ? this.renderGit() : null} + {installedGit ? this.renderGit() : null} - - {this.renderBugTracker()} - + {this.renderBugTracker()} ); } } -export default Form.create()(AdvancedConfigurationForm); +export default AdvancedConfigurationForm; diff --git a/cvat-ui/src/components/create-task-page/basic-configuration-form.tsx b/cvat-ui/src/components/create-task-page/basic-configuration-form.tsx index f269c38d..ac5cf7bb 100644 --- a/cvat-ui/src/components/create-task-page/basic-configuration-form.tsx +++ b/cvat-ui/src/components/create-task-page/basic-configuration-form.tsx @@ -2,63 +2,62 @@ // // SPDX-License-Identifier: MIT -import React from 'react'; +import React, { RefObject } from 'react'; import Input from 'antd/lib/input'; -import Form, { FormComponentProps } from 'antd/lib/form/Form'; +import Form, { FormInstance } from 'antd/lib/form'; +import { Store } from 'antd/lib/form/interface'; export interface BaseConfiguration { name: string; } -type Props = FormComponentProps & { +interface Props { onSubmit(values: BaseConfiguration): void; -}; +} -class BasicConfigurationForm extends React.PureComponent { - public submit(): Promise { - return new Promise((resolve, reject) => { - const { - form, - onSubmit, - } = this.props; +export default class BasicConfigurationForm extends React.PureComponent { + private formRef: RefObject; + + public constructor(props: Props) { + super(props); + this.formRef = React.createRef(); + } - form.validateFields((error, values): void => { - if (!error) { - onSubmit({ - name: values.name, - }); - resolve(); - } else { - reject(); - } + public submit(): Promise { + const { onSubmit } = this.props; + if (this.formRef.current) { + return this.formRef.current.validateFields().then((values: Store): Promise => { + onSubmit({ name: values.name }); + return Promise.resolve(); }); - }); + } + + return Promise.reject(new Error('Form ref is empty')); } public resetFields(): void { - const { form } = this.props; - form.resetFields(); + if (this.formRef.current) { + this.formRef.current.resetFields(); + } } public render(): JSX.Element { - const { form } = this.props; - const { getFieldDecorator } = form; - return ( -
    e.preventDefault()}> - Name}> - { getFieldDecorator('name', { - rules: [{ + + Name} + rules={[ + { required: true, - message: 'Please, specify a name', - }], - })( - , - ) } + message: 'Task name cannot be empty', + }, + ]} + > + ); } } - -export default Form.create()(BasicConfigurationForm); diff --git a/cvat-ui/src/components/create-task-page/create-task-content.tsx b/cvat-ui/src/components/create-task-page/create-task-content.tsx index 18de3d7a..c5a3b6a3 100644 --- a/cvat-ui/src/components/create-task-page/create-task-content.tsx +++ b/cvat-ui/src/components/create-task-page/create-task-content.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -import React from 'react'; +import React, { RefObject } from 'react'; import { RouteComponentProps } from 'react-router'; import { withRouter } from 'react-router-dom'; import { Row, Col } from 'antd/lib/grid'; @@ -13,35 +13,40 @@ import notification from 'antd/lib/notification'; import Text from 'antd/lib/typography/Text'; import ConnectedFileManager from 'containers/file-manager/file-manager'; +import LabelsEditor from 'components/labels-editor/labels-editor'; +import { Files } from 'components/file-manager/file-manager'; import BasicConfigurationForm, { BaseConfiguration } from './basic-configuration-form'; +import ProjectSearchField from './project-search-field'; import AdvancedConfigurationForm, { AdvancedConfiguration } from './advanced-configuration-form'; -import LabelsEditor from '../labels-editor/labels-editor'; -import { Files } from '../file-manager/file-manager'; export interface CreateTaskData { + projectId: number | null; basic: BaseConfiguration; advanced: AdvancedConfiguration; labels: any[]; files: Files; + activeFileManagerTab: string; } interface Props { onCreate: (data: CreateTaskData) => void; status: string; taskId: number | null; + projectId: number | null; installedGit: boolean; } type State = CreateTaskData; const defaultState = { + projectId: null, basic: { name: '', }, advanced: { - zOrder: false, lfs: false, useZipChunks: true, + useCache: true, }, labels: [], files: { @@ -49,38 +54,45 @@ const defaultState = { share: [], remote: [], }, + activeFileManagerTab: 'local', }; class CreateTaskContent extends React.PureComponent { - private basicConfigurationComponent: any; - private advancedConfigurationComponent: any; + private basicConfigurationComponent: RefObject; + private advancedConfigurationComponent: RefObject; private fileManagerContainer: any; public constructor(props: Props & RouteComponentProps) { super(props); this.state = { ...defaultState }; + this.basicConfigurationComponent = React.createRef(); + this.advancedConfigurationComponent = React.createRef(); + } + + public componentDidMount(): void { + const { projectId } = this.props; + + if (projectId) { + this.handleProjectIdChange(projectId); + } } public componentDidUpdate(prevProps: Props): void { const { status, history, taskId } = this.props; if (status === 'CREATED' && prevProps.status !== 'CREATED') { - const btn = ( - - ); + const btn = ; notification.info({ message: 'The task has been created', btn, }); - this.basicConfigurationComponent.resetFields(); - if (this.advancedConfigurationComponent) { - this.advancedConfigurationComponent.resetFields(); + if (this.basicConfigurationComponent.current) { + this.basicConfigurationComponent.current.resetFields(); + } + if (this.advancedConfigurationComponent.current) { + this.advancedConfigurationComponent.current.resetFields(); } this.fileManagerContainer.reset(); @@ -91,9 +103,9 @@ class CreateTaskContent extends React.PureComponent { - const { labels } = this.state; - return !!labels.length; + private validateLabelsOrProject = (): boolean => { + const { projectId, labels } = this.state; + return !!labels.length || !!projectId; }; private validateFiles = (): boolean => { @@ -101,13 +113,17 @@ class CreateTaskContent extends React.PureComponent acc + files[key].length, 0, - ); + const totalLen = Object.keys(files).reduce((acc, key) => acc + files[key].length, 0); return !!totalLen; }; + private handleProjectIdChange = (value: null | number): void => { + this.setState({ + projectId: value, + }); + }; + private handleSubmitBasicConfiguration = (values: BaseConfiguration): void => { this.setState({ basic: { ...values }, @@ -120,11 +136,19 @@ class CreateTaskContent extends React.PureComponent { + const values = this.state; + this.setState({ + ...values, + activeFileManagerTab: key, + }); + }; + private handleSubmitClick = (): void => { - if (!this.validateLabels()) { + if (!this.validateLabelsOrProject()) { notification.error({ message: 'Could not create a task', - description: 'A task must contain at least one label', + description: 'A task must contain at least one label or belong to some project', }); return; } @@ -137,41 +161,70 @@ class CreateTaskContent extends React.PureComponent { - if (this.advancedConfigurationComponent) { - return this.advancedConfigurationComponent.submit(); - } + if (this.basicConfigurationComponent.current) { + this.basicConfigurationComponent.current.submit() + .then(() => { + if (this.advancedConfigurationComponent.current) { + return this.advancedConfigurationComponent.current.submit(); + } - return new Promise((resolve): void => { - resolve(); - }); - }).then((): void => { - const { onCreate } = this.props; - onCreate(this.state); - }).catch((error: Error): void => { - notification.error({ - message: 'Could not create a task', - description: error.toString(), + return new Promise((resolve): void => { + resolve(); + }); + }).then((): void => { + const { onCreate } = this.props; + onCreate(this.state); + }) + .catch((error: Error): void => { + notification.error({ + message: 'Could not create a task', + description: error.toString(), + }); }); - }); + } }; private renderBasicBlock(): JSX.Element { return (
    { this.basicConfigurationComponent = component; } - } + ref={this.basicConfigurationComponent} onSubmit={this.handleSubmitBasicConfiguration} /> ); } + private renderProjectBlock(): JSX.Element { + const { projectId } = this.state; + + return ( + <> + + Project: + + + + + + ); + } + private renderLabelsBlock(): JSX.Element { - const { labels } = this.state; + const { projectId, labels } = this.state; + + if (projectId) { + return ( + <> + + Labels: + + + Project labels will be used + + + ); + } return ( @@ -179,13 +232,11 @@ class CreateTaskContent extends React.PureComponentLabels: { - this.setState({ - labels: newLabels, - }); - } - } + onSubmit={(newLabels): void => { + this.setState({ + labels: newLabels, + }); + }} /> ); @@ -197,9 +248,10 @@ class CreateTaskContent extends React.PureComponent* Select files: { this.fileManagerContainer = container; } - } + onChangeActiveKey={this.changeFileManagerTab} + ref={(container: any): void => { + this.fileManagerContainer = container; + }} withRemote /> @@ -208,22 +260,15 @@ class CreateTaskContent extends React.PureComponent - Advanced configuration - } - > + Advanced configuration}> { - this.advancedConfigurationComponent = component; - } - } + activeFileManagerTab={activeFileManagerTab} + ref={this.advancedConfigurationComponent} onSubmit={this.handleSubmitAdvancedConfiguration} /> @@ -237,26 +282,20 @@ class CreateTaskContent extends React.PureComponent + Basic configuration - { this.renderBasicBlock() } - { this.renderLabelsBlock() } - { this.renderFilesBlock() } - { this.renderAdvancedBlock() } + {this.renderBasicBlock()} + {this.renderProjectBlock()} + {this.renderLabelsBlock()} + {this.renderFilesBlock()} + {this.renderAdvancedBlock()} - - {loading ? : null} - - - {loading ? : null} + + diff --git a/cvat-ui/src/components/create-task-page/create-task-page.tsx b/cvat-ui/src/components/create-task-page/create-task-page.tsx index 39549ea6..adf65cf1 100644 --- a/cvat-ui/src/components/create-task-page/create-task-page.tsx +++ b/cvat-ui/src/components/create-task-page/create-task-page.tsx @@ -4,6 +4,7 @@ import './styles.scss'; import React, { useEffect } from 'react'; +import { useLocation } from 'react-router'; import { Row, Col } from 'antd/lib/grid'; import Modal from 'antd/lib/modal'; import Text from 'antd/lib/typography/Text'; @@ -22,13 +23,17 @@ interface Props { export default function CreateTaskPage(props: Props): JSX.Element { const { - error, - status, - taskId, - onCreate, - installedGit, + error, status, taskId, onCreate, installedGit, } = props; + const location = useLocation(); + + let projectId = null; + const params = new URLSearchParams(location.search); + if (params.get('projectId')?.match(/^[1-9]+[0-9]*$/)) { + projectId = +(params.get('projectId') as string); + } + useEffect(() => { if (error) { let errorCopy = error; @@ -64,11 +69,12 @@ export default function CreateTaskPage(props: Props): JSX.Element { }, [error]); return ( - + Create a new task void; +}; + +type Project = { + id: number; + name: string; +}; + +export default function ProjectSearchField(props: Props): JSX.Element { + const { value, onSelect } = props; + const [searchPhrase, setSearchPhrase] = useState(''); + + const [projects, setProjects] = useState([]); + + const handleSearch = (searchValue: string): void => { + if (searchValue) { + core.projects.searchNames(searchValue).then((result: Project[]) => { + if (result) { + setProjects(result); + } + }); + } else { + setProjects([]); + } + setSearchPhrase(searchValue); + onSelect(null); + }; + + const handleFocus = (open: boolean): void => { + if (!projects.length && open) { + core.projects.searchNames().then((result: Project[]) => { + if (result) { + setProjects(result); + } + }); + } + if (!open && !value && searchPhrase) { + setSearchPhrase(''); + } + }; + + const handleSelect = (_value: SelectValue): void => { + setSearchPhrase(projects.filter((proj) => proj.id === +_value)[0].name); + onSelect(_value ? +_value : null); + }; + + useEffect(() => { + if (value && !projects.filter((project) => project.id === value).length) { + core.projects.get({ id: value }).then((result: Project[]) => { + const [project] = result; + setProjects([ + ...projects, + { + id: project.id, + name: project.name, + }, + ]); + setSearchPhrase(project.name); + onSelect(project.id); + }); + } + }, [value]); + + return ( + ({ + value: proj.id.toString(), + label: proj.name, + }))} + /> + ); +} diff --git a/cvat-ui/src/components/create-task-page/styles.scss b/cvat-ui/src/components/create-task-page/styles.scss index a9b03632..59e89cd9 100644 --- a/cvat-ui/src/components/create-task-page/styles.scss +++ b/cvat-ui/src/components/create-task-page/styles.scss @@ -30,9 +30,13 @@ margin-top: 10px; } - > div:nth-child(7) > button { + .cvat-create-task-submit-section > button { float: right; width: 120px; } + + .cvat-project-search-field { + width: 100%; + } } } diff --git a/cvat-ui/src/components/cvat-app.tsx b/cvat-ui/src/components/cvat-app.tsx index 5c1af2cf..1c2c868d 100644 --- a/cvat-ui/src/components/cvat-app.tsx +++ b/cvat-ui/src/components/cvat-app.tsx @@ -3,37 +3,40 @@ // SPDX-License-Identifier: MIT import 'antd/dist/antd.css'; -import '../styles.scss'; -import React from 'react'; -import { Switch, Route, Redirect } from 'react-router'; -import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { GlobalHotKeys, ExtendedKeyMapOptions, configure } from 'react-hotkeys'; -import Spin from 'antd/lib/spin'; +import { Col, Row } from 'antd/lib/grid'; import Layout from 'antd/lib/layout'; -import { Row, Col } from 'antd/lib/grid'; -import Text from 'antd/lib/typography/Text'; +import Modal from 'antd/lib/modal'; import notification from 'antd/lib/notification'; - +import Spin from 'antd/lib/spin'; +import Text from 'antd/lib/typography/Text'; import GlobalErrorBoundary from 'components/global-error-boundary/global-error-boundary'; +import Header from 'components/header/header'; +import ResetPasswordPageConfirmComponent from 'components/reset-password-confirm-page/reset-password-confirm-page'; +import ResetPasswordPageComponent from 'components/reset-password-page/reset-password-page'; import ShorcutsDialog from 'components/shortcuts-dialog/shortcuts-dialog'; +import ProjectsPageComponent from 'components/projects-page/projects-page'; +import CreateProjectPageComponent from 'components/create-project-page/create-project-page'; +import ProjectPageComponent from 'components/project-page/project-page'; import TasksPageContainer from 'containers/tasks-page/tasks-page'; +import LoginWithTokenComponent from 'components/login-with-token/login-with-token'; import CreateTaskPageContainer from 'containers/create-task-page/create-task-page'; import TaskPageContainer from 'containers/task-page/task-page'; import ModelsPageContainer from 'containers/models-page/models-page'; import AnnotationPageContainer from 'containers/annotation-page/annotation-page'; import LoginPageContainer from 'containers/login-page/login-page'; import RegisterPageContainer from 'containers/register-page/register-page'; -import Header from 'components/header/header'; -import { customWaViewHit } from 'utils/enviroment'; -import showPlatformNotification, { stopNotifications, platformInfo } from 'utils/platform-checker'; - import getCore from 'cvat-core-wrapper'; +import React from 'react'; +import { configure, ExtendedKeyMapOptions, GlobalHotKeys } from 'react-hotkeys'; +import { Redirect, Route, Switch } from 'react-router'; +import { RouteComponentProps, withRouter } from 'react-router-dom'; import { NotificationsState } from 'reducers/interfaces'; -import Modal from 'antd/lib/modal'; +import { customWaViewHit } from 'utils/enviroment'; +import showPlatformNotification, { platformInfo, stopNotifications } from 'utils/platform-checker'; +import '../styles.scss'; interface CVATAppProps { loadFormats: () => void; - loadUsers: () => void; loadAbout: () => void; verifyAuthorized: () => void; loadUserAgreements: () => void; @@ -53,17 +56,15 @@ interface CVATAppProps { modelsFetching: boolean; formatsInitialized: boolean; formatsFetching: boolean; - usersInitialized: boolean; - usersFetching: boolean; aboutInitialized: boolean; aboutFetching: boolean; userAgreementsFetching: boolean; userAgreementsInitialized: boolean; authActionsFetching: boolean; authActionsInitialized: boolean; - allowChangePassword: boolean; notifications: NotificationsState; user: any; + isModelPluginActive: boolean; } class CVATApplication extends React.PureComponent { @@ -91,7 +92,6 @@ class CVATApplication extends React.PureComponent - {`The browser you are using is ${info.name} ${info.version} based on ${info.engine} .` - + ' CVAT was tested in the latest versions of Chrome and Firefox.' - + ' We recommend to use Chrome (or another Chromium based browser)'} + {`The browser you are using is ${name} ${version} based on ${engine}.` + + ' CVAT was tested in the latest versions of Chrome and Firefox.' + + ' We recommend to use Chrome (or another Chromium based browser)'} - - {`The operating system is ${info.os}`} - + {`The operating system is ${os}`} @@ -300,7 +299,6 @@ class CVATApplication extends React.PureComponent + + + - - + {isModelPluginActive && ( + + )} + {/* eslint-disable-next-line */} @@ -332,15 +338,26 @@ class CVATApplication extends React.PureComponent - + + + + 1 ? `/auth/login/?next=${location.pathname}` : '/auth/login'} + /> ); } - return ( - - ); + return ; } } diff --git a/cvat-ui/src/components/feedback/feedback.tsx b/cvat-ui/src/components/feedback/feedback.tsx index cc1869c7..b1741186 100644 --- a/cvat-ui/src/components/feedback/feedback.tsx +++ b/cvat-ui/src/components/feedback/feedback.tsx @@ -5,9 +5,11 @@ import './styles.scss'; import React from 'react'; import Button from 'antd/lib/button'; -import Icon from 'antd/lib/icon'; import Popover from 'antd/lib/popover'; import Text from 'antd/lib/typography/Text'; +import { + StarOutlined, LikeOutlined, CloseCircleOutlined, MessageOutlined, +} from '@ant-design/icons'; import { FacebookShareButton, LinkedinShareButton, @@ -30,31 +32,38 @@ import { import consts from 'consts'; function renderContent(): JSX.Element { - const { - GITHUB_URL, - GITHUB_IMAGE_URL, - GITTER_PUBLIC_URL, - } = consts; + const { GITHUB_URL, GITHUB_IMAGE_URL, GITTER_PUBLIC_URL } = consts; return ( <> - + Star us on - GitHub + + {' '} + GitHub +
    - + Leave a - feedback + + {' '} + feedback +
    - + @@ -79,7 +88,10 @@ function renderContent(): JSX.Element {
    Do you need help? Contact us on - gitter + + {' '} + gitter + ); @@ -92,22 +104,19 @@ export default function Feedback(): JSX.Element { <> Help to make CVAT better - } + title={Help to make CVAT better} content={renderContent()} visible={visible} > diff --git a/cvat-ui/src/components/feedback/styles.scss b/cvat-ui/src/components/feedback/styles.scss index 39415886..5b44af6b 100644 --- a/cvat-ui/src/components/feedback/styles.scss +++ b/cvat-ui/src/components/feedback/styles.scss @@ -9,7 +9,7 @@ padding: 0; height: auto; - > i { + > span[role='img'] { font-size: 40px; } } diff --git a/cvat-ui/src/components/file-manager/file-manager.tsx b/cvat-ui/src/components/file-manager/file-manager.tsx index 3c970cd5..3a547e0b 100644 --- a/cvat-ui/src/components/file-manager/file-manager.tsx +++ b/cvat-ui/src/components/file-manager/file-manager.tsx @@ -3,15 +3,17 @@ // SPDX-License-Identifier: MIT import './styles.scss'; -import React from 'react'; +import React, { ReactText } from 'react'; import Tabs from 'antd/lib/tabs'; -import Icon from 'antd/lib/icon'; import Input from 'antd/lib/input'; import Text from 'antd/lib/typography/Text'; import Paragraph from 'antd/lib/typography/Paragraph'; import Upload, { RcFile } from 'antd/lib/upload'; import Empty from 'antd/lib/empty'; -import Tree, { AntTreeNode, TreeNodeNormal } from 'antd/lib/tree/Tree'; +import Tree, { TreeNodeNormal } from 'antd/lib/tree/Tree'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { EventDataNode } from 'rc-tree/lib/interface'; +import { InboxOutlined } from '@ant-design/icons'; import consts from 'consts'; @@ -31,6 +33,7 @@ interface Props { withRemote: boolean; treeData: TreeNodeNormal[]; onLoadData: (key: string, success: () => void, failure: () => void) => void; + onChangeActiveKey(key: string): void; } export default class FileManager extends React.PureComponent { @@ -51,10 +54,7 @@ export default class FileManager extends React.PureComponent { } public getFiles(): Files { - const { - active, - files, - } = this.state; + const { active, files } = this.state; return { local: active === 'local' ? files.local : [], share: active === 'share' ? files.share : [], @@ -62,15 +62,14 @@ export default class FileManager extends React.PureComponent { }; } - private loadData = (key: string): Promise => new Promise( - (resolve, reject): void => { + private loadData = (key: string): Promise => + new Promise((resolve, reject): void => { const { onLoadData } = this.props; const success = (): void => resolve(); const failure = (): void => reject(); onLoadData(key, success, failure); - }, - ); + }); public reset(): void { this.setState({ @@ -93,9 +92,11 @@ export default class FileManager extends React.PureComponent { multiple listType='text' fileList={files.local as any[]} - showUploadList={files.local.length < 5 && { - showRemoveIcon: false, - }} + showUploadList={ + files.local.length < 5 && { + showRemoveIcon: false, + } + } beforeUpload={(_: RcFile, newLocalFiles: RcFile[]): boolean => { this.setState({ files: { @@ -107,22 +108,17 @@ export default class FileManager extends React.PureComponent { }} >

    - +

    Click or drag files to this area

    -

    - Support for a bulk images or a single video -

    +

    Support for a bulk images or a single video

    - { files.local.length >= 5 - && ( - <> -
    - - {`${files.local.length} files selected`} - - - )} + {files.local.length >= 5 && ( + <> +
    + {`${files.local.length} files selected`} + + )} ); } @@ -130,80 +126,74 @@ export default class FileManager extends React.PureComponent { private renderShareSelector(): JSX.Element { function renderTreeNodes(data: TreeNodeNormal[]): JSX.Element[] { // sort alphabetically - data.sort((a: TreeNodeNormal, b: TreeNodeNormal): number => a.key.localeCompare(b.key)); + data.sort((a: TreeNodeNormal, b: TreeNodeNormal): number => + a.key.toLocaleString().localeCompare(b.key.toLocaleString())); return data.map((item: TreeNodeNormal) => { if (item.children) { return ( - + {renderTreeNodes(item.children)} ); } - return ; + return ; }); } const { SHARE_MOUNT_GUIDE_URL } = consts; const { treeData } = this.props; - const { - expandedKeys, - files, - } = this.state; + const { expandedKeys, files } = this.state; return ( - { treeData[0].children && treeData[0].children.length - ? ( - => this.loadData( - node.props.dataRef.key, - )} - onExpand={(newExpandedKeys: string[]): void => { - this.setState({ - expandedKeys: newExpandedKeys, - }); - }} - onCheck={ - (checkedKeys: string[] | { - checked: string[]; - halfChecked: string[]; - }): void => { - const keys = checkedKeys as string[]; - this.setState({ - files: { - ...files, - share: keys, - }, - }); - } - } - > - { renderTreeNodes(treeData) } - - ) : ( -
    - - - Please, be sure you had - - mounted - - share before you built CVAT and the shared storage contains files - -
    - )} + {treeData[0].children && treeData[0].children.length ? ( + => this.loadData(event.key.toLocaleString())} + onExpand={(newExpandedKeys: ReactText[]): void => { + this.setState({ + expandedKeys: newExpandedKeys.map((text: ReactText): string => text.toLocaleString()), + }); + }} + onCheck={( + checkedKeys: + | ReactText[] + | { + checked: ReactText[]; + halfChecked: ReactText[]; + }, + ): void => { + const keys = (checkedKeys as ReactText[]).map((text: ReactText): string => + text.toLocaleString()); + this.setState({ + files: { + ...files, + share: keys, + }, + }); + }} + > + {renderTreeNodes(treeData)} + + ) : ( +
    + + + Please, be sure you had + + mounted + + share before you built CVAT and the shared storage contains files + +
    + )}
    ); } @@ -231,7 +221,7 @@ export default class FileManager extends React.PureComponent { } public render(): JSX.Element { - const { withRemote } = this.props; + const { withRemote, onChangeActiveKey } = this.props; const { active } = this.state; return ( @@ -240,15 +230,16 @@ export default class FileManager extends React.PureComponent { type='card' activeKey={active} tabBarGutter={5} - onChange={ - (activeKey: string): void => this.setState({ + onChange={(activeKey: string): void => { + onChangeActiveKey(activeKey); + this.setState({ active: activeKey as any, - }) - } + }); + }} > - { this.renderLocalSelector() } - { this.renderShareSelector() } - { withRemote && this.renderRemoteSelector() } + {this.renderLocalSelector()} + {this.renderShareSelector()} + {withRemote && this.renderRemoteSelector()} ); diff --git a/cvat-ui/src/components/file-manager/styles.scss b/cvat-ui/src/components/file-manager/styles.scss index 7c72d764..dd280ceb 100644 --- a/cvat-ui/src/components/file-manager/styles.scss +++ b/cvat-ui/src/components/file-manager/styles.scss @@ -5,10 +5,7 @@ @import '../../base.scss'; .cvat-share-tree { - height: fit-content; - min-height: 10em; - max-height: 20em; - overflow: auto; + height: 32 * $grid-unit-size; } .cvat-empty-share-tree { diff --git a/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx b/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx index 9be93aae..6330ca00 100644 --- a/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx +++ b/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx @@ -40,14 +40,9 @@ interface State { function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { - job: { - instance: job, - }, - }, - about: { - server, - packageVersion, + job: { instance: job }, }, + about: { server, packageVersion }, } = state; return { @@ -67,7 +62,6 @@ function mapDispatchToProps(dispatch: ThunkDispatch): DispatchToProps { }; } - type Props = StateToProps & DispatchToProps; class GlobalErrorBoundary extends React.PureComponent { public constructor(props: Props) { @@ -107,12 +101,7 @@ class GlobalErrorBoundary extends React.PureComponent { public render(): React.ReactNode { const { - restore, - job, - serverVersion, - coreVersion, - canvasVersion, - uiVersion, + restore, job, serverVersion, coreVersion, canvasVersion, uiVersion, } = this.props; const { hasError, error } = this.state; @@ -142,7 +131,11 @@ class GlobalErrorBoundary extends React.PureComponent { -