diff --git a/.dockerignore b/.dockerignore index 57189ad6..fe1fa8c9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ -datasets/* \ No newline at end of file +datasets/* +models/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4598ae83..bb5431d3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ __pycache__ dist/* !dist/.gitkeep -docs/.vuepress/dist/* \ No newline at end of file +docs/.vuepress/dist/* +models/*.h5 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 4f436e95..4196ba16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,21 +12,19 @@ matrix: - TESTING=true - LOGIN_DISABLED=true before_script: + - pip install -r backend/requirements.txt - pip install pycocotools - docker run -d -p 27017:27017 mongo - docker ps -a script: pytest - - - language: node_js - node_js: - - 8 - - node - cache: npm - before_install: - - npm install -g npm@latest - - cd client - install: - - npm i - script: npm test - - + # - language: node_js + # node_js: + # - 8 + # - node + # cache: npm + # before_install: + # - npm install -g npm@latest + # - cd client + # install: + # - npm i + # script: npm test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..45fc542d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,146 @@ +# Contributing to HTML5 Boilerplate + +Love [COCO Annotator](/jsbroks/coco-annotator) and want to get involved? +Thanks! We're actively looking for folks interested in helping out and there +are plenty of ways you can help! + +Please take a moment to review this document in order to make the contribution +process easy and effective for everyone involved. + +Following these guidelines helps to communicate that you respect the time of +the developers managing and developing this open source project. In return, +they should reciprocate that respect in addressing your issue or assessing +patches and features. + + +## Using the issue tracker + +The [issue tracker](/jsbroks/coco-annotator/issues) 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 + [Stack Overflow](https://stackoverflow.com/questions/tagged/coco-annotator)). + +* 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. +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. + +2. **Check if the issue has been fixed** — try to reproduce it using the + latest `master` or development branch in the repository. + +3. **Isolate the problem** — ideally create a [reduced test + case](https://css-tricks.com/reduced-test-cases/) and a live example. + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. What is +your environment? What steps will reproduce the issue? What browser(s) and OS +experience the problem? What would you expect to be the outcome? All these +details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If +> suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case +> +> Any other information you want to share that is relevant to the issue being +> reported. This might include the lines of code that you have identified as +> causing the bug, and potential solutions (and your opinions on their +> merits). + + + +## Feature requests + +Feature requests are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +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 +help. They should remain focused in scope and avoid containing unrelated +commits. + +**Please ask first** before embarking on any significant pull request (e.g. +implementing features, refactoring code, porting to a different language), +otherwise you risk spending a lot of time working on something that the +project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, +accurate comments, etc.) and any other requirements (such as test coverage). + +Adhering to the following process is the best way to get your work +included in the project: + +1. [Fork](https://help.github.com/articles/fork-a-repo/) the project, clone your + fork, and configure the remotes: + + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//html5-boilerplate.git + # Navigate to the newly cloned directory + cd html5-boilerplate + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/h5bp/html5-boilerplate.git + ``` + +2. If you cloned a while ago, get the latest changes from upstream: + + ```bash + git checkout master + git pull upstream master + ``` + +3. Create a new topic branch (off the main project development branch) to + contain your feature, change, or fix: + + ```bash + git checkout -b + ``` + +4. Commit your changes in logical chunks. Please adhere to these [git commit + message guidelines](https://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://help.github.com/articles/about-git-rebase/) + feature to tidy up your commits before making them public. + +5. Locally merge (or rebase) the upstream development branch into your topic branch: + + ```bash + git pull [--rebase] upstream master + ``` + +6. Push your topic branch up to your fork: + + ```bash + git push origin + ``` + +7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) + with a clear title and description. + +**IMPORTANT**: By submitting a patch, you agree to allow the project +owners to license your work under the terms of the [MIT License](LICENSE.txt). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..bacfc3b2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +FROM node:10 as build-stage + +WORKDIR /workspace/ +COPY ./client /workspace/client + +RUN npm install -g --quiet \ + @vue/cli@3.3.0 \ + @vue/cli-service@3.3.0 + +COPY ./client/package* /workspace/ + +RUN npm install +ENV NODE_PATH=/workspace/node_modules + +WORKDIR /workspace/client +RUN npm run build + +FROM jsbroks/coco-annotator:python-env + +WORKDIR /workspace/ +COPY ./backend/ /workspace/ +COPY ./.git /workspace/.git +RUN python set_path.py + +COPY --from=build-stage /workspace/client/dist /workspace/dist + +ENV FLASK_ENV=production +ENV DEBUG=false + +EXPOSE 5000 +CMD gunicorn -c webserver/gunicorn_config.py webserver:app --no-sendfile --timeout 180 + diff --git a/README.md b/README.md index cb847f4d..b9cb7ee5 100644 --- a/README.md +++ b/README.md @@ -3,67 +3,125 @@

FeaturesWiki • - Getting Stated • + Getting StartedIssuesLicense

- --- +

+ + + + + + + + + + + + + + + + + + + + + +

-[![GitHub Stars](https://img.shields.io/github/stars/jsbroks/coco-annotator.svg)](https://github.com/jsbroks/coco-annotator/stargazers) -[![GitHub Issues](https://img.shields.io/github/issues/jsbroks/coco-annotator.svg)](https://github.com/jsbroks/coco-annotator/issues) -![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg) -[![Code Quality](https://img.shields.io/lgtm/grade/javascript/g/jsbroks/coco-annotator.svg?label=code%20quality)](https://lgtm.com/projects/g/jsbroks/coco-annotator/context:javascript) -[![Demo](https://img.shields.io/badge/demo-online-green.svg)](https://annotator.justinbrooks.ca/) -[![Build Status](https://travis-ci.org/jsbroks/coco-annotator.svg?branch=master)](https://travis-ci.org/jsbroks/coco-annotator) -[![Docker Pulls](https://img.shields.io/docker/pulls/jsbroks/coco-annotator.svg)](https://hub.docker.com/r/jsbroks/coco-annotator) - -COCO Annotator is a web-based image annotation tool designed for versatility and efficiently label images to create training data for image localization and object detection. It provides many distinct features including the ability to label an image segment (or part of a segment), track object instances, labeling objects with disconnected visible parts, efficiently storing and export annotations in the well-know [COCO format](http://cocodataset.org/#format-data). The annotation process is delivered though an intuitive and customizable interface and provides many tools for creating accurate datasets. +COCO Annotator is a web-based image annotation tool designed for versatility and efficiently label images to create training data for image localization and object detection. It provides many distinct features including the ability to label an image segment (or part of a segment), track object instances, labeling objects with disconnected visible parts, efficiently storing and export annotations in the well-known [COCO format](http://cocodataset.org/#format-data). The annotation process is delivered through an intuitive and customizable interface and provides many tools for creating accurate datasets.

Note: This video is from v0.1.0 and many new features have been added.

+
+

If you enjoy my work please consider supporting me

+

+ + + +

+
+ # Features Several annotation tools are currently available, with most applications as a desktop installation. Once installed, users can manually define regions in an image and creating a textual description. Generally, objects can be marked by a bounding box, either directly, through a masking tool, or by marking points to define the containing area. _COCO Annotator_ allows users to annotate images using free-form curves or polygons and provides many additional features were other annotations tool fall short. - - Directly export to COCO format - - Segmentation of objects - - Useful API endpoints to analyze data - - Import datasets already annotated in COCO format - - Annotated disconnected objects as a single instance - - Labeling image segments with any number of labels simultaneously - - Allow custom metadata for each instance or object - - Magic wand/select tool - - Generate datasets using google images - - User authenication system +- Directly export to COCO format +- Segmentation of objects +- Ability to add key points +- Useful API endpoints to analyze data +- Import datasets already annotated in COCO format +- Annotate disconnect objects as a single instance +- Labeling image segments with any number of labels simultaneously +- Allow custom metadata for each instance or object +- Advanced selection tools such as, [DEXTR](https://github.com/jsbroks/dextr-keras), [MaskRCNN](https://github.com/matterport/Mask_RCNN) and Magic Wand +- Annotate images with semi-trained models +- Generate datasets using google images +- User authentication system For examples and more information check out the [wiki](https://github.com/jsbroks/coco-annotator/wiki). # Demo -| Login Information | -| ----------------- | -| __Username:__ admin | -| __Password:__ password | +| Login Information | +| ---------------------- | +| **Username:** admin | +| **Password:** password | https://annotator.justinbrooks.ca/ # Backers -

-

Backed by the The Robotics Institute @ Guelph (GitHub)

+Thanks to the backers for making this project possible! + +

+ +

+

+ The Robotics Institute @ Guelph (GitHub) +

+ +

+ +

+

+ INTVO (GitHub) +

# Built With Thanks to all these wonderful libaries/frameworks: - - [Flask](http://flask.pocoo.org/) - Python web microframework - - [Vue](https://vuejs.org/) - Frontend javascript framework - - [Axios](https://github.com/axios/axios) - Promise based HTTP client - - [PaperJS](http://paperjs.org/) - Canvas editor library - - [Bootstrap](https://getbootstrap.com/) - Frontend component library + +### Backend + +- [Flask](http://flask.pocoo.org/) - Python web microframework +- [MongoDB](https://www.mongodb.com/) - Cross-platform document-oriented database +- [MongoEngine](http://mongoengine.org/) - Python object data mapper for MongoDB + +### Frontend + +- [Vue](https://vuejs.org/) - JavaScript framework for building user interfaces +- [Axios](https://github.com/axios/axios) - Promise based HTTP client +- [PaperJS](http://paperjs.org/) - HTML canvas vector graphics library +- [Bootstrap](https://getbootstrap.com/) - Frontend component library # License + [MIT](https://tldrlegal.com/license/mit-license) + +# Citation + +``` + @MISC{cocoannotator, + author = {Justin Brooks}, + title = {{COCO Annotator}}, + howpublished = "\url{https://github.com/jsbroks/coco-annotator/}", + year = {2019}, + } +``` diff --git a/app/api/datasets.py b/app/api/datasets.py deleted file mode 100644 index fc65f833..00000000 --- a/app/api/datasets.py +++ /dev/null @@ -1,393 +0,0 @@ -from flask_restplus import Namespace, Resource, reqparse -from flask_login import login_required, current_user -from werkzeug.datastructures import FileStorage -from mongoengine.errors import NotUniqueError -from threading import Thread - -from google_images_download import google_images_download as gid - -from ..util.pagination_util import Pagination -from ..util import query_util, coco_util -from ..models import * - - -import datetime -import json -import os - -api = Namespace('dataset', description='Dataset related operations') - - -dataset_create = reqparse.RequestParser() -dataset_create.add_argument('name', required=True) -dataset_create.add_argument('categories', type=list, required=False, location='json', - help="List of default categories for sub images") - -page_data = reqparse.RequestParser() -page_data.add_argument('page', default=1, type=int) -page_data.add_argument('limit', default=20, type=int) -page_data.add_argument('folder', required=False, default='', help='Folder for data') - -delete_data = reqparse.RequestParser() -delete_data.add_argument('fully', default=False, type=bool, - help="Fully delete dataset (no undo)") - -coco_upload = reqparse.RequestParser() -coco_upload.add_argument('coco', location='files', type=FileStorage, required=True, help='Json coco') - - -update_dataset = reqparse.RequestParser() -update_dataset.add_argument('categories', location='json', type=list, help="New list of categories") -update_dataset.add_argument('default_annotation_metadata', location='json', type=dict, - help="Default annotation metadata") - -dataset_generate = reqparse.RequestParser() -dataset_generate.add_argument('keywords', location='json', type=list, default=[], - help="Keywords associated with images") -dataset_generate.add_argument('limit', location='json', type=int, default=100, help="Number of images per keyword") - -share = reqparse.RequestParser() -share.add_argument('users', location='json', type=list, default=[], help="List of users") - - -@api.route('/') -class Dataset(Resource): - @login_required - def get(self): - """ Returns all datasets """ - return query_util.fix_ids(current_user.datasets.filter(deleted=False).all()) - - @api.expect(dataset_create) - @login_required - def post(self): - """ Creates a dataset """ - args = dataset_create.parse_args() - name = args['name'] - categories = args.get('categories', []) - - category_ids = CategoryModel.bulk_create(categories) - - try: - dataset = DatasetModel(name=name, categories=category_ids) - dataset.save() - except NotUniqueError: - return {'message': 'Dataset already exists. Check the undo tab to fully delete the dataset.'}, 400 - - return query_util.fix_ids(dataset) - - -def download_images(output_dir, args): - for keyword in args['keywords']: - response = gid.googleimagesdownload() - response.download({ - "keywords": keyword, - "limit": args['limit'], - "output_directory": output_dir, - "no_numbering": True, - "format": "jpg", - "type": "photo", - "print_urls": False, - "print_paths": False, - "print_size": False - }) - - -@api.route('//generate') -class DatasetGenerate(Resource): - @api.expect(dataset_generate) - @login_required - def post(self, dataset_id): - """ Adds images found on google to the dataset """ - args = dataset_generate.parse_args() - - dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() - if dataset is None: - return {"message": "Invalid dataset id"}, 400 - - thread = Thread(target=download_images, args=(dataset.directory, args)) - thread.start() - - return {"success": True} - - -@api.route('/') -class DatasetId(Resource): - @login_required - def delete(self, dataset_id): - """ Deletes dataset by ID (only owners of datasets can delete them)""" - - datasets = DatasetModel.objects(id=dataset_id, deleted=False) - if not current_user.is_admin: - datasets = datasets.filter(owner=current_user.username) - - dataset = datasets.first() - - if dataset is None: - return {"message": "Invalid dataset id"}, 400 - - dataset.update(set__deleted=True, set__deleted_date=datetime.datetime.now()) - return {"success": True} - - @api.expect(update_dataset) - def post(self, dataset_id): - """ Updates dataset by ID """ - dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() - if dataset is None: - return {"message": "Invalid dataset id"}, 400 - - args = update_dataset.parse_args() - categories = args.get('categories') - default_annotation_metadata = args.get('default_annotation_metadata') - - if categories is not None: - dataset.categories = CategoryModel.bulk_create(categories) - - if default_annotation_metadata is not None: - dataset.default_annotation_metadata = default_annotation_metadata - - dataset.update( - categories=dataset.categories, - default_annotation_metadata=dataset.default_annotation_metadata - ) - - return {"success": True} - - -@api.route('//share') -class DatasetIdShare(Resource): - @api.expect(share) - @login_required - def post(self, dataset_id): - args = share.parse_args() - - dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() - if dataset is None: - return {"message": "Invalid dataset id"}, 400 - - dataset.update(users=args.get('users')) - - return {"success": True} - - -@api.route('/data') -class Dataset(Resource): - @api.expect(page_data) - @login_required - def get(self): - """ Endpoint called by dataset viewer client """ - - args = page_data.parse_args() - limit = args['limit'] - page = args['page'] - folder = args['folder'] - - datasets = current_user.datasets.filter(deleted=False) - pagination = Pagination(datasets.count(), limit, page) - datasets = query_util.fix_ids(datasets[pagination.start:pagination.end]) - - for dataset in datasets: - images = ImageModel.objects(dataset_id=dataset.get('id'), deleted=False) - - dataset['numberImages'] = images.count() - dataset['numberAnnotated'] = images.filter(annotated=True).count() - - first = images.first() - if first is not None: - dataset['first_image_id'] = images.first().id - - return { - "pagination": pagination.export(), - "folder": folder, - "datasets": datasets, - "categories": query_util.fix_ids(current_user.categories.filter(deleted=False).all()) - } - - -@api.route('//data') -class DatasetDataId(Resource): - - @api.expect(page_data) - @login_required - def get(self, dataset_id): - """ Endpoint called by image viewer client """ - - exec_start = datetime.datetime.now() - args = page_data.parse_args() - limit = args['limit'] - page = args['page'] - folder = args['folder'] - - # Check if dataset exists - dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() - if dataset is None: - return {'message', 'Invalid dataset id'}, 400 - - # Make sure folder starts with is in proper format - if len(folder) > 0: - folder = folder[0].strip('/') + folder[1:] - if folder[-1] != '/': - folder = folder + '/' - - # Get directory - directory = os.path.join(dataset.directory, folder) - if not os.path.exists(directory): - return {'message': 'Directory does not exist.'}, 400 - - images = ImageModel.objects(dataset_id=dataset_id, path__startswith=directory, deleted=False) \ - .order_by('file_name').only('id', 'file_name') - - pagination = Pagination(images.count(), limit, page) - images = query_util.fix_ids(images[pagination.start:pagination.end]) - - for image in images: - image_id = image.get('id') - image['annotations'] = AnnotationModel.objects(image_id=image_id, deleted=False).count() - - subdirectories = [f for f in sorted(os.listdir(directory)) - if os.path.isdir(directory + f)] - - delta = datetime.datetime.now() - exec_start - return { - "time_ms": int(delta.total_seconds() * 1000), - "pagination": pagination.export(), - "images": images, - "folder": folder, - "directory": directory, - "dataset": query_util.fix_ids(dataset), - "subdirectories": subdirectories - } - - -@api.route('//coco') -class ImageCoco(Resource): - - @login_required - def get(self, dataset_id): - """ Returns coco of images and annotations in the dataset """ - - dataset = current_user.datasets.filter(id=dataset_id).first() - - if dataset is None: - return {"message": "Invalid dataset ID"}, 400 - - return coco_util.get_dataset_coco(dataset) - - @api.expect(coco_upload) - @login_required - def post(self, dataset_id): - """ Adds coco formatted annotations to the dataset """ - args = coco_upload.parse_args() - coco = args['coco'] - - dataset = current_user.datasets.filter(id=dataset_id).first() - images = ImageModel.objects(dataset_id=dataset_id) - categories = CategoryModel.objects - - if dataset is None: - return {'message': 'Invalid dataset ID'}, 400 - - coco_json = json.load(coco) - coco_images = coco_json.get('images') - coco_annotations = coco_json.get('annotations') - coco_categories = coco_json.get('categories') - - errors = [] - - categories_id = {} - images_id = {} - - # Create any missing categories - for category in coco_categories: - category_name = category.get('name') - print("Loading category {}".format(category_name), flush=True) - - category_id = category.get('id') - category_model = categories.filter(name__exact=category_name).all() - - if len(category_model) == 0: - errors.append({'category': category_name, - 'message': 'Creating category ' + category_name + '.'}) - - new_category = CategoryModel(name=category_name, color=color_util.random_color_hex()) - new_category.save() - categories_id[category_id] = new_category.id - print("Category not found! (Creating new one)", flush=True) - continue - - if len(category_model) > 1: - errors.append({'category': category_name, - 'message': 'To many categories found with file name.'}) - continue - - category_model = category_model[0] - categories_id[category_id] = category_model.id - - # Add any new categories to dataset - for key, value in categories_id.items(): - if value not in dataset.categories: - dataset.categories.append(value) - - dataset.update(set__categories=dataset.categories) - - # Find all images - for image in coco_images: - image_id = image.get('id') - image_filename = image.get('file_name') - - print("Loading image {}".format(image_filename), flush=True) - image_model = images.filter(file_name__exact=image_filename).all() - - if len(image_model) == 0: - errors.append({'file_name': image_filename, - 'message': 'Could not find image.'}) - continue - - if len(image_model) > 1: - errors.append({'file_name': image_filename, - 'message': 'To many images found with the same file name.'}) - continue - - image_model = image_model[0] - print("Image found", flush=True) - images_id[image_id] = image_model - - # Generate annotations - for annotation in coco_annotations: - image_id = annotation.get('image_id') - category_id = annotation.get('category_id') - segmentation = annotation.get('segmentation', []) - is_crowd = annotation.get('iscrowed', False) - - if len(segmentation) == 0: - continue - - print("Loading annotation data (image:{} category:{})".format(image_id, category_id), flush=True) - - try: - image_model = images_id[image_id] - category_model_id = categories_id[category_id] - except KeyError: - continue - - # Check if annotation already exists - annotation = AnnotationModel.objects(image_id=image_model.id, - category_id=category_model_id, - segmentation=segmentation, delete=False).first() - # Create annotation - if annotation is None: - print("Creating annotation", flush=True) - annotation = AnnotationModel(image_id=image_model.id) - annotation.category_id = category_model_id - # annotation.iscrowd = is_crowd - annotation.segmentation = segmentation - annotation.color = color_util.random_color_hex() - annotation.save() - - image_model.update(set__annotated=True) - else: - print("Annotation already exists", flush=True) - - return { - 'errors': errors - } - diff --git a/app/config.py b/app/config.py deleted file mode 100644 index aceaf763..00000000 --- a/app/config.py +++ /dev/null @@ -1,28 +0,0 @@ -import os - -from .util.version_util import get_tag - - -class Config: - - NAME = "COCO Annotator" - VERSION = get_tag() - - # Flask instance - SWAGGER_UI_JSONEDITOR = True - MAX_CONTENT_LENGTH = 1 * 1024 * 1024 * 1024 # 1GB - MONGODB_HOST = os.getenv("MONGODB_HOST", "mongodb://database/flask") - SECRET_KEY = os.getenv('SECRET_KEY', '<--- YOUR_SECRET_FORM_KEY --->') - - TESTING = os.getenv("TESTING", False) - - # Dataset Options - DATASET_DIRECTORY = os.getenv("DATASET_DIRECTORY", "/datasets/") - INITIALIZE_FROM_FILE = os.getenv("INITIALIZE_FROM_FILE") - LOAD_IMAGES_ON_START = os.getenv("LOAD_IMAGES_ON_START", False) - - # User Options - LOGIN_DISABLED = os.getenv('LOGIN_DISABLED', False) - ALLOW_REGISTRATION = True - - diff --git a/app/gunicorn_config.py b/app/gunicorn_config.py deleted file mode 100644 index b2a64ad5..00000000 --- a/app/gunicorn_config.py +++ /dev/null @@ -1,53 +0,0 @@ -import os - - -def on_starting(server): - """ - Attach a set of IDs that can be temporarily re-used. - Used on reloads when each worker exists twice. - """ - server._worker_id_overload = set() - - -def nworkers_changed(server, new_value, old_value): - """ - Gets called on startup too. - Set the current number of workers. Required if we raise the worker count - temporarily using TTIN because server.cfg.workers won't be updated and if - one of those workers dies, we wouldn't know the ids go that far. - """ - server._worker_id_current_workers = new_value - - -def _next_worker_id(server): - """ - If there are IDs open for re-use, take one. Else look for a free one. - """ - if server._worker_id_overload: - return server._worker_id_overload.pop() - - in_use = set(w._worker_id for w in server.WORKERS.values() if w.alive) - free = set(range(1, server._worker_id_current_workers + 1)) - in_use - - return free.pop() - - -def on_reload(server): - """ - Add a full set of ids into overload so it can be re-used once. - """ - server._worker_id_overload = set(range(1, server.cfg.workers + 1)) - - -def pre_fork(server, worker): - """ - Attach the next free worker_id before forking off. - """ - worker._worker_id = _next_worker_id(server) - - -def post_fork(server, worker): - """ - Put the worker_id into an env variable for further use within the app. - """ - os.environ["APP_WORKER_ID"] = str(worker._worker_id) \ No newline at end of file diff --git a/app/image_folder.py b/app/image_folder.py deleted file mode 100644 index f38c54e8..00000000 --- a/app/image_folder.py +++ /dev/null @@ -1,35 +0,0 @@ -from watchdog.events import FileSystemEventHandler - -from .models import ImageModel - - -class ImageFolderHandler(FileSystemEventHandler): - - def __init__(self, pattern=None): - self.pattern = pattern or (".gif", ".png", ".jpg", ".jpeg", ".bmp") - - def on_any_event(self, event): - - path = event.dest_path if event.event_type == "moved" else event.src_path - - # Check if thumbnails directory - folders = path.split('/') - i = folders.index("datasets") - if i+1 < len(folders) and folders[i+1] == "_thumbnails": - return - - if not event.is_directory and path.endswith(self.pattern): - - image = ImageModel.objects(path=event.src_path).first() - - if image is None and event.event_type != 'deleted': - print("Adding new file to database: {}".format(path), flush=True) - ImageModel.create_from_path(path).save() - - elif event.event_type == 'moved': - print("Moving image from {} to {}".format(event.src_path, path), flush=True) - image.update(path=path) - - elif event.event_type == 'deleted': - print("Deleting image from database: {}".format(path), flush=True) - ImageModel.objects(path=path).delete() diff --git a/app/models.py b/app/models.py deleted file mode 100644 index e0b0c3de..00000000 --- a/app/models.py +++ /dev/null @@ -1,375 +0,0 @@ -import os -import cv2 -import json -import datetime -import numpy as np - -from flask_mongoengine import MongoEngine -from mongoengine.queryset.visitor import Q -from flask_login import UserMixin, current_user - - -from .util import color_util -from .config import Config -from PIL import Image - - -db = MongoEngine() - - -class DatasetModel(db.DynamicDocument): - - id = db.SequenceField(primary_key=True) - name = db.StringField(required=True, unique=True) - directory = db.StringField() - categories = db.ListField(default=[]) - - owner = db.StringField(required=True) - users = db.ListField(default=[]) - - default_annotation_metadata = db.DictField(default={}) - - deleted = db.BooleanField(default=False) - deleted_date = db.DateTimeField() - - def save(self, *args, **kwargs): - - directory = os.path.join(Config.DATASET_DIRECTORY, self.name + '/') - - if not os.path.exists(directory): - os.makedirs(directory) - else: - ImageModel.load_images(directory, self.id) - - self.directory = directory - self.owner = current_user.username - - return super(DatasetModel, self).save(*args, **kwargs) - - -class ImageModel(db.DynamicDocument): - - PATTERN = (".gif", ".png", ".jpg", ".jpeg", ".bmp") - - id = db.SequenceField(primary_key=True) - path = db.StringField(required=True, unique=True) - - dataset_id = db.IntField() - - width = db.IntField(required=True) - height = db.IntField(required=True) - file_name = db.StringField() - - annotated = db.BooleanField(default=False) - - image_url = db.StringField() - thumbnail_url = db.StringField() - - category_ids = db.ListField(default=[]) - - metadata = db.DictField() - - license = db.IntField() - coco_url = db.StringField() - - deleted = db.BooleanField(default=False) - deleted_date = db.DateTimeField() - - @classmethod - def create_from_path(cls, path, dataset_id=None): - - pil_image = Image.open(path) - - image = cls() - image.file_name = os.path.basename(path) - image.path = path - image.width = pil_image.size[0] - image.height = pil_image.size[1] - - if dataset_id is not None: - image.dataset_id = dataset_id - else: - # Get dataset name from path - folders = path.split('/') - i = folders.index("datasets") - dataset_name = folders[i+1] - - dataset = DatasetModel.objects(name=dataset_name).first() - if dataset is not None: - image.dataset_id = dataset.id - - pil_image.close() - - return image - - @classmethod - def load_images(cls, directory, dataset_id=None): - print("Checking all images in dataset directory (may take a few minutes)") - for root, dirs, files in os.walk(directory): - for file in files: - path = os.path.join(root, file) - - if path.endswith(cls.PATTERN): - db_image = cls.objects(path=path).first() - - if db_image is None: - print("New file found: {}".format(path)) - cls.create_from_path(path, dataset_id).save() - - def thumbnail_path(self): - folders = self.path.split('/') - i = folders.index("datasets") - folders.insert(i+1, "_thumbnails") - - directory = '/'.join(folders[:-1]) - if not os.path.exists(directory): - os.makedirs(directory) - - return '/'.join(folders) - - def copy_annotations(self, annotations): - """ - Creates a copy of the annotations for this image - :param annotations: QuerySet of annotation models - :return: number of annotations - """ - annotations = annotations.filter(width=self.width, height=self.height, area__gt=0) - - for annotation in annotations: - clone = annotation.clone() - - clone.dataset_id = self.dataset_id - clone.image_id = self.id - - clone.save(copy=True) - - return annotations.count() - - -class AnnotationModel(db.DynamicDocument): - - id = db.SequenceField(primary_key=True) - image_id = db.IntField(required=True) - category_id = db.IntField(required=True) - dataset_id = db.IntField() - - segmentation = db.ListField(default=[]) - area = db.IntField(default=0) - bbox = db.ListField() - iscrowd = db.BooleanField(default=False) - - creator = db.StringField(required=True) - width = db.IntField() - height = db.IntField() - - color = db.StringField() - - metadata = db.DictField(default={}) - paper_object = db.ListField(default=[]) - - deleted = db.BooleanField(default=False) - deleted_date = db.DateTimeField() - - def __init__(self, image_id=None, **data): - - image = ImageModel.objects(id=image_id).first() - - if image is not None: - data['image_id'] = image_id - data['width'] = image.width - data['height'] = image.height - data['dataset_id'] = image.dataset_id - else: - raise ValueError("Invalid image id.") - - super(AnnotationModel, self).__init__(**data) - - def save(self, copy=False, *args, **kwargs): - - if not self.dataset_id and not copy: - dataset = DatasetModel.objects(id=self.dataset_id).first() - - if dataset is not None: - self.metadata = dataset.default_annotation_metadata.copy() - - if self.color is None: - self.color = color_util.random_color_hex() - - self.creator = current_user.username - return super(AnnotationModel, self).save(*args, **kwargs) - - def is_empty(self): - return len(self.segmentation) == 0 or self.area == 0 - - def mask(self): - """ Returns binary mask of annotation """ - mask = np.zeros((self.height, self.width)) - pts = [ - np.array(anno).reshape(-1, 2).round().astype(int) - for anno in self.segmentation - ] - mask = cv2.fillPoly(mask, pts, 1) - return mask - - def clone(self): - """ Creates a clone """ - create = json.loads(self.to_json()) - del create['_id'] - - return AnnotationModel(**create) - - -class CategoryModel(db.DynamicDocument): - - id = db.SequenceField(primary_key=True) - name = db.StringField(required=True, unique_with=['creator']) - supercategory = db.StringField(default="") - color = db.StringField(default=None) - metadata = db.DictField(default={}) - - creator = db.StringField(default="unknown") - deleted = db.BooleanField(default=False) - deleted_date = db.DateTimeField() - - @classmethod - def bulk_create(cls, categories): - - if not categories: - return [] - - category_ids = [] - for category in categories: - category_model = CategoryModel.objects(name=category).first() - - if category_model is None: - new_category = CategoryModel(name=category) - new_category.save() - category_ids.append(new_category.id) - else: - category_ids.append(category_model.id) - - return category_ids - - def save(self, *args, **kwargs): - - if not self.color: - self.color = color_util.random_color_hex() - - if current_user: - self.creator = current_user.username - - return super(CategoryModel, self).save(*args, **kwargs) - - -class LicenseModel(db.DynamicDocument): - id = db.SequenceField(primary_key=True) - name = db.StringField() - url = db.StringField() - - -class UserModel(db.DynamicDocument, UserMixin): - password = db.StringField(required=True) - username = db.StringField(max_length=25, required=True, unique=True) - email = db.StringField(max_length=30) - - name = db.StringField() - last_seen = db.DateTimeField() - - is_admin = db.BooleanField(default=False) - - preferences = db.DictField(default={}) - - def save(self, *args, **kwargs): - - self.last_seen = datetime.datetime.now() - - return super(UserModel, self).save(*args, **kwargs) - - @property - def datasets(self): - self._update_last_seen() - - if self.is_admin: - return DatasetModel.objects - - return DatasetModel.objects(Q(owner=self.username) | Q(users__contains=self.username)) - - @property - def categories(self): - self._update_last_seen() - - if self.is_admin: - return CategoryModel.objects - - dataset_ids = self.datasets.distinct('categories') - return CategoryModel.objects(Q(id__in=dataset_ids) | Q(creator=self.username)) - - @property - def images(self): - self._update_last_seen() - - if self.is_admin: - return ImageModel.objects - - dataset_ids = self.datasets.distinct('id') - return ImageModel.objects(dataset_id__in=dataset_ids) - - @property - def annotations(self): - self._update_last_seen() - - if self.is_admin: - return AnnotationModel.objects - - image_ids = self.images.distinct('id') - return AnnotationModel.objects(image_id__in=image_ids) - - def _update_last_seen(self): - self.update(last_seen=datetime.datetime.now()) - - -# https://github.com/MongoEngine/mongoengine/issues/1171 -# Use this methods until a solution is found -def upsert(model, query=None, update=None): - - if not update: - update = query - - if not query: - return None - - found = model.objects(**query) - - if found.first(): - return found.modify(new=True, **update) - - new_model = model(**update) - new_model.save() - - return new_model - - -def create_from_json(json_file): - - with open(json_file) as file: - - data_json = json.load(file) - for category in data_json.get('categories', []): - name = category.get('name') - if name is not None: - upsert(CategoryModel, query={"name": name}, update=category) - - for dataset_json in data_json.get('datasets', []): - name = dataset_json.get('name') - if name: - # map category names to ids; create as needed - category_ids = [] - for category in dataset_json.get('categories', []): - category_obj = {"name": category} - - category_model = upsert(CategoryModel, query=category_obj) - category_ids.append(category_model.id) - - dataset_json['categories'] = category_ids - upsert(DatasetModel, query={ "name": name}, update=dataset_json) - diff --git a/app/routes.py b/app/routes.py deleted file mode 100644 index 0ec48266..00000000 --- a/app/routes.py +++ /dev/null @@ -1,40 +0,0 @@ -# from flask import Blueprint, render_template - - -# client = Blueprint('client', __name__, static_folder='client') -# client = Blueprint('client', __name__, static_folder="../dist", template_folder="../dist") - - -# @client.route('/') -# def index(): -# return render_template('index.html') - - -# @client.route('/images/') -# @client.route('/datasets/') -# def index(dataset_id): -# return render_template('images.html') -# -# -# @client.route('/annotate/') -# @client.route('/editor/') -# def annotate(image_id): -# return render_template('annotator.html') -# -# -# @client.route('/datasets/') -# def datasets(): -# return render_template('datasets.html') -# -# -# @client.route('/categories/') -# def categories(): -# return render_template('categories.html') -# -# -# @client.route('/undo/') -# def undo(): -# return render_template('undo.html') - - - diff --git a/app/util/color_util.py b/app/util/color_util.py deleted file mode 100644 index 17ffe1bc..00000000 --- a/app/util/color_util.py +++ /dev/null @@ -1,29 +0,0 @@ -import random -import colorsys - - -def random_color_hls(hue=[0, 1], lightness=[0.35, 0.70], saturation=[0.60, 1]): - h = random.uniform(hue[0], hue[1]) - l = random.uniform(lightness[0], lightness[1]) - s = random.uniform(saturation[0], saturation[1]) - return h, l, s - - -def random_color_rgb(): - h, l, s = random_color_hls() - return [int(256*i) for i in colorsys.hls_to_rgb(h, l, s)] - - -def random_color_hex(): - rgb = random_color_rgb() - return '#%02x%02x%02x' % (rgb[0], rgb[1], rgb[2]) - - -def hex_to_rgb(h): - h = h.lstrip('#') - return tuple(int(h[i:i + 2], 16) for i in (0, 2, 4)) - - -def rgb_to_hsl(): - pass - diff --git a/app/util/query_util.py b/app/util/query_util.py deleted file mode 100644 index a88e5a46..00000000 --- a/app/util/query_util.py +++ /dev/null @@ -1,7 +0,0 @@ -import json - - -def fix_ids(objs): - objects_list = json.loads(objs.to_json().replace('\"_id\"', '\"id\"')) - return objects_list - diff --git a/app/util/thumbnail_util.py b/app/util/thumbnail_util.py deleted file mode 100644 index 60dc926b..00000000 --- a/app/util/thumbnail_util.py +++ /dev/null @@ -1,46 +0,0 @@ -import numpy as np - -from ..models import AnnotationModel -from .color_util import hex_to_rgb - -from PIL import Image - - -def apply_mask(image, mask, color, alpha=0.5): - """Apply the given mask to the image. - """ - for c in range(3): - image[:, :, c] = np.where(mask == 1, - image[:, :, c] * - (1 - alpha) + alpha * color[c] * 255, - image[:, :, c]) - return image - - -def generate_thumbnail(image_model, save=True): - - image = Image.open(image_model.path) - binary_image = np.array(image) - binary_image.setflags(write=True) - - annotations = AnnotationModel.objects(image_id=image_model.id, deleted=False).all() - - for annotation in annotations: - - if len(annotation.segmentation) == 0: - continue - - color = np.array(hex_to_rgb(annotation.color))/255 - binary_image = apply_mask(binary_image, annotation.mask(), color) - - image = Image.fromarray(binary_image) - - if save: - image.save(image_model.thumbnail_path()) - - return image - - - - - diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..1ec98c3f --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,25 @@ +# Backend environment docker image +FROM python:3.6 + +WORKDIR /workspace/ + +# Copy backend +COPY ./backend/requirements.txt /workspace/ + +# Install python package dependices +RUN pip install -r requirements.txt && \ + pip install gunicorn[eventlet]==19.9.0 && \ + pip install pycocotools + +# Install maskrcnn +RUN git clone --single-branch --depth 1 https://github.com/matterport/Mask_RCNN.git /tmp/maskrcnn && \ + cd /tmp/maskrcnn && \ + pip install -r requirements.txt && \ + python3 setup.py install + +# Install DEXTR +RUN git clone --single --depth 1 https://github.com/jsbroks/dextr-keras.git /tmp/dextr && \ + cd /tmp/dextr && \ + pip install -r requirements.txt && \ + python setup.py install + diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 00000000..1aad7b09 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,9 @@ +# COCO Annotator Backend + +## Web Server + +## Workers + +## Database + +## Config diff --git a/backend/config/__init__.py b/backend/config/__init__.py new file mode 100644 index 00000000..d085c3a9 --- /dev/null +++ b/backend/config/__init__.py @@ -0,0 +1 @@ +from .config import * \ No newline at end of file diff --git a/backend/config/config.py b/backend/config/config.py new file mode 100644 index 00000000..05dbfef5 --- /dev/null +++ b/backend/config/config.py @@ -0,0 +1,66 @@ +import os +import subprocess + + +def get_tag(): + result = subprocess.run(["git", "describe", "--abbrev=0", "--tags"], stdout=subprocess.PIPE) + return str(result.stdout.decode("utf-8")).strip() + + +class Config: + + NAME = os.getenv("NAME", "COCO Annotator") + VERSION = get_tag() + + ### File Watcher + FILE_WATCHER = os.getenv("FILE_WATCHER", False) + IGNORE_DIRECTORIES = ["_thumbnail", "_settings"] + + # Flask/Gunicorn + # + # LOG_LEVEL - The granularity of log output + # + # A string of "debug", "info", "warning", "error", "critical" + # + # WORKER_CONNECTIONS - limits the maximum number of simultaneous + # clients that a single process can handle. + # + # A positive integer generally set to around 1000. + # + # WORKER_TIMEOUT - If a worker does not notify the master process + # in this number of seconds it is killed and a new worker is + # spawned to replace it. + # + SWAGGER_UI_JSONEDITOR = True + DEBUG = os.getenv("DEBUG", 'false').lower() == 'true' + PRELOAD = False + + MAX_CONTENT_LENGTH = os.getenv("MAX_CONTENT_LENGTH", 1 * 1024 * 1024 * 1024) # 1GB + MONGODB_HOST = os.getenv("MONGODB_HOST", "mongodb://database/flask") + SECRET_KEY = os.getenv("SECRET_KEY", "<--- CHANGE THIS KEY --->") + + LOG_LEVEL = 'debug' + WORKER_CONNECTIONS = 1000 + + TESTING = os.getenv("TESTING", False) + + ### Workers + CELERY_BROKER_URL = "amqp://user:password@messageq:5672//" + CELERY_RESULT_BACKEND = "mongodb://database/flask" + + ### Dataset Options + DATASET_DIRECTORY = os.getenv("DATASET_DIRECTORY", "/datasets/") + INITIALIZE_FROM_FILE = os.getenv("INITIALIZE_FROM_FILE") + + ### User Options + LOGIN_DISABLED = os.getenv("LOGIN_DISABLED", False) + ALLOW_REGISTRATION = True + + ### Models + MASK_RCNN_FILE = os.getenv("MASK_RCNN_FILE", "") + MASK_RCNN_CLASSES = os.getenv("MASK_RCNN_CLASSES", "BG") + + DEXTR_FILE = os.getenv("DEXTR_FILE", "/models/dextr_pascal-sbd.h5") + + +__all__ = ["Config"] \ No newline at end of file diff --git a/backend/database/__init__.py b/backend/database/__init__.py new file mode 100644 index 00000000..7bf07a43 --- /dev/null +++ b/backend/database/__init__.py @@ -0,0 +1,73 @@ +from mongoengine import connect +from config import Config + +from .annotations import * +from .categories import * +from .datasets import * +from .lisence import * +from .exports import * +from .images import * +from .events import * +from .users import * +from .tasks import * + +import json + + +def connect_mongo(name, host=None): + if host is None: + host = Config.MONGODB_HOST + connect(name, host=host) + + +# https://github.com/MongoEngine/mongoengine/issues/1171 +# Use this methods until a solution is found +def upsert(model, query=None, update=None): + + if not update: + update = query + + if not query: + return None + + found = model.objects(**query) + + if found.first(): + return found.modify(new=True, **update) + + new_model = model(**update) + new_model.save() + + return new_model + + +def fix_ids(q): + json_obj = json.loads(q.to_json().replace('\"_id\"', '\"id\"')) + return json_obj + + +def create_from_json(json_file): + + with open(json_file) as file: + + data_json = json.load(file) + for category in data_json.get('categories', []): + name = category.get('name') + if name is not None: + upsert(CategoryModel, query={"name": name}, update=category) + + for dataset_json in data_json.get('datasets', []): + name = dataset_json.get('name') + if name: + # map category names to ids; create as needed + category_ids = [] + for category in dataset_json.get('categories', []): + category_obj = {"name": category} + + category_model = upsert(CategoryModel, query=category_obj) + category_ids.append(category_model.id) + + dataset_json['categories'] = category_ids + upsert(DatasetModel, query={ "name": name}, update=dataset_json) + + diff --git a/backend/database/annotations.py b/backend/database/annotations.py new file mode 100644 index 00000000..9a810bd7 --- /dev/null +++ b/backend/database/annotations.py @@ -0,0 +1,120 @@ +import imantics as im +import json + +from mongoengine import * + +from .datasets import DatasetModel +from .categories import CategoryModel +from .events import Event +from flask_login import current_user + + +class AnnotationModel(DynamicDocument): + + COCO_PROPERTIES = ["id", "image_id", "category_id", "segmentation", + "iscrowd", "color", "area", "bbox", "metadata", + "keypoints"] + + id = SequenceField(primary_key=True) + image_id = IntField(required=True) + category_id = IntField(required=True) + dataset_id = IntField() + + segmentation = ListField(default=[]) + area = IntField(default=0) + bbox = ListField(default=[0, 0, 0, 0]) + iscrowd = BooleanField(default=False) + + creator = StringField(required=True) + width = IntField() + height = IntField() + + color = StringField() + + keypoints = ListField(default=[]) + + metadata = DictField(default={}) + paper_object = ListField(default=[]) + + deleted = BooleanField(default=False) + deleted_date = DateTimeField() + + milliseconds = IntField(default=0) + events = EmbeddedDocumentListField(Event) + + def __init__(self, image_id=None, **data): + + from .images import ImageModel + + if image_id is not None: + image = ImageModel.objects(id=image_id).first() + + if image is not None: + data['image_id'] = image_id + data['width'] = image.width + data['height'] = image.height + data['dataset_id'] = image.dataset_id + + super(AnnotationModel, self).__init__(**data) + + def save(self, copy=False, *args, **kwargs): + + if self.dataset_id and not copy: + dataset = DatasetModel.objects(id=self.dataset_id).first() + + if dataset is not None: + self.metadata = dataset.default_annotation_metadata.copy() + + if self.color is None: + self.color = im.Color.random().hex + + if current_user: + self.creator = current_user.username + else: + self.creator = 'system' + + return super(AnnotationModel, self).save(*args, **kwargs) + + def is_empty(self): + return len(self.segmentation) == 0 or self.area == 0 + + def mask(self): + """ Returns binary mask of annotation """ + mask = np.zeros((self.height, self.width)) + pts = [ + np.array(anno).reshape(-1, 2).round().astype(int) + for anno in self.segmentation + ] + mask = cv2.fillPoly(mask, pts, 1) + return mask + + def clone(self): + """ Creates a clone """ + create = json.loads(self.to_json()) + del create['_id'] + + return AnnotationModel(**create) + + def __call__(self): + + category = CategoryModel.objects(id=self.category_id).first() + if category: + category = category() + + data = { + 'image': None, + 'category': category, + 'color': self.color, + 'polygons': self.segmentation, + 'width': self.width, + 'height': self.height, + 'metadata': self.metadata + } + + return im.Annotation(**data) + + def add_event(self, e): + self.update(push__events=e) + + +__all__ = ["AnnotationModel"] diff --git a/backend/database/categories.py b/backend/database/categories.py new file mode 100644 index 00000000..49074d69 --- /dev/null +++ b/backend/database/categories.py @@ -0,0 +1,83 @@ + +from flask_login import current_user +from mongoengine import * + +import imantics as im + + +class CategoryModel(DynamicDocument): + + COCO_PROPERTIES = ["id", "name", "supercategory", "color", "metadata",\ + "keypoint_edges", "keypoint_labels"] + + id = SequenceField(primary_key=True) + name = StringField(required=True, unique_with=['creator']) + supercategory = StringField(default='') + color = StringField(default=None) + metadata = DictField(default={}) + + creator = StringField(default='unknown') + deleted = BooleanField(default=False) + deleted_date = DateTimeField() + + keypoint_edges = ListField(default=[]) + keypoint_labels = ListField(default=[]) + + + @classmethod + def bulk_create(cls, categories): + + if not categories: + return [] + + category_ids = [] + for category in categories: + category_model = CategoryModel.objects(name=category).first() + + if category_model is None: + new_category = CategoryModel(name=category) + new_category.save() + category_ids.append(new_category.id) + else: + category_ids.append(category_model.id) + + return category_ids + + def save(self, *args, **kwargs): + + if not self.color: + self.color = im.Color.random().hex + + if current_user: + self.creator = current_user.username + else: + self.creator = 'system' + + return super(CategoryModel, self).save(*args, **kwargs) + + def __call__(self): + """ Generates imantics category object """ + data = { + 'name': self.name, + 'color': self.color, + 'parent': self.supercategory, + 'metadata': self.metadata, + 'id': self.id + } + return im.Category(**data) + + def is_owner(self, user): + + if user.is_admin: + return True + + return user.username.lower() == self.creator.lower() + + def can_edit(self, user): + return self.is_owner(user) + + def can_delete(self, user): + return self.is_owner(user) + + +__all__ = ["CategoryModel"] \ No newline at end of file diff --git a/backend/database/datasets.py b/backend/database/datasets.py new file mode 100644 index 00000000..d761b7dc --- /dev/null +++ b/backend/database/datasets.py @@ -0,0 +1,141 @@ + +from flask_login import current_user +from mongoengine import * +from config import Config + +from .tasks import TaskModel + +import os + + +class DatasetModel(DynamicDocument): + + id = SequenceField(primary_key=True) + name = StringField(required=True, unique=True) + directory = StringField() + thumbnails = StringField() + categories = ListField(default=[]) + + owner = StringField(required=True) + users = ListField(default=[]) + + annotate_url = StringField(default="") + + default_annotation_metadata = DictField(default={}) + + deleted = BooleanField(default=False) + deleted_date = DateTimeField() + + def save(self, *args, **kwargs): + + directory = os.path.join(Config.DATASET_DIRECTORY, self.name + '/') + os.makedirs(directory, mode=0o777, exist_ok=True) + + self.directory = directory + self.owner = current_user.username if current_user else 'system' + + return super(DatasetModel, self).save(*args, **kwargs) + + def get_users(self): + from .users import UserModel + + members = self.users + members.append(self.owner) + + return UserModel.objects(username__in=members)\ + .exclude('password', 'id', 'preferences') + + def import_coco(self, coco_json): + + from workers.tasks import import_annotations + + task = TaskModel( + name="Import COCO format into {}".format(self.name), + dataset_id=self.id, + group="Annotation Import" + ) + task.save() + + cel_task = import_annotations.delay(task.id, self.id, coco_json) + + return { + "celery_id": cel_task.id, + "id": task.id, + "name": task.name + } + + def export_coco(self, categories=None, style="COCO"): + + from workers.tasks import export_annotations + + if categories is None or len(categories) == 0: + categories = self.categories + + task = TaskModel( + name=f"Exporting {self.name} into {style} format", + dataset_id=self.id, + group="Annotation Export" + ) + task.save() + + cel_task = export_annotations.delay(task.id, self.id, categories) + + return { + "celery_id": cel_task.id, + "id": task.id, + "name": task.name + } + + def scan(self): + + from workers.tasks import scan_dataset + + task = TaskModel( + name=f"Scanning {self.name} for new images", + dataset_id=self.id, + group="Directory Image Scan" + ) + task.save() + + cel_task = scan_dataset.delay(task.id, self.id) + + return { + "celery_id": cel_task.id, + "id": task.id, + "name": task.name + } + + def is_owner(self, user): + + if user.is_admin: + return True + + return user.username.lower() == self.owner.lower() + + def can_download(self, user): + return self.is_owner(user) + + def can_delete(self, user): + return self.is_owner(user) + + def can_share(self, user): + return self.is_owner(user) + + def can_generate(self, user): + return self.is_owner(user) + + def can_edit(self, user): + return user.username in self.users or self.is_owner(user) + + def permissions(self, user): + return { + 'owner': self.is_owner(user), + 'edit': self.can_edit(user), + 'share': self.can_share(user), + 'generate': self.can_generate(user), + 'delete': self.can_delete(user), + 'download': self.can_download(user) + } + + +__all__ = ["DatasetModel"] diff --git a/backend/database/events.py b/backend/database/events.py new file mode 100644 index 00000000..92e8de01 --- /dev/null +++ b/backend/database/events.py @@ -0,0 +1,36 @@ +from mongoengine import * + +import datetime +import time + + +class Event(EmbeddedDocument): + + name = StringField() + created_at = DateTimeField() + + meta = {'allow_inheritance': True} + + def now(self, event): + self.created_at = datetime.datetime.now() + + +class SessionEvent(Event): + + user = StringField(required=True) + milliseconds = IntField(default=0, min_value=0) + tools_used = ListField(default=[]) + + @classmethod + def create(self, start, user, end=None, tools=[]): + + if end is None: + end = time.time() + + return SessionEvent( + user=user.username, + milliseconds=int((end-start)*1000) + ) + + +__all__ = ["Event", "SessionEvent"] \ No newline at end of file diff --git a/backend/database/exports.py b/backend/database/exports.py new file mode 100644 index 00000000..65170fa7 --- /dev/null +++ b/backend/database/exports.py @@ -0,0 +1,20 @@ +from mongoengine import * + +import datetime +import time + + +class ExportModel(DynamicDocument): + + id = SequenceField(primary_key=True) + dataset_id = IntField(required=True) + path = StringField(required=True) + tags = ListField(default=[]) + categories = ListField(default=[]) + created_at = DateTimeField(default=datetime.datetime.utcnow) + + def get_file(self): + return + + +__all__ = ["ExportModel"] \ No newline at end of file diff --git a/backend/database/images.py b/backend/database/images.py new file mode 100644 index 00000000..fbd0cb90 --- /dev/null +++ b/backend/database/images.py @@ -0,0 +1,197 @@ +import os +import imantics as im + + +from PIL import Image +from mongoengine import * + +from .events import Event, SessionEvent +from .datasets import DatasetModel +from .annotations import AnnotationModel + +class ImageModel(DynamicDocument): + + COCO_PROPERTIES = ["id", "width", "height", "file_name", "path", "license",\ + "flickr_url", "coco_url", "date_captured", "dataset_id"] + + # -- Contants + THUMBNAIL_DIRECTORY = '.thumbnail' + PATTERN = (".gif", ".png", ".jpg", ".jpeg", ".bmp") + + # -- Private + _dataset = None + + # -- Database + id = SequenceField(primary_key=True) + dataset_id = IntField(required=True) + category_ids = ListField(default=[]) + + # Absolute path to image file + path = StringField(required=True, unique=True) + width = IntField(required=True) + height = IntField(required=True) + file_name = StringField() + + # True if the image is annotated + annotated = BooleanField(default=False) + # Poeple currently annotation the image + annotating = ListField(default=[]) + num_annotations = IntField(default=0) + + thumbnail_url = StringField() + image_url = StringField() + coco_url = StringField() + date_captured = DateTimeField() + + metadata = DictField() + license = IntField() + + deleted = BooleanField(default=False) + deleted_date = DateTimeField() + + milliseconds = IntField(default=0) + events = EmbeddedDocumentListField(Event) + regenerate_thumbnail = BooleanField(default=False) + + @classmethod + def create_from_path(cls, path, dataset_id=None): + + pil_image = Image.open(path) + + image = cls() + image.file_name = os.path.basename(path) + image.path = path + image.width = pil_image.size[0] + image.height = pil_image.size[1] + + if dataset_id is not None: + image.dataset_id = dataset_id + else: + # Get dataset name from path + folders = path.split('/') + i = folders.index("datasets") + dataset_name = folders[i+1] + + dataset = DatasetModel.objects(name=dataset_name).first() + if dataset is not None: + image.dataset_id = dataset.id + + pil_image.close() + + return image + + def delete(self, *args, **kwargs): + self.thumbnail_delete() + AnnotationModel.objects(image_id=self.id).delete() + return super(ImageModel, self).delete(*args, **kwargs) + + def thumbnail(self): + """ + Generates (if required) and returns thumbnail + """ + if not self.annotated: + self.thumbnail_delete() + return Image.open(self.path) + + thumbnail_path = self.thumbnail_path() + + if self.regenerate_thumbnail or \ + not os.path.isfile(thumbnail_path): + + # logger.debug(f'Generating thumbnail for {self.id}') + + pil_image = self.generate_thumbnail() + pil_image = pil_image.convert("RGB") + pil_image.save(thumbnail_path) + + self.update(is_modified=False) + return pil_image + else: + return Image.open(thumbnail_path) + + def thumbnail_path(self): + folders = self.path.split('/') + folders.insert(len(folders)-1, self.THUMBNAIL_DIRECTORY) + + path = '/' + os.path.join(*folders) + directory = os.path.dirname(path) + + if not os.path.exists(directory): + os.makedirs(directory) + + return path + + def thumbnail_delete(self): + path = self.thumbnail_path() + if os.path.isfile(path): + os.remove(path) + + def generate_thumbnail(self): + image = self().draw(color_by_category=True, bbox=False) + return Image.fromarray(image) + + def flag_thumbnail(self, flag=True): + """ + Toggles values to regenerate thumbnail on next thumbnail request + """ + if self.regenerate_thumbnail != flag: + self.update(regenerate_thumbnail=flag) + + def copy_annotations(self, annotations): + """ + Creates a copy of the annotations for this image + :param annotations: QuerySet of annotation models + :return: number of annotations + """ + annotations = annotations.filter( + width=self.width, height=self.height, area__gt=0).exclude('events') + + for annotation in annotations: + clone = annotation.clone() + + clone.dataset_id = self.dataset_id + clone.image_id = self.id + + clone.save(copy=True) + + return annotations.count() + + @property + def dataset(self): + if self._dataset is None: + self._dataset = DatasetModel.objects(id=self.dataset_id).first() + return self._dataset + + def __call__(self): + + image = im.Image.from_path(self.path) + for annotation in AnnotationModel.objects(image_id=self.id, deleted=False).all(): + if not annotation.is_empty(): + image.add(annotation()) + + return image + + def can_delete(self, user): + return user.can_delete(self.dataset) + + def can_download(self, user): + return user.can_download(self.dataset) + + # TODO: Fix why using the functions throws an error + def permissions(self, user): + return { + 'delete': True, + 'download': True + } + + def add_event(self, e): + u = { + 'push__events': e, + } + if isinstance(e, SessionEvent): + u['inc__milliseconds'] = e.milliseconds + + self.update(**u) + + +__all__ = ["ImageModel"] \ No newline at end of file diff --git a/backend/database/lisence.py b/backend/database/lisence.py new file mode 100644 index 00000000..d5d35997 --- /dev/null +++ b/backend/database/lisence.py @@ -0,0 +1,10 @@ +from mongoengine import * + + +class LicenseModel(DynamicDocument): + id = SequenceField(primary_key=True) + name = StringField() + url = StringField() + + +__all__ = ["LicenseModel"] \ No newline at end of file diff --git a/backend/database/tasks.py b/backend/database/tasks.py new file mode 100644 index 00000000..7a9e622a --- /dev/null +++ b/backend/database/tasks.py @@ -0,0 +1,99 @@ +from mongoengine import * + +import datetime + + +class TaskModel(DynamicDocument): + id = SequenceField(primary_key=True) + + # Type of task: Importer, Exporter, Scanner, etc. + group = StringField(required=True) + name = StringField(required=True) + desciption = StringField() + status = StringField(default="PENDING") + creator = StringField() + + #: Start date of the executor + start_date = DateTimeField() + #: End date of the executor + end_date = DateTimeField() + completed = BooleanField(default=False) + failed = BooleanField(default=False) + has_download = BooleanField(default=False) + + # If any of the information is relevant to the task + # it should be added + dataset_id = IntField() + image_id = IntField() + category_id = IntField() + + progress = FloatField(default=0, min_value=0, max_value=100) + + logs = ListField(default=[]) + errors = IntField(default=0) + warnings = IntField(default=0) + + priority = IntField() + + metadata = DictField(default={}) + + _update_every = 10 + _progress_update = 0 + + def error(self, string): + self._log(string, level="ERROR") + + def warning(self, string): + self._log(string, level="WARNING") + + def info(self, string): + self._log(string, level="INFO") + + def _log(self, string, level): + + level = level.upper() + date = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S") + + message = f"[{date}] [{level}] {string}" + + statment = { + 'push__logs': message + } + + if level == "ERROR": + statment['inc__errors'] = 1 + self.errors += 1 + + if level == "WARNING": + statment['inc__warnings'] = 1 + self.warnings += 1 + + self.update(**statment) + + def set_progress(self, percent, socket=None): + + self.update(progress=int(percent), completed=(percent >= 100)) + + # Send socket update every 10% + if self._progress_update < percent or percent >= 100: + + if socket is not None: + # logger.debug(f"Emitting {percent} progress update for task {self.id}") + + socket.emit('taskProgress', { + 'id': self.id, + 'progress': percent, + 'errors': self.errors, + 'warnings': self.warnings + }, broadcast=True) + + self._progress_update += self._update_every + + def api_json(self): + return { + "id": self.id, + "name": self.name + } + + +__all__ = ["TaskModel"] \ No newline at end of file diff --git a/backend/database/users.py b/backend/database/users.py new file mode 100644 index 00000000..d154ab4d --- /dev/null +++ b/backend/database/users.py @@ -0,0 +1,96 @@ +import datetime + +from mongoengine import * +from flask_login import UserMixin + +from .annotations import AnnotationModel +from .categories import CategoryModel +from .datasets import DatasetModel +from .images import ImageModel + + +class UserModel(DynamicDocument, UserMixin): + + password = StringField(required=True) + username = StringField(max_length=25, required=True, unique=True) + email = StringField(max_length=30) + + name = StringField() + online = BooleanField(default=False) + last_seen = DateTimeField() + + is_admin = BooleanField(default=False) + + preferences = DictField(default={}) + permissions = ListField(defualt=[]) + + # meta = {'allow_inheritance': True} + + @property + def datasets(self): + self._update_last_seen() + + if self.is_admin: + return DatasetModel.objects + + return DatasetModel.objects(Q(owner=self.username) | Q(users__contains=self.username)) + + @property + def categories(self): + self._update_last_seen() + + if self.is_admin: + return CategoryModel.objects + + dataset_ids = self.datasets.distinct('categories') + return CategoryModel.objects(Q(id__in=dataset_ids) | Q(creator=self.username)) + + @property + def images(self): + self._update_last_seen() + + if self.is_admin: + return ImageModel.objects + + dataset_ids = self.datasets.distinct('id') + return ImageModel.objects(dataset_id__in=dataset_ids) + + @property + def annotations(self): + self._update_last_seen() + + if self.is_admin: + return AnnotationModel.objects + + image_ids = self.images.distinct('id') + return AnnotationModel.objects(image_id__in=image_ids) + + def can_view(self, model): + if model is None: + return False + + return model.can_view(self) + + def can_download(self, model): + if model is None: + return False + + return model.can_download(self) + + def can_delete(self, model): + if model is None: + return False + return model.can_delete(self) + + def can_edit(self, model): + if model is None: + return False + + return model.can_edit(self) + + def _update_last_seen(self): + self.update(last_seen=datetime.datetime.utcnow()) + + + +__all__ = ["UserModel"] \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 00000000..cd431702 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,18 @@ +eventlet==0.24.1 +opencv-python==4.0.0.21 +flask==1.0.2 +flask-cors==3.0.7 +flask-login==0.4.1 +flask-restplus==0.12.1 +flask-mongoengine==0.9.5 +numpy +cython +scikit-image +requests +google_images_download==2.5.0 +watchdog==0.8.3 +pytest==3.9.3 +pytest-ordering==0.6 +imantics==0.1.9 +flask-socketio==3.3.2 +celery==4.2.2 diff --git a/backend/set_path.py b/backend/set_path.py new file mode 100644 index 00000000..252cddbc --- /dev/null +++ b/backend/set_path.py @@ -0,0 +1,10 @@ + +import sys + +paths = [ + '/workspace/' +] + +for path in paths: + if path not in sys.path: + sys.path.append(path) diff --git a/backend/tests/Dockerfile b/backend/tests/Dockerfile new file mode 100644 index 00000000..69d3ffa7 --- /dev/null +++ b/backend/tests/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.6 + +WORKDIR /workspace/ + +# Install python package dependices +COPY ./backend/ /workspace/ +COPY ./.git /workspace/.git + +RUN pip install -r requirements.txt &&\ + pip install pycocotools + +ENV LOGIN_DISABLED=true +CMD pytest diff --git a/app/util/__init__.py b/backend/tests/__init__.py similarity index 100% rename from app/util/__init__.py rename to backend/tests/__init__.py diff --git a/tests/api/test_category.py b/backend/tests/api/test_category.py similarity index 64% rename from tests/api/test_category.py rename to backend/tests/api/test_category.py index 1ad52e58..acd82d25 100644 --- a/tests/api/test_category.py +++ b/backend/tests/api/test_category.py @@ -1,7 +1,7 @@ import json import pytest -from app.models import CategoryModel +from database import CategoryModel category1_id = 0 category2_id = 0 @@ -51,7 +51,6 @@ def test_post_categories(self, client): response = client.post("/api/category/", json=data) r = json.loads(response.data) - print(data) assert response.status_code == 200 assert r.get("name") == data.get("name") assert r.get("color") == data.get("color") @@ -104,6 +103,54 @@ def test_get(self, client): response = client.delete("/api/category/{}".format(category3_id)) assert response.status_code == 200 + @pytest.mark.run(after='test_post_categories') + def test_put_equal(self, client): + """ Test response when the name to update is the same as already stored """ + data = { + "name": "test1" + } + response = client.put("/api/category/{}".format(category1_id), json=data) + assert response.status_code == 200 + + def test_put_invalid_id(self, client): + """ Test response when id does not exit """ + response = client.put("/api/category/1000") + assert response.status_code == 400 + + def test_put_not_unique(self, client): + """ Test response when the name already exits """ + data = { + "name": "test2" + } + response = client.put("/api/category/{}".format(category1_id), json=data) + assert response.status_code == 400 + + def test_put_empty(self, client): + """ Test response when category name is empty""" + data = { + "name": "" + } + response = client.put("/api/category/{}".format(category1_id), json=data) + assert response.status_code == 400 + + @pytest.mark.run(after='test_put_not_unique') + def test_put(self, client): + """ Test response when update is correct""" + data = { + "name": "test1_updated" + } + response = client.put("/api/category/{}".format(category1_id), json=data) + assert response.status_code == 200 + + @pytest.mark.run(after='test_put') + def test_put_reset(self, client): + """ Reset test after a correct update """ + data = { + "name": "test1" + } + response = client.put("/api/category/{}".format(category1_id), json=data) + assert response.status_code == 200 + class TestCategoryData: diff --git a/tests/api/test_image.py b/backend/tests/api/test_image.py similarity index 84% rename from tests/api/test_image.py rename to backend/tests/api/test_image.py index 62771257..8e628322 100644 --- a/tests/api/test_image.py +++ b/backend/tests/api/test_image.py @@ -37,9 +37,4 @@ def test_get_invalid_id(self, client): assert response.status_code == 400 -class TestImageThumbnail: - def test_invalid_id(self, client): - response = client.get("/api/image/1000/thumbnail") - assert response.status_code == 400 - diff --git a/tests/api/test_info.py b/backend/tests/api/test_info.py similarity index 100% rename from tests/api/test_info.py rename to backend/tests/api/test_info.py diff --git a/tests/api/test_user.py b/backend/tests/api/test_user.py similarity index 93% rename from tests/api/test_user.py rename to backend/tests/api/test_user.py index 0e9dea05..06e4a7ab 100644 --- a/tests/api/test_user.py +++ b/backend/tests/api/test_user.py @@ -1,7 +1,7 @@ import json import pytest -from app.models import UserModel +from database import UserModel @pytest.mark.second diff --git a/tests/conftest.py b/backend/tests/conftest.py similarity index 80% rename from tests/conftest.py rename to backend/tests/conftest.py index 7b7fc41f..0875e78b 100644 --- a/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,5 +1,5 @@ import pytest -from app import app +from webserver import app @pytest.fixture diff --git a/tests/models/test_upsert.py b/backend/tests/models/test_upsert.py similarity index 94% rename from tests/models/test_upsert.py rename to backend/tests/models/test_upsert.py index efb9d67d..c37b52e4 100644 --- a/tests/models/test_upsert.py +++ b/backend/tests/models/test_upsert.py @@ -1,4 +1,4 @@ -from app.models import CategoryModel, upsert +from database import CategoryModel, upsert category1 = { "name": "Upsert Category", diff --git a/tests/test_app.py b/backend/tests/test_app.py similarity index 100% rename from tests/test_app.py rename to backend/tests/test_app.py diff --git a/backend/webserver/Dockerfile b/backend/webserver/Dockerfile new file mode 100644 index 00000000..cb8fe628 --- /dev/null +++ b/backend/webserver/Dockerfile @@ -0,0 +1,16 @@ +FROM jsbroks/coco-annotator:python-env + +WORKDIR /workspace/ + +# Install python package dependices +COPY ./backend/ /workspace/ +COPY ./.git /workspace/.git +RUN python set_path.py + +ENV FLASK_ENV=development +ENV DEBUG=true + +EXPOSE 5000 +CMD gunicorn -c webserver/gunicorn_config.py webserver:app --no-sendfile + + diff --git a/app/__init__.py b/backend/webserver/__init__.py similarity index 52% rename from app/__init__.py rename to backend/webserver/__init__.py index d830f09c..f6d5f9a9 100644 --- a/app/__init__.py +++ b/backend/webserver/__init__.py @@ -1,41 +1,43 @@ +import eventlet +eventlet.monkey_patch(thread=False) + +import sys +import workers + +from config import Config +from database import ( + connect_mongo, + ImageModel, + create_from_json +) + from flask import Flask -from werkzeug.contrib.fixers import ProxyFix from flask_cors import CORS -from watchdog.observers import Observer +from flask_socketio import SocketIO +from werkzeug.contrib.fixers import ProxyFix + +from celery import Celery -from .image_folder import ImageFolderHandler +from .watcher import run_watcher from .api import blueprint as api -from .config import Config -from .models import * +from .util import query_util from .authentication import login_manager -from .util import query_util, color_util +from .sockets import socketio import threading import requests +import logging import time import os -def run_watcher(): - observer = Observer() - observer.schedule(ImageFolderHandler(), Config.DATASET_DIRECTORY, recursive=True) - observer.start() - - try: - while True: - time.sleep(1) - except KeyboardInterrupt: - observer.stop() - - observer.join() +connect_mongo('webserver') def create_app(): - if os.environ.get("APP_WORKER_ID", "1") == "1" and not Config.TESTING: - print("Creating file watcher on PID: {}".format(os.getpid()), flush=True) - watcher_thread = threading.Thread(target=run_watcher) - watcher_thread.start() + if Config.FILE_WATCHER: + run_watcher() flask = Flask(__name__, static_url_path='', @@ -48,29 +50,31 @@ def create_app(): flask.wsgi_app = ProxyFix(flask.wsgi_app) flask.register_blueprint(api) - db.init_app(flask) login_manager.init_app(flask) + socketio.init_app(flask, message_queue=Config.CELERY_BROKER_URL) + # Remove all poeple who were annotating when + # the server shutdown + ImageModel.objects.update(annotating=[]) return flask app = create_app() +logger = logging.getLogger('gunicorn.error') +app.logger.handlers = logger.handlers +app.logger.setLevel(logger.level) + if Config.INITIALIZE_FROM_FILE: create_from_json(Config.INITIALIZE_FROM_FILE) -if Config.LOAD_IMAGES_ON_START: - ImageModel.load_images(Config.DATASET_DIRECTORY) - @app.route('/', defaults={'path': ''}) @app.route('/') def index(path): - + if app.debug: return requests.get('http://frontend:8080/{}'.format(path)).text return app.send_static_file('index.html') - - diff --git a/app/api/__init__.py b/backend/webserver/api/__init__.py similarity index 80% rename from app/api/__init__.py rename to backend/webserver/api/__init__.py index 36420bc1..280028d2 100644 --- a/app/api/__init__.py +++ b/backend/webserver/api/__init__.py @@ -5,13 +5,16 @@ from .categories import api as ns_categories from .annotator import api as ns_annotator from .datasets import api as ns_datasets +from .exports import api as ns_exports from .images import api as ns_images +from .models import api as ns_models from .users import api as ns_users from .admin import api as ns_admin +from .tasks import api as ns_tasks from .undo import api as ns_undo from .info import api as ns_info -from ..config import Config +from config import Config # Create /api/ space blueprint = Blueprint('api', __name__, url_prefix='/api') @@ -31,8 +34,11 @@ api.add_namespace(ns_images) api.add_namespace(ns_annotations) api.add_namespace(ns_categories) -api.add_namespace(ns_annotator) api.add_namespace(ns_datasets) +api.add_namespace(ns_exports) +api.add_namespace(ns_tasks) api.add_namespace(ns_undo) +api.add_namespace(ns_models) api.add_namespace(ns_admin) +api.add_namespace(ns_annotator) diff --git a/app/api/admin.py b/backend/webserver/api/admin.py similarity index 98% rename from app/api/admin.py rename to backend/webserver/api/admin.py index db21d383..c7575b24 100644 --- a/app/api/admin.py +++ b/backend/webserver/api/admin.py @@ -2,7 +2,7 @@ from flask_restplus import Namespace, Resource, reqparse from werkzeug.security import generate_password_hash -from ..models import UserModel +from database import UserModel from ..util.query_util import fix_ids api = Namespace('admin', description='Admin related operations') @@ -42,7 +42,7 @@ def get(self): total = user_model.count() pages = int(total/per_page) + 1 - user_model = user_model.skip(page*per_page).limit(per_page).exclude("preferences") + user_model = user_model.skip(page*per_page).limit(per_page).exclude("preferences", "password") return { "total": total, diff --git a/app/api/annotations.py b/backend/webserver/api/annotations.py similarity index 63% rename from app/api/annotations.py rename to backend/webserver/api/annotations.py index 8b7cde36..2c539805 100644 --- a/app/api/annotations.py +++ b/backend/webserver/api/annotations.py @@ -1,17 +1,22 @@ from flask_restplus import Namespace, Resource, reqparse from flask_login import login_required, current_user -from ..models import AnnotationModel -from ..util import query_util, color_util +from database import AnnotationModel +from ..util import query_util import datetime +import logging +logger = logging.getLogger('gunicorn.error') api = Namespace('annotation', description='Annotation related operations') create_annotation = reqparse.RequestParser() -create_annotation.add_argument('image_id', type=int, required=True, location='json') +create_annotation.add_argument( + 'image_id', type=int, required=True, location='json') create_annotation.add_argument('category_id', type=int, location='json') create_annotation.add_argument('metadata', type=dict, location='json') +create_annotation.add_argument('segmentation', type=list, location='json') +create_annotation.add_argument('keypoints', type=list, location='json') create_annotation.add_argument('color', location='json') @@ -31,11 +36,24 @@ def post(self): image_id = args.get('image_id') category_id = args.get('category_id') metadata = args.get('metadata', {}) - color = args.get('color') + segmentation = args.get('segmentation', []) + keypoints = args.get('keypoints', []) + + image = current_user.images.filter(id=image_id, deleted=False).first() + if image is None: + return {"message": "Invalid image id"}, 400 + + logger.info( + f'{current_user.username} has created an annotation for image {image_id}') try: - annotation = AnnotationModel(image_id=image_id, category_id=category_id, metadata=metadata) - annotation.color = color_util.random_color_hex() if color is None else color + annotation = AnnotationModel( + image_id=image_id, + category_id=category_id, + metadata=metadata, + segmentation=segmentation, + keypoints=keypoints + ) annotation.save() except (ValueError, TypeError) as e: return {'message': str(e)}, 400 @@ -64,7 +82,12 @@ def delete(self, annotation_id): if annotation is None: return {"message": "Invalid annotation id"}, 400 - annotation.update(set__deleted=True, set__deleted_date=datetime.datetime.now()) + image = current_user.images.filter( + id=annotation.image_id, deleted=False).first() + image.flag_thumbnail() + + annotation.update(set__deleted=True, + set__deleted_date=datetime.datetime.now()) return {'success': True} @@ -73,5 +96,3 @@ def delete(self, annotation_id): # def get(self, annotation_id): # """ Returns the binary mask of an annotation """ # return query_util.fix_ids(AnnotationModel.objects(id=annotation_id).first()) - - diff --git a/app/api/annotator.py b/backend/webserver/api/annotator.py similarity index 60% rename from app/api/annotator.py rename to backend/webserver/api/annotator.py index a772cd30..3e647057 100644 --- a/app/api/annotator.py +++ b/backend/webserver/api/annotator.py @@ -1,11 +1,18 @@ +import datetime + from flask_restplus import Namespace, Resource from flask_login import login_required, current_user from flask import request -from ..util import query_util -from ..util import coco_util -from ..models import * +from ..util import query_util, coco_util, profile +from config import Config +from database import ( + ImageModel, + CategoryModel, + AnnotationModel, + SessionEvent +) api = Namespace('annotator', description='Annotator related operations') @@ -13,6 +20,7 @@ @api.route('/data') class AnnotatorData(Resource): + @profile @login_required def post(self): """ @@ -20,17 +28,21 @@ def post(self): """ data = request.get_json(force=True) image = data.get('image') + dataset = data.get('dataset') image_id = image.get('id') - + image_model = ImageModel.objects(id=image_id).first() - # Check if current user can access dataset - if current_user.datasets.filter(id=image_model.dataset_id).first() is None: - return {'success': False, 'message': 'Could not find associated dataset'} - if image_model is None: return {'success': False, 'message': 'Image does not exist'}, 400 + # Check if current user can access dataset + db_dataset = current_user.datasets.filter(id=image_model.dataset_id).first() + if dataset is None: + return {'success': False, 'message': 'Could not find associated dataset'} + + db_dataset.update(annotate_url=dataset.get('annotate_url', '')) + categories = CategoryModel.objects.all() annotations = AnnotationModel.objects(image_id=image_id) @@ -46,7 +58,12 @@ def post(self): if db_category is None: continue - db_category.update(set__color=category.get('color')) + category_update = {'color': category.get('color')} + if current_user.can_edit(db_category): + category_update['keypoint_edges'] = category.get('keypoint_edges', []) + category_update['keypoint_labels'] = category.get('keypoint_labels', []) + + db_category.update(**category_update) # Iterate every annotation from the data annotations for annotation in category.get('annotations', []): @@ -62,7 +79,23 @@ def post(self): # the annotation twice, checking if the paperjs exists. # Update annotation in database + sessions = [] + total_time = 0 + for session in annotation.get('sessions', []): + date = datetime.datetime.fromtimestamp(int(session.get('start')) / 1e3) + model = SessionEvent( + user=current_user.username, + created_at=date, + milliseconds=session.get('milliseconds'), + tools_used=session.get('tools') + ) + total_time += session.get('milliseconds') + sessions.append(model) + db_annotation.update( + add_to_set__events=sessions, + inc__milliseconds=total_time, + set__keypoints=annotation.get('keypoints', []), set__metadata=annotation.get('metadata'), set__color=annotation.get('color') ) @@ -92,19 +125,24 @@ def post(self): image_model.update( set__metadata=image.get('metadata', {}), set__annotated=annotated, - set__category_ids=image.get('category_ids', []) + set__category_ids=image.get('category_ids', []), + set__regenerate_thumbnail=annotated, + set__num_annotations=annotations\ + .filter(deleted=False, area__gt=0).count() ) - return data + return {"success": True} @api.route('/data/') class AnnotatorId(Resource): + @profile @login_required def get(self, image_id): """ Called when loading from the annotator client """ - image = ImageModel.objects(id=image_id).first() + image = ImageModel.objects(id=image_id)\ + .exclude('events').first() if image is None: return {'success': False, 'message': 'Could not load image'}, 400 @@ -113,30 +151,39 @@ def get(self, image_id): if dataset is None: return {'success': False, 'message': 'Could not find associated dataset'}, 400 - categories = CategoryModel.objects(deleted=False).in_bulk(dataset.categories).items() + categories = CategoryModel.objects(deleted=False)\ + .in_bulk(dataset.categories).items() # Get next and previous image - images = list(ImageModel.objects(dataset_id=dataset.id, deleted=False).order_by('file_name').all()) - image_index = images.index(image) - image_previous = None if image_index - 1 < 0 else images[image_index - 1].id - image_next = None if image_index + 1 == len(images) else images[image_index + 1].id + images = ImageModel.objects(dataset_id=dataset.id, deleted=False) + pre = images.filter(file_name__lt=image.file_name).order_by('-file_name').first() + nex = images.filter(file_name__gt=image.file_name).order_by('file_name').first() + + preferences = {} + if not Config.LOGIN_DISABLED: + preferences = current_user.preferences # Generate data about the image to return to client data = { 'image': query_util.fix_ids(image), 'categories': [], 'dataset': query_util.fix_ids(dataset), - 'settings': [] + 'preferences': preferences, + 'permissions': { + 'dataset': dataset.permissions(current_user), + 'image': image.permissions(current_user) + } } - data['image']['previous'] = image_previous - data['image']['next'] = image_next + data['image']['previous'] = pre.id if pre else None + data['image']['next'] = nex.id if nex else None for category in categories: category = query_util.fix_ids(category[1]) category_id = category.get('id') - annotations = AnnotationModel.objects(image_id=image_id, category_id=category_id, deleted=False).all() + annotations = AnnotationModel.objects(image_id=image_id, category_id=category_id, deleted=False)\ + .exclude('events').all() category['show'] = True category['visualize'] = False diff --git a/app/api/categories.py b/backend/webserver/api/categories.py similarity index 61% rename from app/api/categories.py rename to backend/webserver/api/categories.py index 56c54142..5e35ee5e 100644 --- a/app/api/categories.py +++ b/backend/webserver/api/categories.py @@ -1,9 +1,10 @@ from flask_restplus import Namespace, Resource, reqparse from flask_login import login_required, current_user +from mongoengine.errors import NotUniqueError from ..util.pagination_util import Pagination -from ..util import query_util, color_util -from ..models import CategoryModel, AnnotationModel +from ..util import query_util +from database import CategoryModel, AnnotationModel import datetime @@ -15,6 +16,9 @@ create_category.add_argument('color', location='json') create_category.add_argument('metadata', type=dict, location='json') +update_category = reqparse.RequestParser() +update_category.add_argument('name', required=True, location='json') + page_data = reqparse.RequestParser() page_data.add_argument('page', default=1, type=int) page_data.add_argument('limit', default=20, type=int) @@ -37,7 +41,7 @@ def post(self): supercategory = args.get('supercategory') metadata = args.get('metadata', {}) color = args.get('color') - + try: category = CategoryModel( name=name, @@ -46,8 +50,8 @@ def post(self): metadata=metadata ) category.save() - except (ValueError, TypeError) as e: - return {'message': str(e)}, 400 + except NotUniqueError as e: + return {'message': 'Category already exists. Check the undo tab to fully delete the category.'}, 400 return query_util.fix_ids(category) @@ -71,10 +75,49 @@ def delete(self, category_id): category = current_user.categories.filter(id=category_id).first() if category is None: return {"message": "Invalid image id"}, 400 + + if not current_user.can_delete(category): + return {"message": "You do not have permission to delete this category"}, 403 category.update(set__deleted=True, set__deleted_date=datetime.datetime.now()) return {'success': True} + @api.expect(update_category) + @login_required + def put(self, category_id): + """ Updates a category name by ID """ + + category = current_user.categories.filter(id=category_id).first() + + # check if the id exits + if category is None: + return {"message": "Invalid category id"}, 400 + + args = update_category.parse_args() + name_to_update = args.get('name') + + # check if the name to update is the same as already stored + if category.name == name_to_update: + return {"message": "Nothing to update"}, 200 + + # check if the name is empty + if not name_to_update: + return {"message": "Invalid category name to update"}, 400 + + # update name of the category + # check if the name to update exits already in db + # @ToDo: Is it necessary to allow equal category names among different creators? + category.name = name_to_update + try: + category.update( + name=category.name + ) + except NotUniqueError: + # it is only triggered when the name already exists and the creator is the same + return {"message": "Category '" + name_to_update + "' already exits"}, 400 + + return {"success": True} + @api.route('/data') class CategoriesData(Resource): diff --git a/backend/webserver/api/datasets.py b/backend/webserver/api/datasets.py new file mode 100644 index 00000000..94edf02a --- /dev/null +++ b/backend/webserver/api/datasets.py @@ -0,0 +1,523 @@ +from flask import request +from flask_restplus import Namespace, Resource, reqparse +from flask_login import login_required, current_user +from werkzeug.datastructures import FileStorage +from mongoengine.errors import NotUniqueError +from threading import Thread + +from google_images_download import google_images_download as gid + +from ..util.pagination_util import Pagination +from ..util import query_util, coco_util, profile + +from database import ( + ImageModel, + DatasetModel, + CategoryModel, + AnnotationModel, + ExportModel +) + +import datetime +import json +import os + +api = Namespace('dataset', description='Dataset related operations') + + +dataset_create = reqparse.RequestParser() +dataset_create.add_argument('name', required=True) +dataset_create.add_argument('categories', type=list, required=False, location='json', + help="List of default categories for sub images") + +page_data = reqparse.RequestParser() +page_data.add_argument('page', default=1, type=int) +page_data.add_argument('limit', default=20, type=int) +page_data.add_argument('folder', default='', help='Folder for data') +page_data.add_argument('order', default='file_name', help='Order to display images') + +delete_data = reqparse.RequestParser() +delete_data.add_argument('fully', default=False, type=bool, + help="Fully delete dataset (no undo)") + +coco_upload = reqparse.RequestParser() +coco_upload.add_argument('coco', location='files', type=FileStorage, required=True, help='Json coco') + +export = reqparse.RequestParser() +export.add_argument('categories', type=str, default=None, required=False, help='Ids of categories to export') + +update_dataset = reqparse.RequestParser() +update_dataset.add_argument('categories', location='json', type=list, help="New list of categories") +update_dataset.add_argument('default_annotation_metadata', location='json', type=dict, + help="Default annotation metadata") + +dataset_generate = reqparse.RequestParser() +dataset_generate.add_argument('keywords', location='json', type=list, default=[], + help="Keywords associated with images") +dataset_generate.add_argument('limit', location='json', type=int, default=100, help="Number of images per keyword") + +share = reqparse.RequestParser() +share.add_argument('users', location='json', type=list, default=[], help="List of users") + + +@api.route('/') +class Dataset(Resource): + @login_required + def get(self): + """ Returns all datasets """ + return query_util.fix_ids(current_user.datasets.filter(deleted=False).all()) + + @api.expect(dataset_create) + @login_required + def post(self): + """ Creates a dataset """ + args = dataset_create.parse_args() + name = args['name'] + categories = args.get('categories', []) + + category_ids = CategoryModel.bulk_create(categories) + + try: + dataset = DatasetModel(name=name, categories=category_ids) + dataset.save() + except NotUniqueError: + return {'message': 'Dataset already exists. Check the undo tab to fully delete the dataset.'}, 400 + + return query_util.fix_ids(dataset) + + +def download_images(output_dir, args): + for keyword in args['keywords']: + response = gid.googleimagesdownload() + response.download({ + "keywords": keyword, + "limit": args['limit'], + "output_directory": output_dir, + "no_numbering": True, + "format": "jpg", + "type": "photo", + "print_urls": False, + "print_paths": False, + "print_size": False + }) + + +@api.route('//generate') +class DatasetGenerate(Resource): + @api.expect(dataset_generate) + @login_required + def post(self, dataset_id): + """ Adds images found on google to the dataset """ + args = dataset_generate.parse_args() + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + if not dataset.is_owner(current_user): + return {"message": "You do not have permission to download the dataset's annotations"}, 403 + + thread = Thread(target=download_images, args=(dataset.directory, args)) + thread.start() + + return {"success": True} + + +@api.route('//users') +class DatasetMembers(Resource): + + @login_required + def get(self, dataset_id): + """ All users in the dataset """ + args = dataset_generate.parse_args() + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + users = dataset.get_users() + return query_util.fix_ids(users) + + +@api.route('//reset/metadata') +class DatasetCleanMeta(Resource): + + @login_required + def get(self, dataset_id): + """ All users in the dataset """ + args = dataset_generate.parse_args() + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + AnnotationModel.objects(dataset_id=dataset.id)\ + .update(metadata=dataset.default_annotation_metadata) + ImageModel.objects(dataset_id=dataset.id)\ + .update(metadata={}) + + return {'success': True} + + +@api.route('//stats') +class DatasetStats(Resource): + + @login_required + def get(self, dataset_id): + """ All users in the dataset """ + args = dataset_generate.parse_args() + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + images = ImageModel.objects(dataset_id=dataset.id, deleted=False) + annotated_images = images.filter(annotated=True) + annotations = AnnotationModel.objects(dataset_id=dataset_id, deleted=False) + stats = { + 'total': { + 'Users': dataset.get_users().count(), + 'Images': images.count(), + 'Annotated Images': annotated_images.count(), + 'Annotations': annotations.count(), + 'Categories': len(dataset.categories), + 'Time Annotating (s)': (images.sum('milliseconds') or 0) / 1000 + }, + 'average': { + 'Image Size (px)': images.average('width'), + 'Image Height (px)': images.average('height'), + 'Annotation Area (px)': annotations.average('area'), + 'Time (ms) per Image': images.average('milliseconds') or 0, + 'Time (ms) per Annotation': annotations.average('milliseconds') or 0 + } + } + return stats + + +@api.route('/') +class DatasetId(Resource): + + @login_required + def delete(self, dataset_id): + """ Deletes dataset by ID (only owners)""" + + dataset = DatasetModel.objects(id=dataset_id, deleted=False).first() + + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + if not current_user.can_delete(dataset): + return {"message": "You do not have permission to delete the dataset"}, 403 + + dataset.update(set__deleted=True, set__deleted_date=datetime.datetime.now()) + return {"success": True} + + @api.expect(update_dataset) + def post(self, dataset_id): + + """ Updates dataset by ID """ + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + args = update_dataset.parse_args() + categories = args.get('categories') + default_annotation_metadata = args.get('default_annotation_metadata') + set_default_annotation_metadata = args.get('set_default_annotation_metadata') + + if categories is not None: + dataset.categories = CategoryModel.bulk_create(categories) + + if default_annotation_metadata is not None: + + update = {} + for key, value in default_annotation_metadata.items(): + if key not in dataset.default_annotation_metadata: + update[f'set__metadata__{key}'] = value + + dataset.default_annotation_metadata = default_annotation_metadata + + if len(update.keys()) > 0: + AnnotationModel.objects(dataset_id=dataset.id, deleted=False)\ + .update(**update) + + dataset.update( + categories=dataset.categories, + default_annotation_metadata=dataset.default_annotation_metadata + ) + + return {"success": True} + + +@api.route('//share') +class DatasetIdShare(Resource): + @api.expect(share) + @login_required + def post(self, dataset_id): + args = share.parse_args() + + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {"message": "Invalid dataset id"}, 400 + + if not dataset.is_owner(current_user): + return {"message": "You do not have permission to share this dataset"}, 403 + + dataset.update(users=args.get('users')) + + return {"success": True} + + +@api.route('/data') +class DatasetData(Resource): + @api.expect(page_data) + @login_required + def get(self): + """ Endpoint called by dataset viewer client """ + + args = page_data.parse_args() + limit = args['limit'] + page = args['page'] + folder = args['folder'] + + datasets = current_user.datasets.filter(deleted=False) + pagination = Pagination(datasets.count(), limit, page) + datasets = datasets[pagination.start:pagination.end] + + datasets_json = [] + for dataset in datasets: + dataset_json = query_util.fix_ids(dataset) + images = ImageModel.objects(dataset_id=dataset.id, deleted=False) + + dataset_json['numberImages'] = images.count() + dataset_json['numberAnnotated'] = images.filter(annotated=True).count() + dataset_json['permissions'] = dataset.permissions(current_user) + + first = images.first() + if first is not None: + dataset_json['first_image_id'] = images.first().id + datasets_json.append(dataset_json) + + return { + "pagination": pagination.export(), + "folder": folder, + "datasets": datasets_json, + "categories": query_util.fix_ids(current_user.categories.filter(deleted=False).all()) + } + +@api.route('//data') +class DatasetDataId(Resource): + + @profile + @api.expect(page_data) + @login_required + def get(self, dataset_id): + """ Endpoint called by image viewer client """ + + parsed_args = page_data.parse_args() + per_page = parsed_args.get('limit') + page = parsed_args.get('page') - 1 + folder = parsed_args.get('folder') + order = parsed_args.get('order') + + args = dict(request.args) + + # Check if dataset exists + dataset = current_user.datasets.filter(id=dataset_id, deleted=False).first() + if dataset is None: + return {'message', 'Invalid dataset id'}, 400 + + # Make sure folder starts with is in proper format + if len(folder) > 0: + folder = folder[0].strip('/') + folder[1:] + if folder[-1] != '/': + folder = folder + '/' + + # Get directory + directory = os.path.join(dataset.directory, folder) + if not os.path.exists(directory): + return {'message': 'Directory does not exist.'}, 400 + + # Remove parsed arguments + for key in parsed_args: + args.pop(key, None) + + # Generate query from remaining arugments + query = {} + for key, value in args.items(): + lower = value.lower() + if lower in ["true", "false"]: + value = json.loads(lower) + + if len(lower) != 0: + query[key] = value + + images = current_user.images \ + .filter(dataset_id=dataset_id, path__startswith=directory, deleted=False, **query) \ + .order_by(order).only('id', 'file_name', 'annotating', 'annotated', 'num_annotations') + + total = images.count() + pages = int(total/per_page) + 1 + + images = images.skip(page*per_page).limit(per_page) + images_json = query_util.fix_ids(images) + # for image in images: + # image_json = query_util.fix_ids(image) + + # query = AnnotationModel.objects(image_id=image.id, deleted=False) + # category_ids = query.distinct('category_id') + # categories = CategoryModel.objects(id__in=category_ids).only('name', 'color') + + # image_json['annotations'] = query.count() + # image_json['categories'] = query_util.fix_ids(categories) + + # images_json.append(image_json) + + + subdirectories = [f for f in sorted(os.listdir(directory)) + if os.path.isdir(directory + f) and not f.startswith('.')] + + categories = CategoryModel.objects(id__in=dataset.categories).only('id', 'name') + + return { + "total": total, + "per_page": per_page, + "pages": pages, + "page": page, + "images": images_json, + "folder": folder, + "directory": directory, + "dataset": query_util.fix_ids(dataset), + "categories": query_util.fix_ids(categories), + "subdirectories": subdirectories + } + + +@api.route('//exports') +class DatasetExports(Resource): + + @login_required + def get(self, dataset_id): + """ Returns exports of images and annotations in the dataset (only owners) """ + dataset = current_user.datasets.filter(id=dataset_id).first() + + if dataset is None: + return {"message": "Invalid dataset ID"}, 400 + + if not current_user.can_download(dataset): + return {"message": "You do not have permission to download the dataset's annotations"}, 403 + + exports = ExportModel.objects(dataset_id=dataset.id).order_by('-created_at').limit(50) + + dict_export = [] + for export in exports: + + time_delta = datetime.datetime.utcnow() - export.created_at + dict_export.append({ + 'id': export.id, + 'ago': query_util.td_format(time_delta), + 'tags': export.tags + }) + + return dict_export + + +@api.route('//export') +class DatasetExport(Resource): + + @api.expect(export) + @login_required + def get(self, dataset_id): + + args = export.parse_args() + categories = args.get('categories') + + if len(categories) == 0: + categories = [] + + if len(categories) > 0 or isinstance(categories, str): + categories = [int(c) for c in categories.split(',')] + + dataset = DatasetModel.objects(id=dataset_id).first() + + if not dataset: + return {'message': 'Invalid dataset ID'}, 400 + + return dataset.export_coco(categories=categories) + + @api.expect(coco_upload) + @login_required + def post(self, dataset_id): + """ Adds coco formatted annotations to the dataset """ + args = coco_upload.parse_args() + coco = args['coco'] + + dataset = current_user.datasets.filter(id=dataset_id).first() + if dataset is None: + return {'message': 'Invalid dataset ID'}, 400 + + return dataset.import_coco(json.load(coco)) + + +@api.route('//coco') +class DatasetCoco(Resource): + + @login_required + def get(self, dataset_id): + """ Returns coco of images and annotations in the dataset (only owners) """ + dataset = current_user.datasets.filter(id=dataset_id).first() + + if dataset is None: + return {"message": "Invalid dataset ID"}, 400 + + if not current_user.can_download(dataset): + return {"message": "You do not have permission to download the dataset's annotations"}, 403 + + return coco_util.get_dataset_coco(dataset) + + @api.expect(coco_upload) + @login_required + def post(self, dataset_id): + """ Adds coco formatted annotations to the dataset """ + args = coco_upload.parse_args() + coco = args['coco'] + + dataset = current_user.datasets.filter(id=dataset_id).first() + if dataset is None: + return {'message': 'Invalid dataset ID'}, 400 + + return dataset.import_coco(json.load(coco)) + + +@api.route('/coco/') +class DatasetCocoId(Resource): + + @login_required + def get(self, import_id): + """ Returns current progress and errors of a coco import """ + coco_import = CocoImportModel.objects( + id=import_id, creator=current_user.username).first() + + if not coco_import: + return {'message': 'No such coco import'}, 400 + + return { + "progress": coco_import.progress, + "errors": coco_import.errors + } + + +@api.route('//scan') +class DatasetScan(Resource): + + @login_required + def get(self, dataset_id): + + dataset = DatasetModel.objects(id=dataset_id).first() + + if not dataset: + return {'message': 'Invalid dataset ID'}, 400 + + return dataset.scan() + diff --git a/backend/webserver/api/exports.py b/backend/webserver/api/exports.py new file mode 100644 index 00000000..3d50fa75 --- /dev/null +++ b/backend/webserver/api/exports.py @@ -0,0 +1,71 @@ +from flask import send_file +from flask_restplus import Namespace, Resource, reqparse +from flask_login import login_required, current_user + +import datetime +from ..util import query_util + +from database import ( + ExportModel, + DatasetModel, + fix_ids +) + + +api = Namespace('export', description='Export related operations') + + +@api.route('/') +class DatasetExports(Resource): + + @login_required + def get(self, export_id): + """ Returns exports """ + export = ExportModel.objects(id=export_id).first() + if export is None: + return {"message": "Invalid export ID"}, 400 + + dataset = current_user.datasets.filter(id=export.dataset_id).first() + if dataset is None: + return {"message": "Invalid dataset ID"}, 400 + + time_delta = datetime.datetime.utcnow() - export.created_at + d = fix_ids(export) + d['ago'] = query_util.td_format(time_delta) + return d + + @login_required + def delete(self, export_id): + """ Returns exports """ + export = ExportModel.objects(id=export_id).first() + if export is None: + return {"message": "Invalid export ID"}, 400 + + dataset = current_user.datasets.filter(id=export.dataset_id).first() + if dataset is None: + return {"message": "Invalid dataset ID"}, 400 + + export.delete() + return {'success': True} + + +@api.route('//download') +class DatasetExports(Resource): + + @login_required + def get(self, export_id): + """ Returns exports """ + + export = ExportModel.objects(id=export_id).first() + if export is None: + return {"message": "Invalid export ID"}, 400 + + dataset = current_user.datasets.filter(id=export.dataset_id).first() + if dataset is None: + return {"message": "Invalid dataset ID"}, 400 + + if not current_user.can_download(dataset): + return {"message": "You do not have permission to download the dataset's annotations"}, 403 + + return send_file(export.path, attachment_filename=f"{dataset.name}-{'-'.join(export.tags)}.json", as_attachment=True) + diff --git a/app/api/images.py b/backend/webserver/api/images.py similarity index 74% rename from app/api/images.py rename to backend/webserver/api/images.py index 961d3525..5554d1ca 100644 --- a/app/api/images.py +++ b/backend/webserver/api/images.py @@ -3,9 +3,14 @@ from werkzeug.datastructures import FileStorage from flask import send_file -from ..util import query_util, coco_util, thumbnail_util -from ..models import * - +from ..util import query_util, coco_util +from database import ( + ImageModel, + DatasetModel, + AnnotationModel +) + +from PIL import Image import datetime import os import io @@ -17,8 +22,7 @@ image_all = reqparse.RequestParser() image_all.add_argument('fields', required=False, type=str) image_all.add_argument('page', default=1, type=int) -image_all.add_argument('perPage', default=50, type=int, required=False) - +image_all.add_argument('per_page', default=50, type=int, required=False) image_upload = reqparse.RequestParser() image_upload.add_argument('image', location='files', @@ -28,9 +32,10 @@ help='Folder to insert photo into') image_download = reqparse.RequestParser() -image_download.add_argument('asAttachment', type=bool, required=False, default=False) -image_download.add_argument('width', type=int, required=False, default=0) -image_download.add_argument('height', type=int, required=False, default=0) +image_download.add_argument('asAttachment', type=bool, default=False) +image_download.add_argument('thumbnail', type=bool, default=False) +image_download.add_argument('width', type=int) +image_download.add_argument('height', type=int) copy_annotations = reqparse.RequestParser() copy_annotations.add_argument('category_ids', location='json', type=list, @@ -45,9 +50,9 @@ class Images(Resource): def get(self): """ Returns all images """ args = image_all.parse_args() - per_page = args['perPage'] + per_page = args['per_page'] page = args['page']-1 - fields = args.get('fields', "") + fields = args.get('fields', '') images = current_user.images.filter(deleted=False) total = images.count() @@ -111,26 +116,25 @@ class ImageId(Resource): def get(self, image_id): """ Returns category by ID """ args = image_download.parse_args() - as_attachment = args['asAttachment'] - width = args['width'] - height = args['height'] + as_attachment = args.get('asAttachment') + thumbnail = args.get('thumbnail') image = current_user.images.filter(id=image_id, deleted=False).first() if image is None: return {'success': False}, 400 - if width < 1: + width = args.get('width') + height = args.get('height') + + if not width: width = image.width - - if height < 1: + if not height: height = image.height - - try: - pil_image = Image.open(image.path) - except Exception as e: - return {'message': str(e)}, 400 - + + pil_image = image.thumbnail() if thumbnail else Image.open(image.path) + image.flag_thumbnail(flag=False) + pil_image.thumbnail((width, height), Image.ANTIALIAS) image_io = io.BytesIO() pil_image = pil_image.convert("RGB") @@ -146,6 +150,9 @@ def delete(self, image_id): if image is None: return {"message": "Invalid image id"}, 400 + if not current_user.can_delete(image): + return {"message": "You do not have permission to download the image"}, 403 + image.update(set__deleted=True, set__deleted_date=datetime.datetime.now()) return {"success": True} @@ -183,40 +190,6 @@ def post(self, from_id, to_id): return {'annotations_created': image_to.copy_annotations(query)} -@api.route('//thumbnail') -class ImageCoco(Resource): - - @api.expect(image_download) - @login_required - def get(self, image_id): - """ Returns coco of image and annotations """ - args = image_download.parse_args() - as_attachment = args['asAttachment'] - width = args['width'] - height = args['height'] - - image = current_user.images.filter(id=image_id, deleted=False).first() - - if image is None: - return {'success': False}, 400 - - if width < 1: - width = image.width - - if height < 1: - height = image.height - - pil_image = thumbnail_util.generate_thumbnail(image, save=False) - pil_image.thumbnail((width, height), Image.ANTIALIAS) - - image_io = io.BytesIO() - pil_image = pil_image.convert("RGB") - pil_image.save(image_io, "JPEG", quality=90) - image_io.seek(0) - - return send_file(image_io, attachment_filename=image.file_name, as_attachment=as_attachment) - - @api.route('//coco') class ImageCoco(Resource): @@ -224,9 +197,12 @@ class ImageCoco(Resource): def get(self, image_id): """ Returns coco of image and annotations """ image = current_user.images.filter(id=image_id).exclude('deleted_date').first() - + if image is None: return {"message": "Invalid image ID"}, 400 - return coco_util.get_image_coco(image) + if not current_user.can_download(image): + return {"message": "You do not have permission to download the images's annotations"}, 403 + + return coco_util.get_image_coco(image_id) diff --git a/app/api/info.py b/backend/webserver/api/info.py similarity index 54% rename from app/api/info.py rename to backend/webserver/api/info.py index 81450347..5a933507 100644 --- a/app/api/info.py +++ b/backend/webserver/api/info.py @@ -1,8 +1,8 @@ -from flask_restplus import Namespace, Resource, reqparse +from flask_restplus import Namespace, Resource -from ..config import Config -from ..util.version_util import get_tag -from ..models import UserModel +from workers.tasks import long_task +from config import Config +from database import UserModel, TaskModel api = Namespace('info', description='Software related operations') @@ -19,10 +19,20 @@ def get(self): "demo": "https://annotator.justinbrooks.ca/", "repo": "https://github.com/jsbroks/coco-annotator", "git": { - "tag": get_tag() + "tag": Config.VERSION }, "login_enabled": not Config.LOGIN_DISABLED, "total_users": UserModel.objects.count(), "allow_registration": Config.ALLOW_REGISTRATION } + +@api.route('/long_task') +class TaskTest(Resource): + def get(self): + """ Returns information about current version """ + task_model = TaskModel(group="test", name="Testing Celery") + task_model.save() + + task = long_task.delay(20, task_model.id) + return {'id': task.id, 'state': task.state} \ No newline at end of file diff --git a/backend/webserver/api/models.py b/backend/webserver/api/models.py new file mode 100644 index 00000000..9fa22dad --- /dev/null +++ b/backend/webserver/api/models.py @@ -0,0 +1,81 @@ +from flask_restplus import Namespace, Resource, reqparse +from werkzeug.datastructures import FileStorage +from imantics import Mask +from flask_login import login_required +from config import Config +from PIL import Image +from database import ImageModel + +import os +import logging + +logger = logging.getLogger('gunicorn.error') + + +MASKRCNN_LOADED = os.path.isfile(Config.MASK_RCNN_FILE) +if MASKRCNN_LOADED: + from ..util.mask_rcnn import model as maskrcnn +else: + logger.warning("MaskRCNN model is disabled.") + +DEXTR_LOADED = os.path.isfile(Config.DEXTR_FILE) +if DEXTR_LOADED: + from ..util.dextr import model as dextr +else: + logger.warning("DEXTR model is disabled.") + +api = Namespace('model', description='Model related operations') + + +image_upload = reqparse.RequestParser() +image_upload.add_argument('image', location='files', type=FileStorage, required=True, help='Image') + +dextr_args = reqparse.RequestParser() +dextr_args.add_argument('points', location='json', type=list, required=True) +dextr_args.add_argument('padding', location='json', type=int, default=50) +dextr_args.add_argument('threshold', location='json', type=int, default=80) + + +@api.route('/dextr/') +class MaskRCNN(Resource): + + @login_required + @api.expect(dextr_args) + def post(self, image_id): + """ COCO data test """ + + if not DEXTR_LOADED: + return {"disabled": True, "message": "DEXTR is disabled"}, 400 + + args = dextr_args.parse_args() + points = args.get('points') + # padding = args.get('padding') + # threshold = args.get('threshold') + + if len(points) != 4: + return {"message": "Invalid points entered"}, 400 + + image_model = ImageModel.objects(id=image_id).first() + if not image_model: + return {"message": "Invalid image ID"}, 400 + + image = Image.open(image_model.path) + result = dextr.predict_mask(image, points) + + return { "segmentaiton": Mask(result).polygons().segmentation } + + +@api.route('/maskrcnn') +class MaskRCNN(Resource): + + @login_required + @api.expect(image_upload) + def post(self): + """ COCO data test """ + if not MASKRCNN_LOADED: + return {"disabled": True, "coco": {}} + + args = image_upload.parse_args() + im = Image.open(args.get('image')) + coco = maskrcnn.detect(im) + return {"coco": coco} \ No newline at end of file diff --git a/backend/webserver/api/tasks.py b/backend/webserver/api/tasks.py new file mode 100644 index 00000000..5be4a4fb --- /dev/null +++ b/backend/webserver/api/tasks.py @@ -0,0 +1,50 @@ +from flask_restplus import Namespace, Resource +from flask_login import login_required + +from ..util import query_util +from database import TaskModel + + +api = Namespace('tasks', description='Task related operations') + + +@api.route('/') +class Task(Resource): + @login_required + def get(self): + """ Returns all tasks """ + query = TaskModel.objects.only( + 'group', 'id', 'name', 'completed', 'progress', + 'priority', 'creator', 'desciption', 'errors', + 'warnings' + ).all() + return query_util.fix_ids(query) + + +@api.route('/') +class TaskId(Resource): + @login_required + def delete(self, task_id): + """ Deletes task """ + task = TaskModel.objects(id=task_id).first() + + if task is None: + return {"message": "Invalid task id"}, 400 + + if not task.completed: + return {"message": "Task is not completed"}, 400 + + task.delete() + return {"success": True} + + +@api.route('//logs') +class TaskId(Resource): + @login_required + def get(self, task_id): + """ Deletes task """ + task = TaskModel.objects(id=task_id).first() + if task is None: + return {"message": "Invalid task id"}, 400 + + return {'logs': task.logs} diff --git a/app/api/undo.py b/backend/webserver/api/undo.py similarity index 89% rename from app/api/undo.py rename to backend/webserver/api/undo.py index 0cd6354b..561961c3 100644 --- a/app/api/undo.py +++ b/backend/webserver/api/undo.py @@ -1,8 +1,15 @@ from flask_restplus import Namespace, Resource, reqparse -from flask_login import login_required, current_user +from flask_login import login_required +import os +import shutil import datetime -from ..models import * +from database import ( + ImageModel, + DatasetModel, + CategoryModel, + AnnotationModel +) api = Namespace('undo', description='Undo related operations') @@ -100,6 +107,14 @@ def delete(self): if model_object is None: return {"message": "Invalid id"}, 400 + if isinstance(model_object, ImageModel): + if os.path.isfile(model_object.path): + os.remove(model_object.path) + + if isinstance(model_object, DatasetModel): + if os.path.isdir(model_object.directory): + shutil.rmtree(model_object.directory) + model_object.delete() return {"success": True} diff --git a/app/api/users.py b/backend/webserver/api/users.py similarity index 93% rename from app/api/users.py rename to backend/webserver/api/users.py index c2d82591..cf84ca34 100644 --- a/app/api/users.py +++ b/backend/webserver/api/users.py @@ -2,10 +2,13 @@ from werkzeug.security import generate_password_hash, check_password_hash from flask_restplus import Namespace, Resource, reqparse -from ..models import UserModel -from ..config import Config +from database import UserModel +from config import Config from ..util.query_util import fix_ids +import logging +logger = logging.getLogger('gunicorn.error') + api = Namespace('user', description='User related operations') register = reqparse.RequestParser() @@ -104,6 +107,8 @@ def post(self): user_json = fix_ids(current_user) del user_json['password'] + + logger.info(f'User {current_user.username} has LOGIN') return {'success': True, 'user': user_json} @@ -115,6 +120,7 @@ class UserLogout(Resource): @login_required def get(self): """ Logs user out """ + logger.info(f'User {current_user.username} has LOGOUT') logout_user() return {'success': True} diff --git a/app/authentication.py b/backend/webserver/authentication.py similarity index 73% rename from app/authentication.py rename to backend/webserver/authentication.py index d1172d1f..037e25fe 100644 --- a/app/authentication.py +++ b/backend/webserver/authentication.py @@ -1,6 +1,11 @@ -from flask_login import LoginManager, login_user, login_required, logout_user, current_user, AnonymousUserMixin -from .models import * -from .config import Config +from flask_login import LoginManager, AnonymousUserMixin +from database import ( + UserModel, + DatasetModel, + CategoryModel, + AnnotationModel, + ImageModel +) login_manager = LoginManager() @@ -45,6 +50,18 @@ def to_json(self): "is_admin": self.is_admin, "anonymous": True } + + def can_edit(self, model): + return True + + def can_view(self, model): + return True + + def can_download(self, model): + return True + + def can_delete(self, model): + return True login_manager.anonymous_user = AnonymousUser diff --git a/backend/webserver/gunicorn_config.py b/backend/webserver/gunicorn_config.py new file mode 100644 index 00000000..b3b734cf --- /dev/null +++ b/backend/webserver/gunicorn_config.py @@ -0,0 +1,19 @@ + +from config import Config + + +bind = '0.0.0.0:5000' +backlog = 2048 + +workers = 1 +worker_class = 'eventlet' +worker_connections = 1000 +timeout = 30 +keepalive = 2 + +reload = Config.DEBUG +preload = Config.PRELOAD + +errorlog = '-' +loglevel = Config.LOG_LEVEL +accesslog = None \ No newline at end of file diff --git a/backend/webserver/sockets.py b/backend/webserver/sockets.py new file mode 100644 index 00000000..fcb5ceca --- /dev/null +++ b/backend/webserver/sockets.py @@ -0,0 +1,131 @@ +import functools +import time + +from flask import session +from flask_socketio import ( + SocketIO, + disconnect, + join_room, + leave_room, + emit +) +from flask_login import current_user + +from database import ImageModel, SessionEvent +from config import Config + +import logging +logger = logging.getLogger('gunicorn.error') + + +socketio = SocketIO() + + +def authenticated_only(f): + @functools.wraps(f) + def wrapped(*args, **kwargs): + if current_user.is_authenticated or Config.LOGIN_DISABLED: + return f(*args, **kwargs) + else: + disconnect() + return wrapped + + +@socketio.on('annotation') +@authenticated_only +def annotation(data): + emit('annotation', data, broadcast=True) + + +@socketio.on('annotating') +@authenticated_only +def annotating(data): + """ + Socket for handling image locking and time logging + """ + + image_id = data.get('image_id') + active = data.get('active') + + image = ImageModel.objects(id=image_id).first() + if image is None: + # invalid image ID + return + + emit('annotating', { + 'image_id': image_id, + 'active': active, + 'username': current_user.username + }, broadcast=True, include_self=False) + + if active: + logger.info(f'{current_user.username} has started annotating image {image_id}') + # Remove user from pervious room + previous = session.get('annotating') + if previous is not None: + leave_room(previous) + previous_image = ImageModel.objects(id=previous).first() + + if previous_image is not None: + + start = session.get('annotating_time', time.time()) + event = SessionEvent.create(start, current_user) + + previous_image.add_event(event) + previous_image.update( + pull__annotating=current_user.username + ) + + emit('annotating', { + 'image_id': previous, + 'active': False, + 'username': current_user.username + }, broadcast=True, include_self=False) + + join_room(image_id) + session['annotating'] = image_id + session['annotating_time'] = time.time() + image.update(add_to_set__annotating=current_user.username) + else: + leave_room(image_id) + + start = session.get('annotating_time', time.time()) + event = SessionEvent.create(start, current_user) + + image.add_event(event) + image.update( + pull__annotating=current_user.username + ) + + session['annotating'] = None + session['time'] = None + + +@socketio.on('connect') +def connect(): + logger.info(f'Socket connection created with {current_user.username}') + + +@socketio.on('disconnect') +def disconnect(): + if current_user.is_authenticated: + logger.info(f'Socket connection has been disconnected with {current_user.username}') + image_id = session.get('annotating') + + # Remove user from room + if image_id is not None: + image = ImageModel.objects(id=image_id).first() + if image is not None: + start = session.get('annotating_time', time.time()) + event = SessionEvent.create(start, current_user) + + image.add_event(event) + image.update( + pull__annotating=current_user.username + ) + emit('annotating', { + 'image_id': image_id, + 'active': False, + 'username': current_user.username + }, broadcast=True, include_self=False) + diff --git a/backend/webserver/util/__init__.py b/backend/webserver/util/__init__.py new file mode 100644 index 00000000..431976bd --- /dev/null +++ b/backend/webserver/util/__init__.py @@ -0,0 +1,16 @@ + + +import time +import logging + + +def profile(func): + def wrap(*args, **kwargs): + started_at = time.time() + result = func(*args, **kwargs) + diff = time.time() - started_at + if isinstance(result, dict): + result['time_ms'] = int(diff * 1000) + return result + + return wrap \ No newline at end of file diff --git a/app/util/coco_util.py b/backend/webserver/util/coco_util.py similarity index 51% rename from app/util/coco_util.py rename to backend/webserver/util/coco_util.py index 62e480eb..0a43e5d6 100644 --- a/app/util/coco_util.py +++ b/backend/webserver/util/coco_util.py @@ -1,7 +1,12 @@ import pycocotools.mask as mask -from .query_util import fix_ids -from ..models import * +from database import ( + fix_ids, + ImageModel, + DatasetModel, + CategoryModel, + AnnotationModel +) def paperjs_to_coco(image_width, image_height, paperjs): @@ -35,18 +40,27 @@ def paperjs_to_coco(image_width, image_height, paperjs): segments_to_add = [] for point in child_segments: - if len(point) != 2: - continue - - x = _fit(round(center[0] + point[0], 2), image_width, 0) - y = _fit(round(center[1] + point[1], 2), image_height, 0) - - segments_to_add.extend([x, y]) + + # Cruve + if len(point) == 4: + point = point[0] + + # Point + if len(point) == 2: + x = _fit(round(center[0] + point[0], 2), image_width, 0) + y = _fit(round(center[1] + point[1], 2), image_height, 0) + segments_to_add.extend([x, y]) # Make sure shape is not all outside the image if sum(segments_to_add) == 0: continue + if len(segments_to_add) == 4: + # len 4 means this is a line with no width; it contributes + # no area to the mask, and if we include it, coco will treat + # it instead as a bbox (and throw an error) + continue + num_widths = segments_to_add.count(image_width) num_heights = segments_to_add.count(image_height) if num_widths + num_heights == len(segments_to_add): @@ -57,11 +71,18 @@ def paperjs_to_coco(image_width, image_height, paperjs): if len(segments) < 1: return [], 0, [0, 0, 0, 0] + area, bbox = get_segmentation_area_and_bbox( + segments, image_height, image_width) + + return segments, area, bbox + + +def get_segmentation_area_and_bbox(segmentation, image_height, image_width): # Convert into rle - rles = mask.frPyObjects(segments, image_height, image_width) + rles = mask.frPyObjects(segmentation, image_height, image_width) rle = mask.merge(rles) - return segments, mask.area(rle), mask.toBbox(rle) + return mask.area(rle), mask.toBbox(rle) def get_annotations_iou(annotation_a, annotation_b): @@ -81,45 +102,61 @@ def get_annotations_iou(annotation_a, annotation_b): return ious[0][0] -def get_image_coco(image): +def get_image_coco(image_id): """ Generates coco for an image :param image: ImageModel :return: Coco in dictionary format """ - dataset = DatasetModel.objects(id=image.dataset_id).first() - image = fix_ids(image) + image = ImageModel.objects(id=image_id)\ + .only(*ImageModel.COCO_PROPERTIES) + + image = fix_ids(image)[0] + dataset = DatasetModel.objects(id=image.get('dataset_id')).first() - bulk_categories = CategoryModel.objects(deleted=False) \ - .exclude('deleted_date').in_bulk(dataset.categories).items() + bulk_categories = CategoryModel.objects(id__in=dataset.categories, deleted=False) \ + .only(*CategoryModel.COCO_PROPERTIES) + print(bulk_categories) + + db_annotations = AnnotationModel.objects(deleted=False, image_id=image_id) categories = [] annotations = [] - for category in bulk_categories: - - category_annotations = AnnotationModel.objects( - deleted=False, category_id=category[1].id, image_id=image.get('id') - ).exclude('paper_object', 'deleted_date').all() + for category in fix_ids(bulk_categories): - if len(category_annotations) == 0: + category_annotations = db_annotations\ + .filter(category_id=category.get('id'))\ + .only(*AnnotationModel.COCO_PROPERTIES) + + if category_annotations.count() == 0: continue - + + category_annotations = fix_ids(category_annotations) for annotation in category_annotations: - annotation = fix_ids(annotation) - if len(annotation.get('segmentation')) != 0: - del annotation['deleted'] - del annotation['paper_object'] + has_segmentation = len(annotation.get('segmentation', [])) > 0 + has_keypoints = len(annotation.get('keypoints', [])) > 0 + + if has_segmentation or has_keypoints: + + if has_keypoints: + arr = np.array(annotation.get('keypoints', [])) + arr = arr[2::3] + annotation['num_keypoints'] = len(arr[arr > 0]) + annotations.append(annotation) - category = fix_ids(category[1]) - del category['deleted'] + if len(category.get('keypoint_labels')) > 0: + category['keypoints'] = category.pop('keypoint_labels') + category['skeleton'] = category.pop('keypoint_edges') + else: + del category['keypoint_edges'] + del category['keypoint_labels'] + categories.append(category) - del image['deleted'] - coco = { "images": [image], "categories": categories, @@ -153,7 +190,15 @@ def get_dataset_coco(dataset): for category in categories: category = fix_ids(category[1]) + del category['deleted'] + if len(category.get('keypoint_labels', [])) > 0: + category['keypoints'] = category.pop('keypoint_labels') + category['skeleton'] = category.pop('keypoint_edges') + else: + del category['keypoint_edges'] + del category['keypoint_labels'] + coco.get('categories').append(category) for image in images: @@ -164,8 +209,21 @@ def get_dataset_coco(dataset): annotations = fix_ids(annotations.all()) for annotation in annotations: - del annotation['deleted'] - coco.get('annotations').append(annotation) + + has_keypoints = len(annotation.get('keypoints', [])) > 0 + has_segmentation = len(annotation.get('segmentation', [])) > 0 + + if has_keypoints or has_segmentation: + del annotation['deleted'] + + if not has_keypoints: + del annotation['keypoints'] + else: + arr = np.array(annotation.get('keypoints', [])) + arr = arr[2::3] + annotation['num_keypoints'] = len(arr[arr > 0]) + + coco.get('annotations').append(annotation) image = fix_ids(image) del image['deleted'] @@ -175,11 +233,4 @@ def get_dataset_coco(dataset): def _fit(value, max_value, min_value): - - if value > max_value: - return max_value - - if value < min_value: - return min_value - - return value + return max(min(value, max_value), min_value) diff --git a/backend/webserver/util/dextr.py b/backend/webserver/util/dextr.py new file mode 100644 index 00000000..5f1f03e4 --- /dev/null +++ b/backend/webserver/util/dextr.py @@ -0,0 +1,6 @@ +from dextr import DEXTR +from config import Config + + +model = DEXTR(nb_classes=1, resnet_layers=101, input_shape=(512, 512), weights_path=Config.DEXTR_FILE, + num_input_channels=4, classifier='psp', sigmoid=True) diff --git a/backend/webserver/util/mask_rcnn.py b/backend/webserver/util/mask_rcnn.py new file mode 100644 index 00000000..593ce072 --- /dev/null +++ b/backend/webserver/util/mask_rcnn.py @@ -0,0 +1,73 @@ +from config import Config as AnnotatorConfig +from skimage.transform import resize +import imantics as im + +from keras.preprocessing.image import img_to_array +from mrcnn.config import Config +import mrcnn.model as modellib +import logging +logger = logging.getLogger('gunicorn.error') + + +MODEL_DIR = "/workspace/models" +COCO_MODEL_PATH = AnnotatorConfig.MASK_RCNN_FILE +CLASS_NAMES = AnnotatorConfig.MASK_RCNN_CLASSES.split(',') + +class CocoConfig(Config): + """ + Configuration for COCO Dataset. + """ + NAME = "coco" + GPU_COUNT = 1 + IMAGES_PER_GPU = 1 + NUM_CLASSES = len(CLASS_NAMES) + + +class MaskRCNN(): + + def __init__(self): + + self.config = CocoConfig() + self.model = modellib.MaskRCNN( + mode="inference", + model_dir=MODEL_DIR, + config=self.config + ) + try: + self.model.load_weights(COCO_MODEL_PATH, by_name=True) + self.model.keras_model._make_predict_function() + logger.info(f"Loaded MaskRCNN model: {COCO_MODEL_PATH}") + except: + logger.error(f"Could not load MaskRCNN model (place 'mask_rcnn_coco.h5' in the models directory)") + self.model = None + + + def detect(self, image): + + if self.model is None: + return {} + + image = image.convert('RGB') + width, height = image.size + image.thumbnail((1024, 1024)) + + image = img_to_array(image) + result = self.model.detect([image])[0] + + masks = result.get('masks') + class_ids = result.get('class_ids') + + coco_image = im.Image(width=width, height=height) + + for i in range(masks.shape[-1]): + mask = resize(masks[..., i], (height, width)) + mask = im.Mask(mask) + class_id = class_ids[i] + class_name = CLASS_NAMES[class_id] + category = im.Category(class_name) + coco_image.add(mask, category=category) + + return coco_image.coco() + + +model = MaskRCNN() diff --git a/app/util/pagination_util.py b/backend/webserver/util/pagination_util.py similarity index 100% rename from app/util/pagination_util.py rename to backend/webserver/util/pagination_util.py diff --git a/backend/webserver/util/query_util.py b/backend/webserver/util/query_util.py new file mode 100644 index 00000000..5a09b9c5 --- /dev/null +++ b/backend/webserver/util/query_util.py @@ -0,0 +1,28 @@ +import json + + +def fix_ids(objs): + objects_list = json.loads(objs.to_json().replace('\"_id\"', '\"id\"')) + return objects_list + + +def td_format(td_object): + seconds = int(td_object.total_seconds()) + periods = [ + ('year', 60*60*24*365), + ('month', 60*60*24*30), + ('day', 60*60*24), + ('hour', 60*60), + ('minute', 60), + ('second', 1) + ] + + strings = [] + for period_name, period_seconds in periods: + if seconds > period_seconds: + period_value, seconds = divmod(seconds, period_seconds) + has_s = 's' if period_value > 1 else '' + strings.append("%s %s%s" % (period_value, period_name, has_s)) + break + + return ", ".join(strings) diff --git a/app/util/version_util.py b/backend/webserver/util/version_util.py similarity index 95% rename from app/util/version_util.py rename to backend/webserver/util/version_util.py index 8e72c00d..e6d58c1c 100644 --- a/app/util/version_util.py +++ b/backend/webserver/util/version_util.py @@ -46,7 +46,6 @@ def get_latest(self): r = requests.get(COMMITS.format(self.branch)) if r.status_code != requests.codes.ok: - print(r.json(), flush=True) self.valid = False return "" @@ -60,7 +59,6 @@ def get_commits_behind(self): r = requests.get(COMPARE.format(self.latest_version, self.current_version)) if r.status_code != requests.codes.ok: - print(r.json(), flush=True) self.valid = False return 0 diff --git a/backend/webserver/watcher.py b/backend/webserver/watcher.py new file mode 100644 index 00000000..1798e0e3 --- /dev/null +++ b/backend/webserver/watcher.py @@ -0,0 +1,52 @@ +from watchdog.events import FileSystemEventHandler +from watchdog.observers import Observer + +from config import Config +from database import ImageModel + +import re + + +class ImageFolderHandler(FileSystemEventHandler): + + PREFIX = "[File Watcher]" + + def __init__(self, pattern=None): + self.pattern = pattern or (".gif", ".png", ".jpg", ".jpeg", ".bmp") + + def on_any_event(self, event): + + path = event.dest_path if event.event_type == "moved" else event.src_path + + if ( + event.is_directory + # check if its a hidden file + or bool(re.search(r'\/\..*?\/', path)) + or not path.lower().endswith(self.pattern) + ): + return + + self._log(f'File {path} for {event.event_type}') + + image = ImageModel.objects(path=event.src_path).first() + + if image is None and event.event_type != 'deleted': + self._log(f'Adding new file to database: {path}') + ImageModel.create_from_path(path).save() + + elif event.event_type == 'moved': + self._log(f'Moving image from {event.src_path} to {path}') + image.update(path=path) + + elif event.event_type == 'deleted': + self._log(f'Deleting image from database {path}') + ImageModel.objects(path=path).delete() + + def _log(self, message): + print(f'{self.PREFIX} {message}', flush=True) + + +def run_watcher(): + observer = Observer() + observer.schedule(ImageFolderHandler(), Config.DATASET_DIRECTORY, recursive=True) + observer.start() diff --git a/backend/workers/Dockerfile b/backend/workers/Dockerfile new file mode 100644 index 00000000..81626d31 --- /dev/null +++ b/backend/workers/Dockerfile @@ -0,0 +1,9 @@ +FROM jsbroks/coco-annotator:python-env + +WORKDIR /workspace/ + +# Install python package dependices +COPY ./backend/ /workspace/ + +EXPOSE 5555 +CMD celery -A workers worker -l info diff --git a/backend/workers/__init__.py b/backend/workers/__init__.py new file mode 100644 index 00000000..d063e8ba --- /dev/null +++ b/backend/workers/__init__.py @@ -0,0 +1,16 @@ +from celery import Celery +from config import Config +from database import connect_mongo + +connect_mongo('Celery Worker') + +celery = Celery( + Config.NAME, + backend=Config.CELERY_RESULT_BACKEND, + broker=Config.CELERY_BROKER_URL +) +celery.autodiscover_tasks(['workers.tasks']) + + +if __name__ == '__main__': + celery.start() diff --git a/backend/workers/socket.py b/backend/workers/socket.py new file mode 100644 index 00000000..391b112f --- /dev/null +++ b/backend/workers/socket.py @@ -0,0 +1,6 @@ +from config import Config +from flask_socketio import SocketIO + + +def create_socket(): + return SocketIO(message_queue=Config.CELERY_BROKER_URL) diff --git a/backend/workers/tasks/__init__.py b/backend/workers/tasks/__init__.py new file mode 100644 index 00000000..b6f4e422 --- /dev/null +++ b/backend/workers/tasks/__init__.py @@ -0,0 +1,4 @@ + +from .data import * +from .test import * +from .scan import * \ No newline at end of file diff --git a/backend/workers/tasks/data.py b/backend/workers/tasks/data.py new file mode 100644 index 00000000..37f3476a --- /dev/null +++ b/backend/workers/tasks/data.py @@ -0,0 +1,290 @@ + +from database import ( + fix_ids, + ImageModel, + CategoryModel, + AnnotationModel, + DatasetModel, + TaskModel, + ExportModel +) + +# import pycocotools.mask as mask +import numpy as np +import time +import json +import os + +from celery import shared_task +from ..socket import create_socket + + +@shared_task +def export_annotations(task_id, dataset_id, categories): + + task = TaskModel.objects.get(id=task_id) + dataset = DatasetModel.objects.get(id=dataset_id) + + task.update(status="PROGRESS") + socket = create_socket() + + task.info("Beginning Export (COCO Format)") + + db_categories = CategoryModel.objects(id__in=categories, deleted=False) \ + .only(*CategoryModel.COCO_PROPERTIES) + db_images = ImageModel.objects(deleted=False, annotated=True, dataset_id=dataset.id)\ + .only(*ImageModel.COCO_PROPERTIES) + db_annotations = AnnotationModel.objects(deleted=False, category_id__in=categories) + + total_items = db_categories.count() + + coco = { + 'images': [], + 'categories': [], + 'annotations': [] + } + + total_items += db_images.count() + progress = 0 + + # iterate though all categoires and upsert + category_names = [] + for category in fix_ids(db_categories): + + if len(category.get('keypoint_labels', [])) > 0: + category['keypoints'] = category.pop('keypoint_labels', []) + category['skeleton'] = category.pop('keypoint_edges', []) + else: + if 'keypoint_edges' in category: + del category['keypoint_edges'] + if 'keypoint_labels' in category: + del category['keypoint_labels'] + + task.info(f"Adding category: {category.get('name')}") + coco.get('categories').append(category) + category_names.append(category.get('name')) + + progress += 1 + task.set_progress((progress/total_items)*100, socket=socket) + + total_annotations = db_annotations.count() + total_images = db_images.count() + for image in fix_ids(db_images): + + progress += 1 + task.set_progress((progress/total_items)*100, socket=socket) + + annotations = db_annotations.filter(image_id=image.get('id'))\ + .only(*AnnotationModel.COCO_PROPERTIES) + annotations = fix_ids(annotations) + num_annotations = 0 + for annotation in annotations: + + has_keypoints = len(annotation.get('keypoints', [])) > 0 + has_segmentation = len(annotation.get('segmentation', [])) > 0 + + if has_keypoints or has_segmentation: + + if not has_keypoints: + if 'keypoints' in annotation: + del annotation['keypoints'] + else: + arr = np.array(annotation.get('keypoints', [])) + arr = arr[2::3] + annotation['num_keypoints'] = len(arr[arr > 0]) + + num_annotations += 1 + coco.get('annotations').append(annotation) + + task.info(f"Exporting {num_annotations} annotations for image {image.get('id')}") + coco.get('images').append(image) + + task.info(f"Done export {total_annotations} annotations and {total_images} images from {dataset.name}") + + timestamp = time.time() + directory = f"{dataset.directory}.exports/" + file_path = f"{directory}coco-{timestamp}.json" + + if not os.path.exists(directory): + os.makedirs(directory) + + task.info(f"Writing export to file {file_path}") + with open(file_path, 'w') as fp: + json.dump(coco, fp) + + task.info("Creating export object") + export = ExportModel(dataset_id=dataset.id, path=file_path, tags=["COCO", *category_names]) + export.save() + + task.set_progress(100, socket=socket) + + +@shared_task +def import_annotations(task_id, dataset_id, coco_json): + + task = TaskModel.objects.get(id=task_id) + dataset = DatasetModel.objects.get(id=dataset_id) + + task.update(status="PROGRESS") + socket = create_socket() + + task.info("Beginning Import") + + images = ImageModel.objects(dataset_id=dataset.id) + categories = CategoryModel.objects + + coco_images = coco_json.get('images', []) + coco_annotations = coco_json.get('annotations', []) + coco_categories = coco_json.get('categories', []) + + task.info(f"Importing {len(coco_categories)} categories, " + f"{len(coco_images)} images, and " + f"{len(coco_annotations)} annotations") + + total_items = sum([ + len(coco_categories), + len(coco_annotations), + len(coco_images) + ]) + progress = 0 + + task.info("===== Importing Categories =====") + # category id mapping ( file : database ) + categories_id = {} + + # Create any missing categories + for category in coco_categories: + + category_name = category.get('name') + category_id = category.get('id') + category_model = categories.filter(name__iexact=category_name).first() + + if category_model is None: + task.warning(f"{category_name} category not found (creating a new one)") + + new_category = CategoryModel( + name=category_name, + keypoint_edges=category.get('skeleton', []), + keypoint_labels=category.get('keypoints', []) + ) + new_category.save() + + category_model = new_category + dataset.categories.append(new_category.id) + + task.info(f"{category_name} category found") + # map category ids + categories_id[category_id] = category_model.id + + # update progress + progress += 1 + task.set_progress((progress/total_items)*100, socket=socket) + + dataset.update(set__categories=dataset.categories) + + task.info("===== Loading Images =====") + # image id mapping ( file: database ) + images_id = {} + categories_by_image = {} + + # Find all images + for image in coco_images: + image_id = image.get('id') + image_filename = image.get('file_name') + + # update progress + progress += 1 + task.set_progress((progress/total_items)*100, socket=socket) + + image_model = images.filter(file_name__exact=image_filename).all() + + if len(image_model) == 0: + task.warning(f"Could not find image {image_filename}") + continue + + if len(image_model) > 1: + task.error(f"Too many images found with the same file name: {image_filename}") + continue + + task.info(f"Image {image_filename} found") + image_model = image_model[0] + images_id[image_id] = image_model + categories_by_image[image_id] = list() + + task.info("===== Import Annotations =====") + for annotation in coco_annotations: + + image_id = annotation.get('image_id') + category_id = annotation.get('category_id') + segmentation = annotation.get('segmentation', []) + keypoints = annotation.get('keypoints', []) + # is_crowd = annotation.get('iscrowed', False) + area = annotation.get('area', 0) + bbox = annotation.get('bbox', [0, 0, 0, 0]) + + progress += 1 + task.set_progress((progress/total_items)*100, socket=socket) + + has_segmentation = len(segmentation) > 0 + has_keypoints = len(keypoints) > 0 + if not has_segmentation and not has_keypoints: + task.warning(f"Annotation {annotation.get('id')} has no segmentation or keypoints") + continue + + try: + image_model = images_id[image_id] + category_model_id = categories_id[category_id] + image_categories = categories_by_image[image_id] + except KeyError: + task.warning(f"Could not find image assoicated with annotation {annotation.get('id')}") + continue + + annotation_model = AnnotationModel.objects( + image_id=image_model.id, + category_id=category_model_id, + segmentation=segmentation, + keypoints=keypoints + ).first() + + if annotation_model is None: + task.info(f"Creating annotation data ({image_id}, {category_id})") + + annotation_model = AnnotationModel(image_id=image_model.id) + annotation_model.category_id = category_model_id + + annotation_model.color = annotation.get('color') + annotation_model.metadata = annotation.get('metadata', {}) + + if has_segmentation: + annotation_model.segmentation = segmentation + annotation_model.area = area + annotation_model.bbox = bbox + + if has_keypoints: + annotation_model.keypoints = keypoints + + annotation_model.save() + + image_categories.append(category_id) + else: + annotation_model.update(deleted=False) + task.info(f"Annotation already exists (i:{image_id}, c:{category_id})") + + for image_id in images_id: + + image_model = images_id[image_id] + category_ids = categories_by_image[image_id] + all_category_ids = list(image_model.category_ids) + all_category_ids += category_ids + + image_model.update( + set__annotated=True, + set__category_ids=list(set(all_category_ids)), + set__num_annotations=AnnotationModel\ + .objects(image_id=image_id, area__gt=0, deleted=False).count() + ) + + task.set_progress(100, socket=socket) + + +__all__ = ["export_annotations", "import_annotations"] \ No newline at end of file diff --git a/backend/workers/tasks/scan.py b/backend/workers/tasks/scan.py new file mode 100644 index 00000000..5b28211f --- /dev/null +++ b/backend/workers/tasks/scan.py @@ -0,0 +1,59 @@ +from database import ( + ImageModel, + TaskModel, + DatasetModel +) + +from celery import shared_task +from ..socket import create_socket + +import os + + +@shared_task +def scan_dataset(task_id, dataset_id): + + task = TaskModel.objects.get(id=task_id) + dataset = DatasetModel.objects.get(id=dataset_id) + + task.update(status="PROGRESS") + socket = create_socket() + + directory = dataset.directory + toplevel = list(os.listdir(directory)) + task.info(f"Scanning {directory}") + + count = 0 + for root, dirs, files in os.walk(directory): + + try: + youarehere = toplevel.index(root.split('/')[-1]) + progress = int(((youarehere)/len(toplevel))*100) + task.set_progress(progress, socket=socket) + except: + pass + + if root.split('/')[-1].startswith('.'): + continue + + for file in files: + path = os.path.join(root, file) + + if path.endswith(ImageModel.PATTERN): + db_image = ImageModel.objects(path=path).first() + + if db_image is not None: + continue + + try: + ImageModel.create_from_path(path, dataset.id).save() + count += 1 + task.info(f"New file found: {path}") + except: + task.warning(f"Could not read {path}") + + task.info(f"Created {count} new image(s)") + task.set_progress(100, socket=socket) + + +__all__ = ["scan_dataset"] \ No newline at end of file diff --git a/backend/workers/tasks/test.py b/backend/workers/tasks/test.py new file mode 100644 index 00000000..fe5ad144 --- /dev/null +++ b/backend/workers/tasks/test.py @@ -0,0 +1,27 @@ + +from celery import shared_task +from database import TaskModel + +from ..socket import create_socket + + +@shared_task +def long_task(n, task_id): + + task = TaskModel.objects.get(id=task_id) + task.update(status="PROGRESS") + + socketio = create_socket() + + print(f"This task will take {n} seconds") + import time + + for i in range(n): + print(i) + time.sleep(1) + socketio.emit('test', i) + + return n + + +__all__ = ["long_task"] \ No newline at end of file diff --git a/docker/client/Dockerfile b/client/Dockerfile similarity index 78% rename from docker/client/Dockerfile rename to client/Dockerfile index 140e3c1f..c2cf2e96 100644 --- a/docker/client/Dockerfile +++ b/client/Dockerfile @@ -1,8 +1,5 @@ FROM node:10 -RUN apt-get -y update \ - && apt-get install -y git - RUN npm install -g --quiet \ @vue/cli@3.3.0 \ @vue/cli-service@3.3.0 @@ -13,7 +10,7 @@ COPY ./client/package.json /workspace/package.json RUN npm install ENV NODE_PATH=/workspace/node_modules -WORKDIR client/ +WORKDIR /workspace/client/ EXPOSE 8080 CMD npm run serve \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 8dc252ef..8c5c46ae 100755 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -10,7 +10,7 @@ "integrity": "sha1-BuKrGb21NThVWaq7W6WXKUgoAPg=", "dev": true, "requires": { - "@babel/highlight": "7.0.0" + "@babel/highlight": "^7.0.0" } }, "@babel/core": { @@ -19,20 +19,20 @@ "integrity": "sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/generator": "7.1.6", - "@babel/helpers": "7.1.5", - "@babel/parser": "7.1.6", - "@babel/template": "7.1.2", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6", - "convert-source-map": "1.6.0", - "debug": "4.1.0", - "json5": "2.1.0", - "lodash": "4.17.11", - "resolve": "1.8.1", - "semver": "5.6.0", - "source-map": "0.5.7" + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.1.6", + "@babel/helpers": "^7.1.5", + "@babel/parser": "^7.1.6", + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.6", + "@babel/types": "^7.1.6", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.10", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" }, "dependencies": { "debug": { @@ -41,7 +41,7 @@ "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -58,11 +58,11 @@ "integrity": "sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ==", "dev": true, "requires": { - "@babel/types": "7.1.6", - "jsesc": "2.5.2", - "lodash": "4.17.11", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "@babel/types": "^7.1.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" } }, "@babel/helper-annotate-as-pure": { @@ -71,7 +71,7 @@ "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -80,8 +80,8 @@ "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "7.1.0", - "@babel/types": "7.1.6" + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-call-delegate": { @@ -90,9 +90,9 @@ "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "7.0.0", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-define-map": { @@ -101,9 +101,9 @@ "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/types": "7.1.6", - "lodash": "4.17.11" + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" } }, "@babel/helper-explode-assignable-expression": { @@ -112,8 +112,8 @@ "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", "dev": true, "requires": { - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-function-name": { @@ -122,9 +122,9 @@ "integrity": "sha1-oM6wFoX3M1XUNgwSR/WCv6/I/1M=", "dev": true, "requires": { - "@babel/helper-get-function-arity": "7.0.0", - "@babel/template": "7.1.2", - "@babel/types": "7.1.6" + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-get-function-arity": { @@ -133,7 +133,7 @@ "integrity": "sha1-g1ctQyDipGVyY3NBE8QoaLZOScM=", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-hoist-variables": { @@ -142,7 +142,7 @@ "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-member-expression-to-functions": { @@ -151,7 +151,7 @@ "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-module-imports": { @@ -160,7 +160,7 @@ "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-module-transforms": { @@ -169,12 +169,12 @@ "integrity": "sha1-Rw1PlnbZ+tULMkzczl+6u8PaV4c=", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-simple-access": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "@babel/template": "7.1.2", - "@babel/types": "7.1.6", - "lodash": "4.17.11" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" } }, "@babel/helper-optimise-call-expression": { @@ -183,7 +183,7 @@ "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-plugin-utils": { @@ -198,7 +198,7 @@ "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.10" } }, "@babel/helper-remap-async-to-generator": { @@ -207,11 +207,11 @@ "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-wrap-function": "7.1.0", - "@babel/template": "7.1.2", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-replace-supers": { @@ -220,10 +220,10 @@ "integrity": "sha1-X8Md5SLsDvCJncmz589qXdZV82I=", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "7.0.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-simple-access": { @@ -232,8 +232,8 @@ "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", "dev": true, "requires": { - "@babel/template": "7.1.2", - "@babel/types": "7.1.6" + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-split-export-declaration": { @@ -242,7 +242,7 @@ "integrity": "sha1-Oq4oXAMRwqsJXZl7jJqUytVH2BM=", "dev": true, "requires": { - "@babel/types": "7.1.6" + "@babel/types": "^7.0.0" } }, "@babel/helper-wrap-function": { @@ -251,10 +251,10 @@ "integrity": "sha1-jPVOkZBwYGfwFq+Pdcs9+CnMjGY=", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/template": "7.1.2", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helpers": { @@ -263,9 +263,9 @@ "integrity": "sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg==", "dev": true, "requires": { - "@babel/template": "7.1.2", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6" + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.1.5" } }, "@babel/highlight": { @@ -274,9 +274,9 @@ "integrity": "sha1-9xDDjI1Fjm3ZogGvtjf8t4HOmeQ=", "dev": true, "requires": { - "chalk": "2.4.1", - "esutils": "2.0.2", - "js-tokens": "4.0.0" + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" } }, "@babel/parser": { @@ -291,9 +291,9 @@ "integrity": "sha1-QcGnAuEAgUVuI6e3TYkZIt0bts4=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-remap-async-to-generator": "7.1.0", - "@babel/plugin-syntax-async-generators": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.0.0" } }, "@babel/plugin-proposal-class-properties": { @@ -302,12 +302,12 @@ "integrity": "sha1-mvAYVrEkHbYOyIONhGkaoL0ejfQ=", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/helper-member-expression-to-functions": "7.0.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.1.0", - "@babel/plugin-syntax-class-properties": "7.0.0" + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/plugin-syntax-class-properties": "^7.0.0" } }, "@babel/plugin-proposal-decorators": { @@ -316,10 +316,10 @@ "integrity": "sha512-U42f8KhUbtlhUDyV/wK4Rq/wWh8vWyttYABckG/v0vVnMPvayOewZC/83CbVdmyP+UhEqI368FEQ7hHMfhBpQA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "@babel/plugin-syntax-decorators": "7.1.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/plugin-syntax-decorators": "^7.1.0" } }, "@babel/plugin-proposal-json-strings": { @@ -328,8 +328,8 @@ "integrity": "sha1-O017XPUeHy5w9SNR0o1E/Clw0B4=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-json-strings": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.0.0" } }, "@babel/plugin-proposal-object-rest-spread": { @@ -338,8 +338,8 @@ "integrity": "sha1-mhe1R/ZNBna2yc7NTt90qCq4Xn4=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-object-rest-spread": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -348,8 +348,8 @@ "integrity": "sha1-thDZKP5VH/cRfULIu0EO7DEqZCU=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.0.0" } }, "@babel/plugin-proposal-unicode-property-regex": { @@ -358,9 +358,9 @@ "integrity": "sha1-SYs5zXJTbNfEsmF30DAibroIzTM=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" } }, "@babel/plugin-syntax-async-generators": { @@ -369,7 +369,7 @@ "integrity": "sha1-vwiR3Nv1lVg1nQxib9yUkOILwTw=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-class-properties": { @@ -378,7 +378,7 @@ "integrity": "sha1-4FGvXTAMv7zsSnR243qANImIFjQ=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-decorators": { @@ -387,7 +387,7 @@ "integrity": "sha1-L6fBp5BaKZyYU+vO80AwZnX5y9w=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-dynamic-import": { @@ -396,7 +396,7 @@ "integrity": "sha1-bft9i2w74UzpUpYvZY87frVMM+4=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-json-strings": { @@ -405,7 +405,7 @@ "integrity": "sha1-DSWaaAkOFbODzjcQ4B1bI/N3DL0=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-jsx": { @@ -414,7 +414,7 @@ "integrity": "sha1-A01eK04UzK6i5ME3r35K+zk3X/0=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -423,7 +423,7 @@ "integrity": "sha1-N9j7yvIWvWWOoa6764t16I68VJs=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-optional-catch-binding": { @@ -432,7 +432,7 @@ "integrity": "sha1-iG9yAIs6ixhZd/fLcHE7ReUe5HU=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-arrow-functions": { @@ -441,7 +441,7 @@ "integrity": "sha1-psFIdYSMaKO0sxY6SGU17yXH50k=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-async-to-generator": { @@ -450,9 +450,9 @@ "integrity": "sha1-EJ4DZJbFHdZYV+FqyrO6/fPFeBE=", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-remap-async-to-generator": "7.1.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -461,7 +461,7 @@ "integrity": "sha1-SCs/dRA5J+NyiLO2e2X4SOKqDQc=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-block-scoping": { @@ -470,8 +470,8 @@ "integrity": "sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "lodash": "4.17.11" + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.10" } }, "@babel/plugin-transform-classes": { @@ -480,14 +480,14 @@ "integrity": "sha1-qz+KVkNhgAy8irHKbyEQgDhDIkk=", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-define-map": "7.1.0", - "@babel/helper-function-name": "7.1.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "globals": "11.9.0" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.1.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { @@ -496,7 +496,7 @@ "integrity": "sha1-L7uJAM0+gljyou3pCbkOdVYYXjE=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-destructuring": { @@ -505,7 +505,7 @@ "integrity": "sha1-5p/1DKAfrGy3KGPFROUWwrGTAS8=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { @@ -514,9 +514,9 @@ "integrity": "sha1-c6JNppvDw3AlH0Oj0EgZhUYRXlg=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" } }, "@babel/plugin-transform-duplicate-keys": { @@ -525,7 +525,7 @@ "integrity": "sha1-oGAeWAmR58rOCA5M+RnP1Y2nToY=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-exponentiation-operator": { @@ -534,8 +534,8 @@ "integrity": "sha1-nDTC7n/XfgJ3nPo35AOi4QA8zHM=", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-for-of": { @@ -544,7 +544,7 @@ "integrity": "sha1-8rpOrbg70X3Dx+mzD0cHNl4cPjk=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-function-name": { @@ -553,8 +553,8 @@ "integrity": "sha1-KcVVDVxGII5/cwUW1B7t3Ur/rbs=", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-literals": { @@ -563,7 +563,7 @@ "integrity": "sha1-KuwdKc3STEBzWckwzdiekU7o/4Y=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-amd": { @@ -572,8 +572,8 @@ "integrity": "sha1-+eCnBywS4pYHm1pZ9Aj/W5e/hqg=", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-commonjs": { @@ -582,9 +582,9 @@ "integrity": "sha1-Cp2GRRy7+ym9FRhjBol8Z/b5oFw=", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-simple-access": "7.1.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" } }, "@babel/plugin-transform-modules-systemjs": { @@ -593,8 +593,8 @@ "integrity": "sha1-IRmj49thL9dKGdiGUu+/6WE6XbA=", "dev": true, "requires": { - "@babel/helper-hoist-variables": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-umd": { @@ -603,8 +603,8 @@ "integrity": "sha1-opp9hdbyjDVhwzlkRCJXzGoh8qg=", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-new-target": { @@ -613,7 +613,7 @@ "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-object-super": { @@ -622,8 +622,8 @@ "integrity": "sha1-sa4ZSgVLgm2NS6fKkUhtStoPkbs=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.1.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" } }, "@babel/plugin-transform-parameters": { @@ -632,9 +632,9 @@ "integrity": "sha1-RPSS+dYYyRJAJuYjAcKWv2Bqeu0=", "dev": true, "requires": { - "@babel/helper-call-delegate": "7.1.0", - "@babel/helper-get-function-arity": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-call-delegate": "^7.1.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-regenerator": { @@ -643,7 +643,7 @@ "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", "dev": true, "requires": { - "regenerator-transform": "0.13.3" + "regenerator-transform": "^0.13.3" } }, "@babel/plugin-transform-runtime": { @@ -652,10 +652,10 @@ "integrity": "sha1-n3aSDUJVG7V34txZTfIptfdiS2M=", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "resolve": "1.8.1", - "semver": "5.6.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" } }, "@babel/plugin-transform-shorthand-properties": { @@ -664,7 +664,7 @@ "integrity": "sha1-hfivWS3MB2R1QaA1DoyVx79BnRU=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-spread": { @@ -673,7 +673,7 @@ "integrity": "sha1-k1g85I3YyF5T86RgVshW5K8wtJs=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -682,8 +682,8 @@ "integrity": "sha1-MKnWSsKrRu7Ah7hTBTW+zZDnM2Y=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" } }, "@babel/plugin-transform-template-literals": { @@ -692,8 +692,8 @@ "integrity": "sha1-CE8ZUu/lsVPdrmnriUX4gsepfGU=", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-typeof-symbol": { @@ -702,7 +702,7 @@ "integrity": "sha1-Tc8eUulD5SZ7cxO/80f9vg+Bzsk=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-unicode-regex": { @@ -711,9 +711,9 @@ "integrity": "sha1-xngOWxhjp2/nktkO3tn81bUdaPw=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" } }, "@babel/preset-env": { @@ -722,47 +722,47 @@ "integrity": "sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw==", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-proposal-async-generator-functions": "7.1.0", - "@babel/plugin-proposal-json-strings": "7.0.0", - "@babel/plugin-proposal-object-rest-spread": "7.0.0", - "@babel/plugin-proposal-optional-catch-binding": "7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "7.0.0", - "@babel/plugin-syntax-async-generators": "7.0.0", - "@babel/plugin-syntax-object-rest-spread": "7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "7.0.0", - "@babel/plugin-transform-arrow-functions": "7.0.0", - "@babel/plugin-transform-async-to-generator": "7.1.0", - "@babel/plugin-transform-block-scoped-functions": "7.0.0", - "@babel/plugin-transform-block-scoping": "7.1.5", - "@babel/plugin-transform-classes": "7.1.0", - "@babel/plugin-transform-computed-properties": "7.0.0", - "@babel/plugin-transform-destructuring": "7.1.3", - "@babel/plugin-transform-dotall-regex": "7.0.0", - "@babel/plugin-transform-duplicate-keys": "7.0.0", - "@babel/plugin-transform-exponentiation-operator": "7.1.0", - "@babel/plugin-transform-for-of": "7.0.0", - "@babel/plugin-transform-function-name": "7.1.0", - "@babel/plugin-transform-literals": "7.0.0", - "@babel/plugin-transform-modules-amd": "7.1.0", - "@babel/plugin-transform-modules-commonjs": "7.1.0", - "@babel/plugin-transform-modules-systemjs": "7.1.3", - "@babel/plugin-transform-modules-umd": "7.1.0", - "@babel/plugin-transform-new-target": "7.0.0", - "@babel/plugin-transform-object-super": "7.1.0", - "@babel/plugin-transform-parameters": "7.1.0", - "@babel/plugin-transform-regenerator": "7.0.0", - "@babel/plugin-transform-shorthand-properties": "7.0.0", - "@babel/plugin-transform-spread": "7.0.0", - "@babel/plugin-transform-sticky-regex": "7.0.0", - "@babel/plugin-transform-template-literals": "7.0.0", - "@babel/plugin-transform-typeof-symbol": "7.0.0", - "@babel/plugin-transform-unicode-regex": "7.0.0", - "browserslist": "4.3.4", - "invariant": "2.2.4", - "js-levenshtein": "1.1.4", - "semver": "5.6.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.1.0", + "@babel/plugin-proposal-json-strings": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.0.0", + "@babel/plugin-syntax-async-generators": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.1.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.1.5", + "@babel/plugin-transform-classes": "^7.1.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-dotall-regex": "^7.0.0", + "@babel/plugin-transform-duplicate-keys": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.1.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.1.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-amd": "^7.1.0", + "@babel/plugin-transform-modules-commonjs": "^7.1.0", + "@babel/plugin-transform-modules-systemjs": "^7.0.0", + "@babel/plugin-transform-modules-umd": "^7.1.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.1.0", + "@babel/plugin-transform-parameters": "^7.1.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typeof-symbol": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "browserslist": "^4.1.0", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" } }, "@babel/runtime": { @@ -771,7 +771,7 @@ "integrity": "sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA==", "dev": true, "requires": { - "regenerator-runtime": "0.12.1" + "regenerator-runtime": "^0.12.0" } }, "@babel/template": { @@ -780,9 +780,9 @@ "integrity": "sha1-CQSEpXT+9aLS13JqZ07O2lxbVkQ=", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/parser": "7.1.6", - "@babel/types": "7.1.6" + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.1.2", + "@babel/types": "^7.1.2" } }, "@babel/traverse": { @@ -791,15 +791,15 @@ "integrity": "sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/generator": "7.1.6", - "@babel/helper-function-name": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "@babel/parser": "7.1.6", - "@babel/types": "7.1.6", - "debug": "4.1.0", - "globals": "11.9.0", - "lodash": "4.17.11" + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.1.6", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.1.6", + "@babel/types": "^7.1.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" }, "dependencies": { "debug": { @@ -808,7 +808,7 @@ "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -825,9 +825,9 @@ "integrity": "sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w==", "dev": true, "requires": { - "esutils": "2.0.2", - "lodash": "4.17.11", - "to-fast-properties": "2.0.0" + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" } }, "@intervolga/optimize-cssnano-plugin": { @@ -836,9 +836,9 @@ "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==", "dev": true, "requires": { - "cssnano": "4.1.7", - "cssnano-preset-default": "4.0.5", - "postcss": "7.0.5" + "cssnano": "^4.0.0", + "cssnano-preset-default": "^4.0.0", + "postcss": "^7.0.0" } }, "@mrmlnc/readdir-enhanced": { @@ -847,8 +847,8 @@ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", "dev": true, "requires": { - "call-me-maybe": "1.0.1", - "glob-to-regexp": "0.3.0" + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" } }, "@nodelib/fs.stat": { @@ -858,9 +858,9 @@ "dev": true }, "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", + "version": "10.12.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.26.tgz", + "integrity": "sha512-nMRqS+mL1TOnIJrL6LKJcNZPB8V3eTfRo9FQA2b5gDvrHurC8XbSA86KNe0dShlEL7ReWJv/OU9NL7Z0dnqWTg==", "dev": true }, "@types/semver": { @@ -887,17 +887,17 @@ "integrity": "sha1-G7Y5XF3chLyOmTrORxUbDZXTgqc=", "dev": true, "requires": { - "@babel/plugin-proposal-class-properties": "7.1.0", - "@babel/plugin-proposal-decorators": "7.1.6", - "@babel/plugin-syntax-dynamic-import": "7.0.0", - "@babel/plugin-syntax-jsx": "7.0.0", - "@babel/plugin-transform-runtime": "7.1.0", - "@babel/preset-env": "7.1.6", - "@babel/runtime": "7.1.5", - "babel-helper-vue-jsx-merge-props": "2.0.3", - "babel-plugin-dynamic-import-node": "2.2.0", - "babel-plugin-transform-vue-jsx": "4.0.1", - "core-js": "2.5.7" + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-decorators": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/runtime": "^7.0.0", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-plugin-dynamic-import-node": "^2.2.0", + "babel-plugin-transform-vue-jsx": "^4.0.1", + "core-js": "^2.5.7" } }, "@vue/cli-overlay": { @@ -912,9 +912,9 @@ "integrity": "sha1-RDRBRW6hFBs6gHAlUDQ0LdR4CeA=", "dev": true, "requires": { - "@babel/core": "7.1.6", - "@vue/babel-preset-app": "3.1.1", - "babel-loader": "8.0.4" + "@babel/core": "^7.0.0", + "@vue/babel-preset-app": "^3.1.0", + "babel-loader": "^8.0.4" } }, "@vue/cli-plugin-eslint": { @@ -923,12 +923,12 @@ "integrity": "sha512-ZcRJqqDeMxf5c6YkCT7nr29SGePBfyeuYfG8p3QVSND90nhS/952/G6ZAb7Ph1dNNsEONU4plQYnQAte6Caf4w==", "dev": true, "requires": { - "@vue/cli-shared-utils": "3.1.1", - "babel-eslint": "10.0.1", - "eslint": "4.19.1", - "eslint-loader": "2.1.1", - "eslint-plugin-vue": "4.7.1", - "globby": "8.0.1" + "@vue/cli-shared-utils": "^3.1.1", + "babel-eslint": "^10.0.1", + "eslint": "^4.19.1", + "eslint-loader": "^2.1.1", + "eslint-plugin-vue": "^4.7.1", + "globby": "^8.0.1" }, "dependencies": { "ajv": { @@ -937,10 +937,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "cross-spawn": { @@ -949,9 +949,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "eslint": { @@ -960,44 +960,44 @@ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.4.1", - "concat-stream": "1.6.2", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.1.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.4", - "esquery": "1.0.1", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.3", - "globals": "11.9.0", - "ignore": "3.3.10", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.1", - "regexpp": "1.1.0", - "require-uncached": "1.0.3", - "semver": "5.6.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", "table": "4.0.2", - "text-table": "0.2.0" + "text-table": "~0.2.0" } }, "eslint-plugin-vue": { @@ -1006,7 +1006,7 @@ "integrity": "sha1-yCm5/GJYLBiXtaC5Sv1E7MpRHmM=", "dev": true, "requires": { - "vue-eslint-parser": "2.0.3" + "vue-eslint-parser": "^2.0.3" } }, "fast-deep-equal": { @@ -1024,38 +1024,70 @@ } }, "@vue/cli-plugin-unit-jest": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-3.3.0.tgz", - "integrity": "sha512-Y/WkrO95vdvjVjeNO1vZRQUAxlZ6ngdgAzvMzCeEaujbRG4b8M6W7ePSAe8C9yfoVcJtbnoHcBv2er31sPwtyQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-3.4.0.tgz", + "integrity": "sha512-F1FzKG2JQmVPXH5OKFN4htBkGERDj5Kxd47Wmts2H0rhmtHR4a+k0X7+WyCzbb1aSRKNYdG4f2eSwyu6tSq28A==", "dev": true, "requires": { - "@vue/cli-shared-utils": "3.3.0", - "babel-jest": "23.6.0", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", - "jest": "23.6.0", - "jest-serializer-vue": "2.0.2", - "jest-transform-stub": "1.0.0", - "vue-jest": "3.0.2" + "@vue/cli-shared-utils": "^3.4.0", + "babel-jest": "^23.6.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "jest": "^23.6.0", + "jest-serializer-vue": "^2.0.2", + "jest-transform-stub": "^1.0.0", + "vue-jest": "^3.0.2" }, "dependencies": { "@vue/cli-shared-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-3.3.0.tgz", - "integrity": "sha512-V/sU1jc7/jMCAbU8uA5f4j9Yd8lTqdi3I6FEHfLG1nstwhaNi4BU3WKWOAl72NYVWFYG8VuCrYWDn75kMimtuw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-3.4.0.tgz", + "integrity": "sha512-w9j2qIroUUC2ym4Lb0lLMdlGmYThhwV0OizOEVigB5eZOEUEBV2Mv43K+nWJ6OyRBACnvhJTDi1gIwJo8zUvOw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "execa": "^1.0.0", + "joi": "^14.3.0", + "launch-editor": "^2.2.1", + "lru-cache": "^5.1.1", + "node-ipc": "^9.1.1", + "opn": "^5.3.0", + "ora": "^3.0.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "semver": "^5.5.0", + "string.prototype.padstart": "^3.0.0" + } + }, + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "babel-jest": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.6.0.tgz", + "integrity": "sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.6", + "babel-preset-jest": "^23.2.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz", + "integrity": "sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=", + "dev": true + }, + "babel-preset-jest": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", + "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", "dev": true, "requires": { - "chalk": "2.4.1", - "execa": "1.0.0", - "joi": "14.3.1", - "launch-editor": "2.2.1", - "lru-cache": "5.1.1", - "node-ipc": "9.1.1", - "opn": "5.4.0", - "ora": "3.0.0", - "request": "2.88.0", - "request-promise-native": "1.0.5", - "semver": "5.6.0", - "string.prototype.padstart": "3.0.0" + "babel-plugin-jest-hoist": "^23.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" } }, "hoek": { @@ -1070,9 +1102,9 @@ "integrity": "sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ==", "dev": true, "requires": { - "hoek": "6.1.2", - "isemail": "3.2.0", - "topo": "3.0.3" + "hoek": "6.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" } }, "lru-cache": { @@ -1081,21 +1113,43 @@ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "yallist": "3.0.3" + "yallist": "^3.0.2" } }, "ora": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-3.0.0.tgz", - "integrity": "sha512-LBS97LFe2RV6GJmXBi6OKcETKyklHNMV0xw7BtsVn2MlsgsydyZetSCbCANr+PFLmDyv4KV88nn0eCKza665Mg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.1.0.tgz", + "integrity": "sha512-vRBPaNCclUi8pUxRF/G8+5qEQkc6EgzKK1G2ZNJUIGu088Un5qIxFXeDgymvPRM9nmrcUOGzQgS1Vmtz+NtlMw==", "dev": true, "requires": { - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0", - "strip-ansi": "4.0.0", - "wcwidth": "1.0.1" + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.3.1", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.0.0", + "wcwidth": "^1.0.1" + }, + "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==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" } }, "yallist": { @@ -1112,56 +1166,56 @@ "integrity": "sha512-dArLh5yd2B2an/jTD+cmkRmyRxKSE+5il9408vhciyqvZGVjkajTN95YjY5VLkBMQvrv/Z+goGSn+7wtnQSOFg==", "dev": true, "requires": { - "@intervolga/optimize-cssnano-plugin": "1.0.6", - "@vue/cli-overlay": "3.1.0", - "@vue/cli-shared-utils": "3.1.1", - "@vue/preload-webpack-plugin": "1.1.0", - "@vue/web-component-wrapper": "1.2.0", - "acorn": "6.0.4", - "acorn-walk": "6.1.1", - "address": "1.0.3", - "autoprefixer": "8.6.5", - "cache-loader": "1.2.5", - "case-sensitive-paths-webpack-plugin": "2.1.2", - "chalk": "2.4.1", - "clipboardy": "1.2.3", - "cliui": "4.1.0", - "copy-webpack-plugin": "4.6.0", - "css-loader": "1.0.1", - "cssnano": "4.1.7", - "debug": "4.1.0", - "escape-string-regexp": "1.0.5", - "file-loader": "2.0.0", - "friendly-errors-webpack-plugin": "1.7.0", - "fs-extra": "7.0.1", - "globby": "8.0.1", - "hash-sum": "1.0.2", - "html-webpack-plugin": "3.2.0", - "launch-editor-middleware": "2.2.1", - "lodash.defaultsdeep": "4.6.0", - "lodash.mapvalues": "4.6.0", - "lodash.transform": "4.6.0", - "mini-css-extract-plugin": "0.4.4", - "minimist": "1.2.0", - "ora": "3.0.0", - "portfinder": "1.0.19", - "postcss-loader": "3.0.0", - "read-pkg": "4.0.1", - "semver": "5.6.0", - "slash": "2.0.0", - "source-map-url": "0.4.0", - "ssri": "6.0.1", - "string.prototype.padend": "3.0.0", - "terser-webpack-plugin": "1.1.0", - "thread-loader": "1.2.0", - "url-loader": "1.1.2", - "vue-loader": "15.4.2", - "webpack": "4.25.1", - "webpack-bundle-analyzer": "3.0.3", - "webpack-chain": "4.12.1", - "webpack-dev-server": "3.1.14", - "webpack-merge": "4.1.4", - "yorkie": "2.0.0" + "@intervolga/optimize-cssnano-plugin": "^1.0.5", + "@vue/cli-overlay": "^3.1.0", + "@vue/cli-shared-utils": "^3.1.1", + "@vue/preload-webpack-plugin": "^1.1.0", + "@vue/web-component-wrapper": "^1.2.0", + "acorn": "^6.0.2", + "acorn-walk": "^6.1.0", + "address": "^1.0.3", + "autoprefixer": "^8.6.5", + "cache-loader": "^1.2.5", + "case-sensitive-paths-webpack-plugin": "^2.1.2", + "chalk": "^2.4.1", + "clipboardy": "^1.2.3", + "cliui": "^4.1.0", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^1.0.1", + "cssnano": "^4.1.7", + "debug": "^4.1.0", + "escape-string-regexp": "^1.0.5", + "file-loader": "^2.0.0", + "friendly-errors-webpack-plugin": "^1.7.0", + "fs-extra": "^7.0.0", + "globby": "^8.0.1", + "hash-sum": "^1.0.2", + "html-webpack-plugin": "^3.2.0", + "launch-editor-middleware": "^2.2.1", + "lodash.defaultsdeep": "^4.6.0", + "lodash.mapvalues": "^4.6.0", + "lodash.transform": "^4.6.0", + "mini-css-extract-plugin": "^0.4.4", + "minimist": "^1.2.0", + "ora": "^3.0.0", + "portfinder": "^1.0.19", + "postcss-loader": "^3.0.0", + "read-pkg": "^4.0.1", + "semver": "^5.6.0", + "slash": "^2.0.0", + "source-map-url": "^0.4.0", + "ssri": "^6.0.1", + "string.prototype.padend": "^3.0.0", + "terser-webpack-plugin": "^1.1.0", + "thread-loader": "^1.2.0", + "url-loader": "^1.1.2", + "vue-loader": "^15.4.2", + "webpack": "^4.18.1", + "webpack-bundle-analyzer": "^3.0.3", + "webpack-chain": "^4.11.0", + "webpack-dev-server": "^3.1.10", + "webpack-merge": "^4.1.4", + "yorkie": "^2.0.0" }, "dependencies": { "acorn": { @@ -1176,7 +1230,7 @@ "integrity": "sha1-NzaHv/pnizixzZH4YbY4UANd3Ic=", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -1191,12 +1245,12 @@ "integrity": "sha1-gXnjUluar9mSQtY8wgb9ZHMnQdA=", "dev": true, "requires": { - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0", - "strip-ansi": "4.0.0", - "wcwidth": "1.0.1" + "chalk": "^2.3.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.1.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^4.0.0", + "wcwidth": "^1.0.1" } }, "slash": { @@ -1213,18 +1267,18 @@ "integrity": "sha1-q4Y4wlMY5YErV4d9fPxlzSr0N0A=", "dev": true, "requires": { - "chalk": "2.4.1", - "execa": "1.0.0", - "joi": "13.7.0", - "launch-editor": "2.2.1", - "lru-cache": "4.1.3", - "node-ipc": "9.1.1", - "opn": "5.4.0", - "ora": "2.1.0", - "request": "2.88.0", - "request-promise-native": "1.0.5", - "semver": "5.6.0", - "string.prototype.padstart": "3.0.0" + "chalk": "^2.4.1", + "execa": "^1.0.0", + "joi": "^13.0.0", + "launch-editor": "^2.2.1", + "lru-cache": "^4.1.3", + "node-ipc": "^9.1.1", + "opn": "^5.3.0", + "ora": "^2.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "semver": "^5.5.0", + "string.prototype.padstart": "^3.0.0" } }, "@vue/component-compiler-utils": { @@ -1233,15 +1287,15 @@ "integrity": "sha1-T1gPGyj8doWFnYfqDpKhwCcck9o=", "dev": true, "requires": { - "consolidate": "0.15.1", - "hash-sum": "1.0.2", - "lru-cache": "4.1.3", - "merge-source-map": "1.1.0", - "postcss": "6.0.23", - "postcss-selector-parser": "3.1.1", + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^6.0.20", + "postcss-selector-parser": "^3.1.1", "prettier": "1.13.7", - "source-map": "0.5.7", - "vue-template-es2015-compiler": "1.6.0" + "source-map": "^0.5.6", + "vue-template-es2015-compiler": "^1.6.0" }, "dependencies": { "postcss": { @@ -1250,9 +1304,9 @@ "integrity": "sha1-YcgswyisYOZ3ZF+XkFTrmLwOMyQ=", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" }, "dependencies": { "source-map": { @@ -1269,9 +1323,9 @@ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", "dev": true, "requires": { - "dot-prop": "4.2.0", - "indexes-of": "1.0.1", - "uniq": "1.0.1" + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } } } @@ -1282,9 +1336,9 @@ "integrity": "sha512-rJEDXPb61Hfgg8GllO3XXFP98bcIxdNNHSrNcxP/vBSukOolgOwQyZJ5f5z/c7ViPyh5/IDlC4qBnhx/0n+I4g==", "dev": true, "requires": { - "eslint-config-prettier": "3.3.0", - "eslint-plugin-prettier": "3.0.0", - "prettier": "1.15.2" + "eslint-config-prettier": "^3.3.0", + "eslint-plugin-prettier": "^3.0.0", + "prettier": "^1.15.2" }, "dependencies": { "prettier": { @@ -1307,8 +1361,8 @@ "integrity": "sha512-Lzrd4ZBkS70Tl8JbXbDrN/NcSaH9aZT6+7emU3QhTJ+CrorJpyFDA1dkvSIhH+rDTs8sHFbGeXjXV/qorXxtRw==", "dev": true, "requires": { - "dom-event-types": "1.0.0", - "lodash": "4.17.11" + "dom-event-types": "^1.0.0", + "lodash": "^4.17.4" } }, "@vue/web-component-wrapper": { @@ -1391,7 +1445,7 @@ "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", "dev": true, "requires": { - "@xtuc/ieee754": "1.2.0" + "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { @@ -1519,7 +1573,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -1535,7 +1589,7 @@ "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", "dev": true, "requires": { - "acorn": "5.7.3" + "acorn": "^5.0.0" } }, "acorn-globals": { @@ -1544,14 +1598,14 @@ "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", "dev": true, "requires": { - "acorn": "6.0.5", - "acorn-walk": "6.1.1" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" }, "dependencies": { "acorn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", - "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", + "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", "dev": true } } @@ -1562,7 +1616,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -1585,16 +1639,21 @@ "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==", "dev": true }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "ajv": { "version": "6.5.5", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-errors": { @@ -1645,7 +1704,7 @@ "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -1654,8 +1713,8 @@ "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "append-transform": { @@ -1664,7 +1723,7 @@ "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", "dev": true, "requires": { - "default-require-extensions": "1.0.0" + "default-require-extensions": "^1.0.0" } }, "aproba": { @@ -1685,7 +1744,7 @@ "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", "dev": true, "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arr-diff": { @@ -1742,7 +1801,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -1757,6 +1816,11 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1769,7 +1833,7 @@ "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "~2.1.0" } }, "asn1.js": { @@ -1778,9 +1842,9 @@ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "assert": { @@ -1842,8 +1906,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", - "dev": true + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=" }, "asynckit": { "version": "0.4.0", @@ -1863,12 +1926,12 @@ "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", "dev": true, "requires": { - "browserslist": "3.2.8", - "caniuse-lite": "1.0.30000907", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "6.0.23", - "postcss-value-parser": "3.3.1" + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000864", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.23", + "postcss-value-parser": "^3.2.3" }, "dependencies": { "browserslist": { @@ -1877,8 +1940,8 @@ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000907", - "electron-to-chromium": "1.3.84" + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" } }, "postcss": { @@ -1887,9 +1950,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -1917,8 +1980,8 @@ "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", "requires": { - "follow-redirects": "1.5.9", - "is-buffer": "1.1.6" + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" } }, "babel-code-frame": { @@ -1927,9 +1990,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { "ansi-regex": { @@ -1950,11 +2013,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "js-tokens": { @@ -1969,7 +2032,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "supports-color": { @@ -1992,12 +2055,12 @@ "integrity": "sha1-kZaB3AmWFM19MdRciQhpUJKh+u0=", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/parser": "7.1.6", - "@babel/traverse": "7.1.6", - "@babel/types": "7.1.6", + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0" + "eslint-visitor-keys": "^1.0.0" } }, "babel-generator": { @@ -2006,14 +2069,14 @@ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.11", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" }, "dependencies": { "jsesc": { @@ -2036,18 +2099,165 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-jest": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.6.0.tgz", - "integrity": "sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.1.0.tgz", + "integrity": "sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw==", "dev": true, "requires": { - "babel-plugin-istanbul": "4.1.6", - "babel-preset-jest": "23.2.0" + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.1.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + }, + "dependencies": { + "babel-plugin-istanbul": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz", + "integrity": "sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.0.0", + "test-exclude": "^5.0.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.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" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "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=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "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", + "path-type": "^3.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz", + "integrity": "sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + } } }, "babel-loader": { @@ -2056,10 +2266,10 @@ "integrity": "sha512-fhBhNkUToJcW9nV46v8w87AJOwAJDz84c1CL57n3Stj73FANM/b9TbCUK4YhdOwEyZ+OxhYpdeZDNzSI29Firw==", "dev": true, "requires": { - "find-cache-dir": "1.0.0", - "loader-utils": "1.1.0", - "mkdirp": "0.5.1", - "util.promisify": "1.0.0" + "find-cache-dir": "^1.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "util.promisify": "^1.0.0" } }, "babel-messages": { @@ -2068,7 +2278,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-dynamic-import-node": { @@ -2077,7 +2287,7 @@ "integrity": "sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==", "dev": true, "requires": { - "object.assign": "4.1.0" + "object.assign": "^4.1.0" } }, "babel-plugin-istanbul": { @@ -2086,16 +2296,16 @@ "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", "dev": true, "requires": { - "babel-plugin-syntax-object-rest-spread": "6.13.0", - "find-up": "2.1.0", - "istanbul-lib-instrument": "1.10.2", - "test-exclude": "4.2.3" + "babel-plugin-syntax-object-rest-spread": "^6.13.0", + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.10.1", + "test-exclude": "^4.2.1" } }, "babel-plugin-jest-hoist": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz", - "integrity": "sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz", + "integrity": "sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw==", "dev": true }, "babel-plugin-syntax-object-rest-spread": { @@ -2110,10 +2320,10 @@ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" } }, "babel-plugin-transform-strict-mode": { @@ -2122,8 +2332,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-vue-jsx": { @@ -2132,17 +2342,17 @@ "integrity": "sha512-wbOz7ITB5cloLSjKUU1hWn8zhR+Dwah/RZiTiJY/CQliCwhowmzu6m7NEF+y5EJX/blDzGjRtZvC10Vdb3Q7vw==", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "babel-preset-jest": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", - "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz", + "integrity": "sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "23.2.0", - "babel-plugin-syntax-object-rest-spread": "6.13.0" + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.1.0" } }, "babel-register": { @@ -2151,13 +2361,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "6.26.3", - "babel-runtime": "6.26.0", - "core-js": "2.5.7", - "home-or-tmp": "2.0.0", - "lodash": "4.17.11", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" }, "dependencies": { "babel-core": { @@ -2166,25 +2376,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.6.0", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" } }, "debug": { @@ -2208,7 +2418,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.6" } } } @@ -2219,8 +2429,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -2237,11 +2447,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.11" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -2250,15 +2460,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.4", - "lodash": "4.17.11" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" }, "dependencies": { "debug": { @@ -2284,10 +2494,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.11", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" }, "dependencies": { "to-fast-properties": { @@ -2304,6 +2514,11 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2316,13 +2531,13 @@ "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -2331,7 +2546,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2340,7 +2555,7 @@ "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2349,7 +2564,7 @@ "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2358,13 +2573,18 @@ "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", @@ -2383,7 +2603,15 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" } }, "bfj": { @@ -2392,10 +2620,10 @@ "integrity": "sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ==", "dev": true, "requires": { - "bluebird": "3.5.3", - "check-types": "7.4.0", - "hoopy": "0.1.4", - "tryer": "1.0.1" + "bluebird": "^3.5.1", + "check-types": "^7.3.0", + "hoopy": "^0.1.2", + "tryer": "^1.0.0" } }, "big.js": { @@ -2410,6 +2638,11 @@ "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", @@ -2429,15 +2662,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" }, "dependencies": { "debug": { @@ -2455,7 +2688,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } } } @@ -2466,12 +2699,12 @@ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { - "array-flatten": "2.1.2", - "deep-equal": "1.0.1", - "dns-equal": "1.0.0", - "dns-txt": "2.0.2", - "multicast-dns": "6.2.3", - "multicast-dns-service-types": "1.1.0" + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" }, "dependencies": { "array-flatten": { @@ -2499,7 +2732,7 @@ "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -2509,16 +2742,16 @@ "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "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": { @@ -2527,7 +2760,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2567,12 +2800,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { @@ -2581,9 +2814,9 @@ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "1.2.0", - "browserify-des": "1.0.2", - "evp_bytestokey": "1.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, "browserify-des": { @@ -2592,10 +2825,10 @@ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "browserify-rsa": { @@ -2604,8 +2837,8 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "4.11.8", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sign": { @@ -2614,13 +2847,13 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "elliptic": "6.4.1", - "inherits": "2.0.3", - "parse-asn1": "5.1.1" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, "browserify-zlib": { @@ -2629,7 +2862,7 @@ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "1.0.6" + "pako": "~1.0.5" } }, "browserslist": { @@ -2638,9 +2871,9 @@ "integrity": "sha1-RHe3N9tqGwcHcnWyR5HmgNQwBCU=", "dev": true, "requires": { - "caniuse-lite": "1.0.30000907", - "electron-to-chromium": "1.3.84", - "node-releases": "1.0.3" + "caniuse-lite": "^1.0.30000899", + "electron-to-chromium": "^1.3.82", + "node-releases": "^1.0.1" } }, "bser": { @@ -2649,7 +2882,7 @@ "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", "dev": true, "requires": { - "node-int64": "0.4.0" + "node-int64": "^0.4.0" } }, "buffer": { @@ -2658,9 +2891,9 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.3.0", - "ieee754": "1.1.12", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "buffer-from": { @@ -2705,19 +2938,19 @@ "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { - "bluebird": "3.5.3", - "chownr": "1.1.1", - "glob": "7.1.3", - "graceful-fs": "4.1.15", - "lru-cache": "4.1.3", - "mississippi": "2.0.0", - "mkdirp": "0.5.1", - "move-concurrently": "1.0.1", - "promise-inflight": "1.0.1", - "rimraf": "2.6.2", - "ssri": "5.3.0", - "unique-filename": "1.1.1", - "y18n": "4.0.0" + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^2.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^5.2.4", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" }, "dependencies": { "ssri": { @@ -2726,7 +2959,7 @@ "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.1.1" } } } @@ -2737,15 +2970,15 @@ "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, "cache-loader": { @@ -2754,10 +2987,10 @@ "integrity": "sha512-enWKEQ4kO3YreDFd7AtVRjtJBmNiqh/X9hVDReu0C4qm8gsGmySkwuWtdc+N5O+vq5FzxL1mIZc30NyXCB7o/Q==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "mkdirp": "0.5.1", - "neo-async": "2.6.0", - "schema-utils": "0.4.7" + "loader-utils": "^1.1.0", + "mkdirp": "^0.5.1", + "neo-async": "^2.5.0", + "schema-utils": "^0.4.2" } }, "call-me-maybe": { @@ -2772,7 +3005,7 @@ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { - "callsites": "2.0.0" + "callsites": "^2.0.0" }, "dependencies": { "callsites": { @@ -2789,9 +3022,14 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", @@ -2804,8 +3042,8 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "2.3.2", - "upper-case": "1.1.3" + "no-case": "^2.2.0", + "upper-case": "^1.1.1" } }, "camelcase": { @@ -2820,10 +3058,10 @@ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dev": true, "requires": { - "browserslist": "4.3.4", - "caniuse-lite": "1.0.30000907", - "lodash.memoize": "4.1.2", - "lodash.uniq": "4.5.0" + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" } }, "caniuse-lite": { @@ -2838,7 +3076,7 @@ "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", "dev": true, "requires": { - "rsvp": "3.6.2" + "rsvp": "^3.3.3" } }, "case-sensitive-paths-webpack-plugin": { @@ -2859,9 +3097,9 @@ "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chardet": { @@ -2882,19 +3120,19 @@ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" } }, "chownr": { @@ -2909,7 +3147,7 @@ "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", "dev": true, "requires": { - "tslib": "1.9.3" + "tslib": "^1.9.0" } }, "ci-info": { @@ -2924,8 +3162,8 @@ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "circular-json": { @@ -2940,10 +3178,10 @@ "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -2952,7 +3190,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2963,7 +3201,7 @@ "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", "dev": true, "requires": { - "source-map": "0.6.1" + "source-map": "~0.6.0" }, "dependencies": { "source-map": { @@ -2980,7 +3218,7 @@ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "2.0.0" + "restore-cursor": "^2.0.0" } }, "cli-spinners": { @@ -3001,8 +3239,8 @@ "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", "dev": true, "requires": { - "arch": "2.1.1", - "execa": "0.8.0" + "arch": "^2.1.0", + "execa": "^0.8.0" }, "dependencies": { "cross-spawn": { @@ -3011,9 +3249,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "execa": { @@ -3022,13 +3260,13 @@ "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.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": { @@ -3045,9 +3283,9 @@ "integrity": "sha1-NIQi2+gtgAswIu709qwQvy5NG0k=", "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" } }, "clone": { @@ -3068,7 +3306,7 @@ "integrity": "sha1-8/iwsVBz411wJj+xBCyywCPbOK8=", "dev": true, "requires": { - "q": "1.5.1" + "q": "^1.1.2" } }, "code-point-at": { @@ -3083,8 +3321,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color": { @@ -3093,8 +3331,8 @@ "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==", "dev": true, "requires": { - "color-convert": "1.9.3", - "color-string": "1.5.3" + "color-convert": "^1.9.1", + "color-string": "^1.5.2" } }, "color-convert": { @@ -3118,8 +3356,8 @@ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", "dev": true, "requires": { - "color-name": "1.1.3", - "simple-swizzle": "0.2.2" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, "colors": { @@ -3134,7 +3372,7 @@ "integrity": "sha1-LR0kMXr7ir6V1tLAsHtXgTU52Cg=", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -3149,11 +3387,20 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, "compressible": { "version": "2.0.15", @@ -3161,7 +3408,7 @@ "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": ">= 1.36.0 < 2" } }, "compression": { @@ -3170,13 +3417,13 @@ "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "2.0.15", + "compressible": "~2.0.14", "debug": "2.6.9", - "on-headers": "1.0.1", + "on-headers": "~1.0.1", "safe-buffer": "5.1.2", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "debug": { @@ -3202,10 +3449,10 @@ "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=", "dev": true, "requires": { - "buffer-from": "1.1.1", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "condense-newlines": { @@ -3214,9 +3461,9 @@ "integrity": "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-whitespace": "0.3.0", - "kind-of": "3.2.2" + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" }, "dependencies": { "extend-shallow": { @@ -3225,7 +3472,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "kind-of": { @@ -3234,7 +3481,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -3245,8 +3492,8 @@ "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", "dev": true, "requires": { - "ini": "1.3.5", - "proto-list": "1.2.4" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, "connect-history-api-fallback": { @@ -3261,7 +3508,7 @@ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "consolidate": { @@ -3270,7 +3517,7 @@ "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", "dev": true, "requires": { - "bluebird": "3.5.3" + "bluebird": "^3.1.1" } }, "constants-browserify": { @@ -3297,7 +3544,7 @@ "integrity": "sha1-UbU3qMQ+DwTewZk7/83VBOdYrCA=", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.1" } }, "cookie": { @@ -3318,12 +3565,12 @@ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", "dev": true, "requires": { - "aproba": "1.2.0", - "fs-write-stream-atomic": "1.0.10", - "iferr": "0.1.5", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" } }, "copy-descriptor": { @@ -3338,14 +3585,14 @@ "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", "dev": true, "requires": { - "cacache": "10.0.4", - "find-cache-dir": "1.0.0", - "globby": "7.1.1", - "is-glob": "4.0.0", - "loader-utils": "1.1.0", - "minimatch": "3.0.4", - "p-limit": "1.3.0", - "serialize-javascript": "1.5.0" + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "globby": "^7.1.1", + "is-glob": "^4.0.0", + "loader-utils": "^1.1.0", + "minimatch": "^3.0.4", + "p-limit": "^1.0.0", + "serialize-javascript": "^1.4.0" }, "dependencies": { "globby": { @@ -3354,12 +3601,12 @@ "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", "dev": true, "requires": { - "array-union": "1.0.2", - "dir-glob": "2.0.0", - "glob": "7.1.3", - "ignore": "3.3.10", - "pify": "3.0.0", - "slash": "1.0.0" + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" } } } @@ -3382,10 +3629,10 @@ "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", "dev": true, "requires": { - "import-fresh": "2.0.0", - "is-directory": "0.3.1", - "js-yaml": "3.12.0", - "parse-json": "4.0.0" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" } }, "create-ecdh": { @@ -3394,8 +3641,8 @@ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.1" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, "create-hash": { @@ -3404,11 +3651,11 @@ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "md5.js": "1.3.5", - "ripemd160": "2.0.2", - "sha.js": "2.4.11" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -3417,12 +3664,12 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "inherits": "2.0.3", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", - "sha.js": "2.4.11" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "cross-spawn": { @@ -3431,11 +3678,11 @@ "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", "dev": true, "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.6.0", - "shebang-command": "1.2.0", - "which": "1.3.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-browserify": { @@ -3444,17 +3691,17 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "1.0.1", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.3", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "diffie-hellman": "5.0.3", - "inherits": "2.0.3", - "pbkdf2": "3.0.17", - "public-encrypt": "4.0.3", - "randombytes": "2.0.6", - "randomfill": "1.0.4" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, "css": { @@ -3463,10 +3710,10 @@ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", "dev": true, "requires": { - "inherits": "2.0.3", - "source-map": "0.6.1", - "source-map-resolve": "0.5.2", - "urix": "0.1.0" + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" }, "dependencies": { "source-map": { @@ -3489,8 +3736,8 @@ "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", "dev": true, "requires": { - "postcss": "7.0.5", - "timsort": "0.3.0" + "postcss": "^7.0.1", + "timsort": "^0.3.0" } }, "css-loader": { @@ -3499,18 +3746,18 @@ "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "css-selector-tokenizer": "0.7.1", - "icss-utils": "2.1.0", - "loader-utils": "1.1.0", - "lodash": "4.17.11", - "postcss": "6.0.23", - "postcss-modules-extract-imports": "1.2.1", - "postcss-modules-local-by-default": "1.2.0", - "postcss-modules-scope": "1.1.0", - "postcss-modules-values": "1.3.0", - "postcss-value-parser": "3.3.1", - "source-list-map": "2.0.1" + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" }, "dependencies": { "postcss": { @@ -3519,9 +3766,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -3538,10 +3785,10 @@ "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", "dev": true, "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.2", - "domutils": "1.7.0", - "nth-check": "1.0.2" + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" } }, "css-select-base-adapter": { @@ -3556,9 +3803,9 @@ "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", "dev": true, "requires": { - "cssesc": "0.1.0", - "fastparse": "1.1.2", - "regexpu-core": "1.0.0" + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" }, "dependencies": { "cssesc": { @@ -3579,9 +3826,9 @@ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { - "regenerate": "1.4.0", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -3596,7 +3843,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } } } @@ -3607,8 +3854,8 @@ "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", "dev": true, "requires": { - "mdn-data": "1.1.4", - "source-map": "0.5.7" + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" } }, "css-unit-converter": { @@ -3641,10 +3888,10 @@ "integrity": "sha1-C/ESKUvsEDq19o0/gFcyyDJaCxs=", "dev": true, "requires": { - "cosmiconfig": "5.0.7", - "cssnano-preset-default": "4.0.5", - "is-resolvable": "1.1.0", - "postcss": "7.0.5" + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.5", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" } }, "cssnano-preset-default": { @@ -3653,36 +3900,36 @@ "integrity": "sha1-0XVsAlnZitMR5gG6dulcYPZ3GsE=", "dev": true, "requires": { - "css-declaration-sorter": "4.0.1", - "cssnano-util-raw-cache": "4.0.1", - "postcss": "7.0.5", - "postcss-calc": "7.0.1", - "postcss-colormin": "4.0.2", - "postcss-convert-values": "4.0.1", - "postcss-discard-comments": "4.0.1", - "postcss-discard-duplicates": "4.0.2", - "postcss-discard-empty": "4.0.1", - "postcss-discard-overridden": "4.0.1", - "postcss-merge-longhand": "4.0.9", - "postcss-merge-rules": "4.0.2", - "postcss-minify-font-values": "4.0.2", - "postcss-minify-gradients": "4.0.1", - "postcss-minify-params": "4.0.1", - "postcss-minify-selectors": "4.0.1", - "postcss-normalize-charset": "4.0.1", - "postcss-normalize-display-values": "4.0.1", - "postcss-normalize-positions": "4.0.1", - "postcss-normalize-repeat-style": "4.0.1", - "postcss-normalize-string": "4.0.1", - "postcss-normalize-timing-functions": "4.0.1", - "postcss-normalize-unicode": "4.0.1", - "postcss-normalize-url": "4.0.1", - "postcss-normalize-whitespace": "4.0.1", - "postcss-ordered-values": "4.1.1", - "postcss-reduce-initial": "4.0.2", - "postcss-reduce-transforms": "4.0.1", - "postcss-svgo": "4.0.1", - "postcss-unique-selectors": "4.0.1" + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.0", + "postcss-colormin": "^4.0.2", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.1", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.9", + "postcss-merge-rules": "^4.0.2", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.1", + "postcss-minify-params": "^4.0.1", + "postcss-minify-selectors": "^4.0.1", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.1", + "postcss-normalize-positions": "^4.0.1", + "postcss-normalize-repeat-style": "^4.0.1", + "postcss-normalize-string": "^4.0.1", + "postcss-normalize-timing-functions": "^4.0.1", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.1", + "postcss-ordered-values": "^4.1.1", + "postcss-reduce-initial": "^4.0.2", + "postcss-reduce-transforms": "^4.0.1", + "postcss-svgo": "^4.0.1", + "postcss-unique-selectors": "^4.0.1" } }, "cssnano-util-get-arguments": { @@ -3703,7 +3950,7 @@ "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "cssnano-util-same-parent": { @@ -3727,16 +3974,16 @@ "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", "dev": true, "requires": { - "mdn-data": "1.1.4", - "source-map": "0.5.7" + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" } } } }, "cssom": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz", - "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", "dev": true }, "cssstyle": { @@ -3745,7 +3992,7 @@ "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", "dev": true, "requires": { - "cssom": "0.3.4" + "cssom": "0.3.x" } }, "cyclist": { @@ -3760,7 +4007,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "data-urls": { @@ -3769,9 +4016,9 @@ "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "abab": "2.0.0", - "whatwg-mimetype": "2.3.0", - "whatwg-url": "7.0.0" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" }, "dependencies": { "whatwg-url": { @@ -3780,9 +4027,9 @@ "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", "dev": true, "requires": { - "lodash.sortby": "4.7.0", - "tr46": "1.0.1", - "webidl-conversions": "4.0.2" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } } } @@ -3846,8 +4093,8 @@ "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", "dev": true, "requires": { - "execa": "0.10.0", - "ip-regex": "2.1.0" + "execa": "^0.10.0", + "ip-regex": "^2.1.0" }, "dependencies": { "execa": { @@ -3856,13 +4103,13 @@ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", "dev": true, "requires": { - "cross-spawn": "6.0.5", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^6.0.0", + "get-stream": "^3.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": { @@ -3879,7 +4126,7 @@ "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", "dev": true, "requires": { - "strip-bom": "2.0.0" + "strip-bom": "^2.0.0" } }, "defaults": { @@ -3888,7 +4135,7 @@ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "1.0.4" + "clone": "^1.0.2" } }, "define-properties": { @@ -3897,7 +4144,7 @@ "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", "dev": true, "requires": { - "object-keys": "1.0.12" + "object-keys": "^1.0.12" } }, "define-property": { @@ -3906,8 +4153,8 @@ "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -3916,7 +4163,7 @@ "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -3925,7 +4172,7 @@ "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -3934,9 +4181,9 @@ "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -3947,12 +4194,12 @@ "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", "dev": true, "requires": { - "globby": "6.1.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "p-map": "1.2.0", - "pify": "3.0.0", - "rimraf": "2.6.2" + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" }, "dependencies": { "globby": { @@ -3961,11 +4208,11 @@ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { - "array-union": "1.0.2", - "glob": "7.1.3", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "dependencies": { "pify": { @@ -3996,8 +4243,8 @@ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "destroy": { @@ -4012,7 +4259,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "detect-newline": { @@ -4039,9 +4286,9 @@ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "bn.js": "4.11.8", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, "dir-glob": { @@ -4050,8 +4297,8 @@ "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", "dev": true, "requires": { - "arrify": "1.0.1", - "path-type": "3.0.0" + "arrify": "^1.0.1", + "path-type": "^3.0.0" } }, "dns-equal": { @@ -4066,8 +4313,8 @@ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", "dev": true, "requires": { - "ip": "1.1.5", - "safe-buffer": "5.1.2" + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" } }, "dns-txt": { @@ -4076,7 +4323,7 @@ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", "dev": true, "requires": { - "buffer-indexof": "1.1.1" + "buffer-indexof": "^1.0.0" } }, "doctrine": { @@ -4085,7 +4332,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "dom-converter": { @@ -4094,7 +4341,7 @@ "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dev": true, "requires": { - "utila": "0.4.0" + "utila": "~0.4" } }, "dom-event-types": { @@ -4109,8 +4356,8 @@ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "dev": true, "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.2" + "domelementtype": "~1.1.1", + "entities": "~1.1.1" }, "dependencies": { "domelementtype": { @@ -4139,7 +4386,7 @@ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "requires": { - "webidl-conversions": "4.0.2" + "webidl-conversions": "^4.0.2" } }, "domhandler": { @@ -4148,7 +4395,7 @@ "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", "dev": true, "requires": { - "domelementtype": "1.2.1" + "domelementtype": "1" } }, "domutils": { @@ -4157,8 +4404,8 @@ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "dev": true, "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.2.1" + "dom-serializer": "0", + "domelementtype": "1" } }, "dot-prop": { @@ -4167,7 +4414,7 @@ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "duplexer": { @@ -4182,10 +4429,10 @@ "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "stream-shift": "1.0.0" + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, "easy-stack": { @@ -4200,8 +4447,8 @@ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, "editorconfig": { @@ -4210,12 +4457,12 @@ "integrity": "sha512-GWjSI19PVJAM9IZRGOS+YKI8LN+/sjkSjNyvxL5ucqP9/IqtYNXBaQ/6c/hkPNYQHyOHra2KoXZI/JVpuqwmcQ==", "dev": true, "requires": { - "@types/node": "10.12.18", - "@types/semver": "5.5.0", - "commander": "2.19.0", - "lru-cache": "4.1.3", - "semver": "5.6.0", - "sigmund": "1.0.1" + "@types/node": "^10.11.7", + "@types/semver": "^5.5.0", + "commander": "^2.19.0", + "lru-cache": "^4.1.3", + "semver": "^5.6.0", + "sigmund": "^1.0.1" }, "dependencies": { "commander": { @@ -4250,13 +4497,13 @@ "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", "dev": true, "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.5", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, "emojis-list": { @@ -4277,7 +4524,37 @@ "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.4.0" + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" } }, "enhanced-resolve": { @@ -4286,9 +4563,9 @@ "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "memory-fs": "0.4.1", - "tapable": "1.1.0" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" } }, "entities": { @@ -4303,7 +4580,7 @@ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "dev": true, "requires": { - "prr": "1.0.1" + "prr": "~1.0.1" } }, "error-ex": { @@ -4312,7 +4589,7 @@ "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", "dev": true, "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "error-stack-parser": { @@ -4321,7 +4598,7 @@ "integrity": "sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw==", "dev": true, "requires": { - "stackframe": "1.0.4" + "stackframe": "^1.0.4" } }, "es-abstract": { @@ -4330,11 +4607,11 @@ "integrity": "sha1-nbvdJ8aFbwABQhyhh4LXhr+KYWU=", "dev": true, "requires": { - "es-to-primitive": "1.2.0", - "function-bind": "1.1.1", - "has": "1.0.3", - "is-callable": "1.1.4", - "is-regex": "1.0.4" + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" } }, "es-to-primitive": { @@ -4343,9 +4620,9 @@ "integrity": "sha1-7fckeAM0VujdqO8J4ArZZQcH83c=", "dev": true, "requires": { - "is-callable": "1.1.4", - "is-date-object": "1.0.1", - "is-symbol": "1.0.2" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, "escape-html": { @@ -4366,11 +4643,11 @@ "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", "dev": true, "requires": { - "esprima": "3.1.3", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.6.1" + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "dependencies": { "esprima": { @@ -4394,44 +4671,44 @@ "integrity": "sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "ajv": "6.5.5", - "chalk": "2.4.1", - "cross-spawn": "6.0.5", - "debug": "4.1.0", - "doctrine": "2.1.0", - "eslint-scope": "4.0.0", - "eslint-utils": "1.3.1", - "eslint-visitor-keys": "1.0.0", - "espree": "4.1.0", - "esquery": "1.0.1", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.3", - "globals": "11.9.0", - "ignore": "4.0.6", - "imurmurhash": "0.1.4", - "inquirer": "6.2.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.1", - "regexpp": "2.0.1", - "require-uncached": "1.0.3", - "semver": "5.6.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "5.1.0", - "text-table": "0.2.0" + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "imurmurhash": "^0.1.4", + "inquirer": "^6.1.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.0.2", + "text-table": "^0.2.0" }, "dependencies": { "acorn": { @@ -4458,7 +4735,7 @@ "integrity": "sha1-NzaHv/pnizixzZH4YbY4UANd3Ic=", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "eslint-scope": { @@ -4467,8 +4744,8 @@ "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "espree": { @@ -4477,9 +4754,9 @@ "integrity": "sha1-co1UUeD9FWwEOEp62J7VH/VOsl8=", "dev": true, "requires": { - "acorn": "6.0.4", - "acorn-jsx": "5.0.0", - "eslint-visitor-keys": "1.0.0" + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" } }, "external-editor": { @@ -4488,9 +4765,9 @@ "integrity": "sha1-WGbbKal4Jtvkvzr9JAcOrZ6kOic=", "dev": true, "requires": { - "chardet": "0.7.0", - "iconv-lite": "0.4.24", - "tmp": "0.0.33" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" } }, "ignore": { @@ -4505,19 +4782,19 @@ "integrity": "sha1-Ua3Nd29mE2ncHolIWcJWCiJKvdg=", "dev": true, "requires": { - "ansi-escapes": "3.1.0", - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "3.0.3", - "figures": "2.0.0", - "lodash": "4.17.11", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rxjs": "6.3.3", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, "ms": { @@ -4538,10 +4815,10 @@ "integrity": "sha1-aaVGRPbwGtFij4F4cVtAjca/Efc=", "dev": true, "requires": { - "ajv": "6.5.5", - "lodash": "4.17.11", + "ajv": "^6.5.3", + "lodash": "^4.17.10", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" } } } @@ -4552,7 +4829,7 @@ "integrity": "sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA==", "dev": true, "requires": { - "get-stdin": "6.0.0" + "get-stdin": "^6.0.0" } }, "eslint-loader": { @@ -4561,11 +4838,11 @@ "integrity": "sha512-1GrJFfSevQdYpoDzx8mEE2TDWsb/zmFuY09l6hURg1AeFIKQOvZ+vH0UPjzmd1CZIbfTV5HUkMeBmFiDBkgIsQ==", "dev": true, "requires": { - "loader-fs-cache": "1.0.1", - "loader-utils": "1.1.0", - "object-assign": "4.1.1", - "object-hash": "1.3.1", - "rimraf": "2.6.2" + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" } }, "eslint-plugin-prettier": { @@ -4574,7 +4851,7 @@ "integrity": "sha1-9rgj4GX4w2UpkYzbdm16Dpdewww=", "dev": true, "requires": { - "prettier-linter-helpers": "1.0.0" + "prettier-linter-helpers": "^1.0.0" } }, "eslint-plugin-vue": { @@ -4583,7 +4860,7 @@ "integrity": "sha512-roXXroqY2AcgF4dk0SG1reeeQz2X3Ef7q9B0GD0+vdc58vApig1hpTReT4Mf0YqTEI80/ldXD1ibV6n4vVUZrw==", "dev": true, "requires": { - "vue-eslint-parser": "3.2.2" + "vue-eslint-parser": "^3.2.1" }, "dependencies": { "acorn": { @@ -4604,8 +4881,8 @@ "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "espree": { @@ -4614,9 +4891,9 @@ "integrity": "sha1-co1UUeD9FWwEOEp62J7VH/VOsl8=", "dev": true, "requires": { - "acorn": "6.0.4", - "acorn-jsx": "5.0.0", - "eslint-visitor-keys": "1.0.0" + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" } }, "vue-eslint-parser": { @@ -4625,12 +4902,12 @@ "integrity": "sha1-R8lx7kw5sO59f14VTLYhvrIvejQ=", "dev": true, "requires": { - "debug": "3.1.0", - "eslint-scope": "4.0.0", - "eslint-visitor-keys": "1.0.0", - "espree": "4.1.0", - "esquery": "1.0.1", - "lodash": "4.17.11" + "debug": "^3.1.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "lodash": "^4.17.10" } } } @@ -4641,8 +4918,8 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint-utils": { @@ -4663,8 +4940,8 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.7.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -4679,7 +4956,7 @@ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -4688,7 +4965,7 @@ "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -4733,7 +5010,7 @@ "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { - "original": "1.0.2" + "original": "^1.0.0" } }, "evp_bytestokey": { @@ -4742,8 +5019,8 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "1.3.5", - "safe-buffer": "5.1.2" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "exec-sh": { @@ -4752,7 +5029,7 @@ "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", "dev": true, "requires": { - "merge": "1.2.1" + "merge": "^1.2.0" } }, "execa": { @@ -4761,13 +5038,13 @@ "integrity": "sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg=", "dev": true, "requires": { - "cross-spawn": "6.0.5", - "get-stream": "4.1.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "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": { @@ -4782,13 +5059,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "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": { @@ -4806,7 +5083,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -4815,7 +5092,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -4826,7 +5103,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.4" + "fill-range": "^2.1.0" }, "dependencies": { "fill-range": { @@ -4835,11 +5112,11 @@ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "3.1.1", - "repeat-element": "1.1.3", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "is-number": { @@ -4848,7 +5125,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "isobject": { @@ -4866,7 +5143,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -4877,12 +5154,12 @@ "integrity": "sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "jest-diff": "23.6.0", - "jest-get-type": "22.4.3", - "jest-matcher-utils": "23.6.0", - "jest-message-util": "23.4.0", - "jest-regex-util": "23.3.0" + "ansi-styles": "^3.2.0", + "jest-diff": "^23.6.0", + "jest-get-type": "^22.1.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0" } }, "express": { @@ -4891,36 +5168,36 @@ "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "debug": { @@ -4946,8 +5223,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -4956,7 +5233,7 @@ "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -4967,9 +5244,9 @@ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.24", - "tmp": "0.0.33" + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" } }, "extglob": { @@ -4978,14 +5255,14 @@ "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "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.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "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": { @@ -4994,7 +5271,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -5003,7 +5280,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -5012,7 +5289,7 @@ "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -5021,7 +5298,7 @@ "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -5030,9 +5307,9 @@ "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -5043,7 +5320,7 @@ "integrity": "sha1-HqffLnx8brmSL6COitrqSG9vj5I=", "dev": true, "requires": { - "css": "2.2.4" + "css": "^2.1.0" } }, "extsprintf": { @@ -5070,12 +5347,12 @@ "integrity": "sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g==", "dev": true, "requires": { - "@mrmlnc/readdir-enhanced": "2.2.1", - "@nodelib/fs.stat": "1.1.3", - "glob-parent": "3.1.0", - "is-glob": "4.0.0", - "merge2": "1.2.3", - "micromatch": "3.1.10" + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" } }, "fast-json-stable-stringify": { @@ -5102,7 +5379,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "fb-watchman": { @@ -5111,7 +5388,7 @@ "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", "dev": true, "requires": { - "bser": "2.0.0" + "bser": "^2.0.0" } }, "figgy-pudding": { @@ -5126,7 +5403,7 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -5135,8 +5412,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.3.4", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "file-loader": { @@ -5145,8 +5422,8 @@ "integrity": "sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "schema-utils": "1.0.0" + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv-keywords": { @@ -5161,9 +5438,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -5180,8 +5457,8 @@ "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", "dev": true, "requires": { - "glob": "7.1.3", - "minimatch": "3.0.4" + "glob": "^7.0.3", + "minimatch": "^3.0.3" } }, "filesize": { @@ -5196,10 +5473,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -5208,7 +5485,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -5220,12 +5497,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" }, "dependencies": { "debug": { @@ -5245,8 +5522,8 @@ "integrity": "sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U=", "dev": true, "requires": { - "json5": "0.5.1", - "path-exists": "3.0.0" + "json5": "^0.5.1", + "path-exists": "^3.0.0" }, "dependencies": { "json5": { @@ -5263,9 +5540,9 @@ "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", "dev": true, "requires": { - "commondir": "1.0.1", - "make-dir": "1.3.0", - "pkg-dir": "2.0.0" + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" } }, "find-up": { @@ -5274,7 +5551,7 @@ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { @@ -5283,10 +5560,10 @@ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "requires": { - "circular-json": "0.3.3", - "graceful-fs": "4.1.15", - "rimraf": "2.6.2", - "write": "0.2.1" + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" } }, "flush-write-stream": { @@ -5295,8 +5572,8 @@ "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.6" + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" } }, "follow-redirects": { @@ -5304,7 +5581,7 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz", "integrity": "sha1-ye2ddIuBSjlTVxblMbkZaoRdicY=", "requires": { - "debug": "3.1.0" + "debug": "=3.1.0" } }, "for-in": { @@ -5319,7 +5596,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "forever-agent": { @@ -5334,9 +5611,9 @@ "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", "dev": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.7", - "mime-types": "2.1.21" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, "forwarded": { @@ -5351,7 +5628,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -5366,9 +5643,9 @@ "integrity": "sha512-K27M3VK30wVoOarP651zDmb93R9zF28usW4ocaK3mfQeIEI5BPht/EzZs5E8QLLwbLRJQMwscAjDxYPb1FuNiw==", "dev": true, "requires": { - "chalk": "1.1.3", - "error-stack-parser": "2.0.2", - "string-width": "2.1.1" + "chalk": "^1.1.3", + "error-stack-parser": "^2.0.0", + "string-width": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -5389,11 +5666,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "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" } }, "strip-ansi": { @@ -5402,7 +5679,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "supports-color": { @@ -5419,8 +5696,8 @@ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.6" + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" } }, "fs-extra": { @@ -5429,9 +5706,9 @@ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "jsonfile": "4.0.0", - "universalify": "0.1.2" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs-write-stream-atomic": { @@ -5440,10 +5717,10 @@ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "iferr": "0.1.5", - "imurmurhash": "0.1.4", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" } }, "fs.realpath": { @@ -5459,8 +5736,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -5486,8 +5763,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { @@ -5500,7 +5777,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -5564,7 +5841,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -5579,14 +5856,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "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": { @@ -5595,12 +5872,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "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": { @@ -5615,7 +5892,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "^2.1.0" } }, "ignore-walk": { @@ -5624,7 +5901,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -5633,8 +5910,8 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -5653,7 +5930,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -5667,7 +5944,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -5680,8 +5957,8 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" } }, "minizlib": { @@ -5690,7 +5967,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -5713,9 +5990,9 @@ "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { @@ -5724,16 +6001,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -5742,8 +6019,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { @@ -5758,8 +6035,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -5768,10 +6045,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "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": { @@ -5790,7 +6067,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -5811,8 +6088,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -5833,10 +6110,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -5853,13 +6130,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "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.2" + "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": { @@ -5868,7 +6145,7 @@ "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -5911,9 +6188,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -5922,7 +6199,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -5930,7 +6207,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -5945,13 +6222,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -5966,7 +6243,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -6011,7 +6288,7 @@ "integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=", "dev": true, "requires": { - "pump": "3.0.0" + "pump": "^3.0.0" } }, "get-value": { @@ -6026,7 +6303,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -6035,12 +6312,12 @@ "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "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-base": { @@ -6049,8 +6326,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" }, "dependencies": { "glob-parent": { @@ -6059,7 +6336,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "is-extglob": { @@ -6074,7 +6351,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } } } @@ -6085,8 +6362,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -6095,7 +6372,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -6118,13 +6395,13 @@ "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", "dev": true, "requires": { - "array-union": "1.0.2", - "dir-glob": "2.0.0", - "fast-glob": "2.2.4", - "glob": "7.1.3", - "ignore": "3.3.10", - "pify": "3.0.0", - "slash": "1.0.0" + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" } }, "graceful-fs": { @@ -6145,8 +6422,8 @@ "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==", "dev": true, "requires": { - "duplexer": "0.1.1", - "pify": "3.0.0" + "duplexer": "^0.1.1", + "pify": "^3.0.0" } }, "handle-thing": { @@ -6156,24 +6433,24 @@ "dev": true }, "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", + "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", "dev": true, "requires": { - "async": "2.6.1", - "optimist": "0.6.1", - "source-map": "0.6.1", - "uglify-js": "3.4.9" + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.11" } }, "source-map": { @@ -6196,8 +6473,8 @@ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "6.5.5", - "har-schema": "2.0.0" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "has": { @@ -6206,7 +6483,7 @@ "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", "dev": true, "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.1.1" } }, "has-ansi": { @@ -6215,7 +6492,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -6226,6 +6503,26 @@ } } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -6244,9 +6541,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -6255,8 +6552,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -6265,7 +6562,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -6276,8 +6573,8 @@ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "hash-sum": { @@ -6292,8 +6589,8 @@ "integrity": "sha1-44q0uF37HgxA/pJlwOm1SFTCOBI=", "dev": true, "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, "he": { @@ -6314,9 +6611,9 @@ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "hash.js": "1.1.5", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "hoek": { @@ -6331,8 +6628,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "hoopy": { @@ -6353,10 +6650,10 @@ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "dev": true, "requires": { - "inherits": "2.0.3", - "obuf": "1.1.2", - "readable-stream": "2.3.6", - "wbuf": "1.7.3" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, "hsl-regex": { @@ -6383,7 +6680,7 @@ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { - "whatwg-encoding": "1.0.5" + "whatwg-encoding": "^1.0.1" } }, "html-entities": { @@ -6398,13 +6695,13 @@ "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", "dev": true, "requires": { - "camel-case": "3.0.0", - "clean-css": "4.2.1", - "commander": "2.17.1", - "he": "1.2.0", - "param-case": "2.1.1", - "relateurl": "0.2.7", - "uglify-js": "3.4.9" + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" } }, "html-webpack-plugin": { @@ -6413,12 +6710,12 @@ "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", "dev": true, "requires": { - "html-minifier": "3.5.21", - "loader-utils": "0.2.17", - "lodash": "4.17.11", - "pretty-error": "2.1.1", - "tapable": "1.1.0", - "toposort": "1.0.7", + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", "util.promisify": "1.0.0" }, "dependencies": { @@ -6434,10 +6731,10 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } } } @@ -6448,10 +6745,10 @@ "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", "dev": true, "requires": { - "domelementtype": "1.2.1", - "domhandler": "2.1.0", - "domutils": "1.1.6", - "readable-stream": "1.0.34" + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" }, "dependencies": { "domutils": { @@ -6460,7 +6757,7 @@ "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", "dev": true, "requires": { - "domelementtype": "1.2.1" + "domelementtype": "1" } }, "isarray": { @@ -6475,10 +6772,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -6501,10 +6798,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "http-parser-js": { @@ -6519,9 +6816,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "3.1.0", - "follow-redirects": "1.5.9", - "requires-port": "1.0.0" + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, "http-proxy-middleware": { @@ -6530,10 +6827,10 @@ "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", "dev": true, "requires": { - "http-proxy": "1.17.0", - "is-glob": "4.0.0", - "lodash": "4.17.11", - "micromatch": "3.1.10" + "http-proxy": "^1.16.2", + "is-glob": "^4.0.0", + "lodash": "^4.17.5", + "micromatch": "^3.1.9" } }, "http-signature": { @@ -6542,9 +6839,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.15.2" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-browserify": { @@ -6559,7 +6856,7 @@ "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "icss-replace-symbols": { @@ -6574,7 +6871,7 @@ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", "dev": true, "requires": { - "postcss": "6.0.23" + "postcss": "^6.0.1" }, "dependencies": { "postcss": { @@ -6583,9 +6880,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -6620,7 +6917,7 @@ "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", "dev": true, "requires": { - "import-from": "2.1.0" + "import-from": "^2.1.0" } }, "import-fresh": { @@ -6629,8 +6926,8 @@ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { - "caller-path": "2.0.0", - "resolve-from": "3.0.0" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" }, "dependencies": { "caller-path": { @@ -6639,7 +6936,7 @@ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { - "caller-callsite": "2.0.0" + "caller-callsite": "^2.0.0" } }, "resolve-from": { @@ -6656,7 +6953,7 @@ "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", "dev": true, "requires": { - "resolve-from": "3.0.0" + "resolve-from": "^3.0.0" }, "dependencies": { "resolve-from": { @@ -6673,8 +6970,8 @@ "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { - "pkg-dir": "3.0.0", - "resolve-cwd": "2.0.0" + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" }, "dependencies": { "find-up": { @@ -6683,7 +6980,7 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, "locate-path": { @@ -6692,8 +6989,8 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "p-limit": { @@ -6702,7 +6999,7 @@ "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -6711,7 +7008,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { @@ -6726,7 +7023,7 @@ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "3.0.0" + "find-up": "^3.0.0" } } } @@ -6746,8 +7043,7 @@ "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, "inflight": { "version": "1.0.6", @@ -6755,8 +7051,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -6777,20 +7073,20 @@ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "3.1.0", - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.2.0", - "figures": "2.0.0", - "lodash": "4.17.11", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, "internal-ip": { @@ -6799,17 +7095,22 @@ "integrity": "sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==", "dev": true, "requires": { - "default-gateway": "2.7.2", - "ipaddr.js": "1.8.0" + "default-gateway": "^2.6.0", + "ipaddr.js": "^1.5.2" } }, + "intersection-observer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.5.1.tgz", + "integrity": "sha512-Zd7Plneq82kiXFixs7bX62YnuZ0BMRci9br7io88LwDyF3V43cQMI+G5IiTlTNTt+LsDUppl19J/M2Fp9UkH6g==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", "dev": true, "requires": { - "loose-envify": "1.4.0" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -6848,7 +7149,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -6857,7 +7158,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -6874,7 +7175,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -6888,7 +7189,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-callable": { @@ -6903,7 +7204,7 @@ "integrity": "sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw=", "dev": true, "requires": { - "ci-info": "1.6.0" + "ci-info": "^1.5.0" } }, "is-color-stop": { @@ -6912,12 +7213,12 @@ "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", "dev": true, "requires": { - "css-color-names": "0.0.4", - "hex-color-regex": "1.1.0", - "hsl-regex": "1.0.0", - "hsla-regex": "1.0.0", - "rgb-regex": "1.0.1", - "rgba-regex": "1.0.0" + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" } }, "is-data-descriptor": { @@ -6926,7 +7227,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -6935,7 +7236,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -6952,9 +7253,9 @@ "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -6983,7 +7284,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -7004,7 +7305,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -7025,7 +7326,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-number": { @@ -7034,7 +7335,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -7043,7 +7344,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -7066,7 +7367,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -7075,7 +7376,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -7084,7 +7385,7 @@ "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-posix-bracket": { @@ -7111,7 +7412,7 @@ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, "requires": { - "has": "1.0.3" + "has": "^1.0.1" } }, "is-resolvable": { @@ -7132,7 +7433,7 @@ "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", "dev": true, "requires": { - "html-comment-regex": "1.1.2" + "html-comment-regex": "^1.1.0" } }, "is-symbol": { @@ -7141,7 +7442,7 @@ "integrity": "sha1-oFX2rlcZLK7jKeeoYBGLSXqVDzg=", "dev": true, "requires": { - "has-symbols": "1.0.0" + "has-symbols": "^1.0.0" } }, "is-typedarray": { @@ -7186,7 +7487,7 @@ "integrity": "sha1-WTEKAhkxqfsGu7UeFVzgs/I2gyw=", "dev": true, "requires": { - "punycode": "2.1.1" + "punycode": "2.x.x" } }, "isexe": { @@ -7213,26 +7514,26 @@ "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", "dev": true, "requires": { - "async": "2.6.1", - "fileset": "2.0.3", - "istanbul-lib-coverage": "1.2.1", - "istanbul-lib-hook": "1.2.2", - "istanbul-lib-instrument": "1.10.2", - "istanbul-lib-report": "1.1.5", - "istanbul-lib-source-maps": "1.2.6", - "istanbul-reports": "1.5.1", - "js-yaml": "3.12.0", - "mkdirp": "0.5.1", - "once": "1.4.0" + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.11" } } } @@ -7249,7 +7550,7 @@ "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", "dev": true, "requires": { - "append-transform": "0.4.0" + "append-transform": "^0.4.0" } }, "istanbul-lib-instrument": { @@ -7258,13 +7559,13 @@ "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", "dev": true, "requires": { - "babel-generator": "6.26.1", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.2.1", - "semver": "5.6.0" + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" } }, "istanbul-lib-report": { @@ -7273,10 +7574,10 @@ "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", "dev": true, "requires": { - "istanbul-lib-coverage": "1.2.1", - "mkdirp": "0.5.1", - "path-parse": "1.0.6", - "supports-color": "3.2.3" + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" }, "dependencies": { "has-flag": { @@ -7291,7 +7592,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -7302,11 +7603,11 @@ "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", "dev": true, "requires": { - "debug": "3.1.0", - "istanbul-lib-coverage": "1.2.1", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "source-map": "0.5.7" + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" } }, "istanbul-reports": { @@ -7315,7 +7616,7 @@ "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", "dev": true, "requires": { - "handlebars": "4.0.12" + "handlebars": "^4.0.3" } }, "javascript-stringify": { @@ -7330,8 +7631,8 @@ "integrity": "sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw==", "dev": true, "requires": { - "import-local": "1.0.0", - "jest-cli": "23.6.0" + "import-local": "^1.0.0", + "jest-cli": "^23.6.0" }, "dependencies": { "arr-diff": { @@ -7340,7 +7641,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -7355,9 +7656,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "cross-spawn": { @@ -7366,9 +7667,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "decamelize": { @@ -7383,13 +7684,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -7398,7 +7699,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -7407,7 +7708,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "get-stream": { @@ -7422,8 +7723,8 @@ "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", "dev": true, "requires": { - "pkg-dir": "2.0.0", - "resolve-cwd": "2.0.0" + "pkg-dir": "^2.0.0", + "resolve-cwd": "^2.0.0" } }, "invert-kv": { @@ -7444,7 +7745,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "jest-cli": { @@ -7453,42 +7754,42 @@ "integrity": "sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ==", "dev": true, "requires": { - "ansi-escapes": "3.1.0", - "chalk": "2.4.1", - "exit": "0.1.2", - "glob": "7.1.3", - "graceful-fs": "4.1.15", - "import-local": "1.0.0", - "is-ci": "1.2.1", - "istanbul-api": "1.3.7", - "istanbul-lib-coverage": "1.2.1", - "istanbul-lib-instrument": "1.10.2", - "istanbul-lib-source-maps": "1.2.6", - "jest-changed-files": "23.4.2", - "jest-config": "23.6.0", - "jest-environment-jsdom": "23.4.0", - "jest-get-type": "22.4.3", - "jest-haste-map": "23.6.0", - "jest-message-util": "23.4.0", - "jest-regex-util": "23.3.0", - "jest-resolve-dependencies": "23.6.0", - "jest-runner": "23.6.0", - "jest-runtime": "23.6.0", - "jest-snapshot": "23.6.0", - "jest-util": "23.4.0", - "jest-validate": "23.6.0", - "jest-watcher": "23.4.0", - "jest-worker": "23.2.0", - "micromatch": "2.3.11", - "node-notifier": "5.3.0", - "prompts": "0.1.14", - "realpath-native": "1.0.2", - "rimraf": "2.6.2", - "slash": "1.0.0", - "string-length": "2.0.0", - "strip-ansi": "4.0.0", - "which": "1.3.1", - "yargs": "11.1.0" + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "import-local": "^1.0.0", + "is-ci": "^1.0.10", + "istanbul-api": "^1.3.1", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-source-maps": "^1.2.4", + "jest-changed-files": "^23.4.2", + "jest-config": "^23.6.0", + "jest-environment-jsdom": "^23.4.0", + "jest-get-type": "^22.1.0", + "jest-haste-map": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0", + "jest-resolve-dependencies": "^23.6.0", + "jest-runner": "^23.6.0", + "jest-runtime": "^23.6.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "jest-watcher": "^23.4.0", + "jest-worker": "^23.2.0", + "micromatch": "^2.3.11", + "node-notifier": "^5.2.1", + "prompts": "^0.1.9", + "realpath-native": "^1.0.0", + "rimraf": "^2.5.4", + "slash": "^1.0.0", + "string-length": "^2.0.0", + "strip-ansi": "^4.0.0", + "which": "^1.2.12", + "yargs": "^11.0.0" } }, "kind-of": { @@ -7497,7 +7798,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "lcid": { @@ -7506,7 +7807,7 @@ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "mem": { @@ -7515,7 +7816,7 @@ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "micromatch": { @@ -7524,19 +7825,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "os-locale": { @@ -7545,9 +7846,9 @@ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, "y18n": { @@ -7562,18 +7863,18 @@ "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.3", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" } }, "yargs-parser": { @@ -7582,7 +7883,7 @@ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -7593,7 +7894,7 @@ "integrity": "sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA==", "dev": true, "requires": { - "throat": "4.1.0" + "throat": "^4.0.0" } }, "jest-config": { @@ -7602,20 +7903,20 @@ "integrity": "sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ==", "dev": true, "requires": { - "babel-core": "6.26.3", - "babel-jest": "23.6.0", - "chalk": "2.4.1", - "glob": "7.1.3", - "jest-environment-jsdom": "23.4.0", - "jest-environment-node": "23.4.0", - "jest-get-type": "22.4.3", - "jest-jasmine2": "23.6.0", - "jest-regex-util": "23.3.0", - "jest-resolve": "23.6.0", - "jest-util": "23.4.0", - "jest-validate": "23.6.0", - "micromatch": "2.3.11", - "pretty-format": "23.6.0" + "babel-core": "^6.0.0", + "babel-jest": "^23.6.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^23.4.0", + "jest-environment-node": "^23.4.0", + "jest-get-type": "^22.1.0", + "jest-jasmine2": "^23.6.0", + "jest-regex-util": "^23.3.0", + "jest-resolve": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "micromatch": "^2.3.11", + "pretty-format": "^23.6.0" }, "dependencies": { "arr-diff": { @@ -7624,7 +7925,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -7639,25 +7940,51 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.6.0", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "babel-jest": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.6.0.tgz", + "integrity": "sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.6", + "babel-preset-jest": "^23.2.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz", + "integrity": "sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=", + "dev": true + }, + "babel-preset-jest": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", + "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^23.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" } }, "braces": { @@ -7666,9 +7993,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "debug": { @@ -7686,7 +8013,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -7695,7 +8022,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-extglob": { @@ -7710,7 +8037,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "json5": { @@ -7725,7 +8052,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "micromatch": { @@ -7734,19 +8061,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } } } @@ -7757,10 +8084,10 @@ "integrity": "sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g==", "dev": true, "requires": { - "chalk": "2.4.1", - "diff": "3.5.0", - "jest-get-type": "22.4.3", - "pretty-format": "23.6.0" + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.6.0" } }, "jest-docblock": { @@ -7769,7 +8096,7 @@ "integrity": "sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=", "dev": true, "requires": { - "detect-newline": "2.1.0" + "detect-newline": "^2.1.0" } }, "jest-each": { @@ -7778,8 +8105,8 @@ "integrity": "sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg==", "dev": true, "requires": { - "chalk": "2.4.1", - "pretty-format": "23.6.0" + "chalk": "^2.0.1", + "pretty-format": "^23.6.0" } }, "jest-environment-jsdom": { @@ -7788,9 +8115,9 @@ "integrity": "sha1-BWp5UrP+pROsYqFAosNox52eYCM=", "dev": true, "requires": { - "jest-mock": "23.2.0", - "jest-util": "23.4.0", - "jsdom": "11.12.0" + "jest-mock": "^23.2.0", + "jest-util": "^23.4.0", + "jsdom": "^11.5.1" } }, "jest-environment-node": { @@ -7799,8 +8126,8 @@ "integrity": "sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA=", "dev": true, "requires": { - "jest-mock": "23.2.0", - "jest-util": "23.4.0" + "jest-mock": "^23.2.0", + "jest-util": "^23.4.0" } }, "jest-get-type": { @@ -7815,14 +8142,14 @@ "integrity": "sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg==", "dev": true, "requires": { - "fb-watchman": "2.0.0", - "graceful-fs": "4.1.15", - "invariant": "2.2.4", - "jest-docblock": "23.2.0", - "jest-serializer": "23.0.1", - "jest-worker": "23.2.0", - "micromatch": "2.3.11", - "sane": "2.5.2" + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "invariant": "^2.2.4", + "jest-docblock": "^23.2.0", + "jest-serializer": "^23.0.1", + "jest-worker": "^23.2.0", + "micromatch": "^2.3.11", + "sane": "^2.0.0" }, "dependencies": { "arr-diff": { @@ -7831,7 +8158,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -7846,9 +8173,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "expand-brackets": { @@ -7857,7 +8184,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -7866,7 +8193,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-extglob": { @@ -7881,7 +8208,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "kind-of": { @@ -7890,7 +8217,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "micromatch": { @@ -7899,19 +8226,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } } } @@ -7922,18 +8249,18 @@ "integrity": "sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ==", "dev": true, "requires": { - "babel-traverse": "6.26.0", - "chalk": "2.4.1", - "co": "4.6.0", - "expect": "23.6.0", - "is-generator-fn": "1.0.0", - "jest-diff": "23.6.0", - "jest-each": "23.6.0", - "jest-matcher-utils": "23.6.0", - "jest-message-util": "23.4.0", - "jest-snapshot": "23.6.0", - "jest-util": "23.4.0", - "pretty-format": "23.6.0" + "babel-traverse": "^6.0.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^23.6.0", + "is-generator-fn": "^1.0.0", + "jest-diff": "^23.6.0", + "jest-each": "^23.6.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "pretty-format": "^23.6.0" } }, "jest-leak-detector": { @@ -7942,7 +8269,7 @@ "integrity": "sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg==", "dev": true, "requires": { - "pretty-format": "23.6.0" + "pretty-format": "^23.6.0" } }, "jest-matcher-utils": { @@ -7951,9 +8278,9 @@ "integrity": "sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog==", "dev": true, "requires": { - "chalk": "2.4.1", - "jest-get-type": "22.4.3", - "pretty-format": "23.6.0" + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.6.0" } }, "jest-message-util": { @@ -7962,11 +8289,11 @@ "integrity": "sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8=", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "chalk": "2.4.1", - "micromatch": "2.3.11", - "slash": "1.0.0", - "stack-utils": "1.0.2" + "@babel/code-frame": "^7.0.0-beta.35", + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "stack-utils": "^1.0.1" }, "dependencies": { "arr-diff": { @@ -7975,7 +8302,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -7990,9 +8317,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "expand-brackets": { @@ -8001,7 +8328,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -8010,7 +8337,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-extglob": { @@ -8025,7 +8352,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "kind-of": { @@ -8034,7 +8361,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "micromatch": { @@ -8043,19 +8370,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } } } @@ -8078,9 +8405,9 @@ "integrity": "sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA==", "dev": true, "requires": { - "browser-resolve": "1.11.3", - "chalk": "2.4.1", - "realpath-native": "1.0.2" + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "realpath-native": "^1.0.0" } }, "jest-resolve-dependencies": { @@ -8089,8 +8416,8 @@ "integrity": "sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA==", "dev": true, "requires": { - "jest-regex-util": "23.3.0", - "jest-snapshot": "23.6.0" + "jest-regex-util": "^23.3.0", + "jest-snapshot": "^23.6.0" } }, "jest-runner": { @@ -8099,19 +8426,19 @@ "integrity": "sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA==", "dev": true, "requires": { - "exit": "0.1.2", - "graceful-fs": "4.1.15", - "jest-config": "23.6.0", - "jest-docblock": "23.2.0", - "jest-haste-map": "23.6.0", - "jest-jasmine2": "23.6.0", - "jest-leak-detector": "23.6.0", - "jest-message-util": "23.4.0", - "jest-runtime": "23.6.0", - "jest-util": "23.4.0", - "jest-worker": "23.2.0", - "source-map-support": "0.5.9", - "throat": "4.1.0" + "exit": "^0.1.2", + "graceful-fs": "^4.1.11", + "jest-config": "^23.6.0", + "jest-docblock": "^23.2.0", + "jest-haste-map": "^23.6.0", + "jest-jasmine2": "^23.6.0", + "jest-leak-detector": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-runtime": "^23.6.0", + "jest-util": "^23.4.0", + "jest-worker": "^23.2.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" } }, "jest-runtime": { @@ -8120,27 +8447,27 @@ "integrity": "sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw==", "dev": true, "requires": { - "babel-core": "6.26.3", - "babel-plugin-istanbul": "4.1.6", - "chalk": "2.4.1", - "convert-source-map": "1.6.0", - "exit": "0.1.2", - "fast-json-stable-stringify": "2.0.0", - "graceful-fs": "4.1.15", - "jest-config": "23.6.0", - "jest-haste-map": "23.6.0", - "jest-message-util": "23.4.0", - "jest-regex-util": "23.3.0", - "jest-resolve": "23.6.0", - "jest-snapshot": "23.6.0", - "jest-util": "23.4.0", - "jest-validate": "23.6.0", - "micromatch": "2.3.11", - "realpath-native": "1.0.2", - "slash": "1.0.0", + "babel-core": "^6.0.0", + "babel-plugin-istanbul": "^4.1.6", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "exit": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-config": "^23.6.0", + "jest-haste-map": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0", + "jest-resolve": "^23.6.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "micromatch": "^2.3.11", + "realpath-native": "^1.0.0", + "slash": "^1.0.0", "strip-bom": "3.0.0", - "write-file-atomic": "2.3.0", - "yargs": "11.1.0" + "write-file-atomic": "^2.1.0", + "yargs": "^11.0.0" }, "dependencies": { "arr-diff": { @@ -8149,7 +8476,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -8164,25 +8491,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.6.0", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" } }, "braces": { @@ -8191,9 +8518,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "cross-spawn": { @@ -8202,9 +8529,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { @@ -8228,13 +8555,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -8243,7 +8570,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -8252,7 +8579,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "get-stream": { @@ -8279,7 +8606,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "json5": { @@ -8294,7 +8621,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "lcid": { @@ -8303,7 +8630,7 @@ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "mem": { @@ -8312,7 +8639,7 @@ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "micromatch": { @@ -8321,19 +8648,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "os-locale": { @@ -8342,9 +8669,9 @@ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, "strip-bom": { @@ -8365,18 +8692,18 @@ "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.3", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" } }, "yargs-parser": { @@ -8385,7 +8712,7 @@ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -8411,16 +8738,16 @@ "integrity": "sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg==", "dev": true, "requires": { - "babel-types": "6.26.0", - "chalk": "2.4.1", - "jest-diff": "23.6.0", - "jest-matcher-utils": "23.6.0", - "jest-message-util": "23.4.0", - "jest-resolve": "23.6.0", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "pretty-format": "23.6.0", - "semver": "5.6.0" + "babel-types": "^6.0.0", + "chalk": "^2.0.1", + "jest-diff": "^23.6.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-resolve": "^23.6.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^23.6.0", + "semver": "^5.5.0" } }, "jest-transform-stub": { @@ -8435,14 +8762,14 @@ "integrity": "sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE=", "dev": true, "requires": { - "callsites": "2.0.0", - "chalk": "2.4.1", - "graceful-fs": "4.1.15", - "is-ci": "1.2.1", - "jest-message-util": "23.4.0", - "mkdirp": "0.5.1", - "slash": "1.0.0", - "source-map": "0.6.1" + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "jest-message-util": "^23.4.0", + "mkdirp": "^0.5.1", + "slash": "^1.0.0", + "source-map": "^0.6.0" }, "dependencies": { "callsites": { @@ -8465,10 +8792,10 @@ "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", "dev": true, "requires": { - "chalk": "2.4.1", - "jest-get-type": "22.4.3", - "leven": "2.1.0", - "pretty-format": "23.6.0" + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^23.6.0" } }, "jest-watcher": { @@ -8477,9 +8804,9 @@ "integrity": "sha1-0uKM50+NrWxq/JIrksq+9u0FyRw=", "dev": true, "requires": { - "ansi-escapes": "3.1.0", - "chalk": "2.4.1", - "string-length": "2.0.0" + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "string-length": "^2.0.0" } }, "jest-worker": { @@ -8488,7 +8815,7 @@ "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", "dev": true, "requires": { - "merge-stream": "1.0.1" + "merge-stream": "^1.0.1" } }, "joi": { @@ -8497,9 +8824,9 @@ "integrity": "sha1-z9hev+Z+ihkAQyQAtNA7vZP7h58=", "dev": true, "requires": { - "hoek": "5.0.4", - "isemail": "3.2.0", - "topo": "3.0.3" + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" } }, "jquery": { @@ -8513,11 +8840,11 @@ "integrity": "sha512-MwPmLywK9RSX0SPsUJjN7i+RQY9w/yC17Lbrq9ViEefpLRgqAR2BgrMN2AbifkUuhDV8tRauLhLda/9+bE0YQA==", "dev": true, "requires": { - "config-chain": "1.1.12", - "editorconfig": "0.15.2", - "glob": "7.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1" + "config-chain": "^1.1.12", + "editorconfig": "^0.15.2", + "glob": "^7.1.3", + "mkdirp": "~0.5.0", + "nopt": "~4.0.1" } }, "js-levenshtein": { @@ -8538,7 +8865,7 @@ "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", "dev": true, "requires": { - "easy-stack": "1.0.0" + "easy-stack": "^1.0.0" } }, "js-tokens": { @@ -8553,8 +8880,8 @@ "integrity": "sha1-6u1lbsg0TxD1J8a/obbiJE3hZ9E=", "dev": true, "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { @@ -8569,32 +8896,32 @@ "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", "dev": true, "requires": { - "abab": "2.0.0", - "acorn": "5.7.3", - "acorn-globals": "4.3.0", - "array-equal": "1.0.0", - "cssom": "0.3.4", - "cssstyle": "1.1.1", - "data-urls": "1.1.0", - "domexception": "1.0.1", - "escodegen": "1.11.0", - "html-encoding-sniffer": "1.0.2", - "left-pad": "1.3.0", - "nwsapi": "2.0.9", + "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.88.0", - "request-promise-native": "1.0.5", - "sax": "1.2.4", - "symbol-tree": "3.2.2", - "tough-cookie": "2.4.3", - "w3c-hr-time": "1.0.1", - "webidl-conversions": "4.0.2", - "whatwg-encoding": "1.0.5", - "whatwg-mimetype": "2.3.0", - "whatwg-url": "6.5.0", - "ws": "5.2.2", - "xml-name-validator": "3.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" }, "dependencies": { "ws": { @@ -8603,7 +8930,7 @@ "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "dev": true, "requires": { - "async-limiter": "1.0.0" + "async-limiter": "~1.0.0" } } } @@ -8656,7 +8983,7 @@ "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "jsonfile": { @@ -8665,7 +8992,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "4.1.15" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -8710,8 +9037,8 @@ "integrity": "sha1-hxtaPuOdZoD8wm03kwtu7aidsMo=", "dev": true, "requires": { - "chalk": "2.4.1", - "shell-quote": "1.6.1" + "chalk": "^2.3.0", + "shell-quote": "^1.6.1" } }, "launch-editor-middleware": { @@ -8720,7 +9047,7 @@ "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==", "dev": true, "requires": { - "launch-editor": "2.2.1" + "launch-editor": "^2.2.1" } }, "lcid": { @@ -8729,7 +9056,7 @@ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "invert-kv": "2.0.0" + "invert-kv": "^2.0.0" } }, "left-pad": { @@ -8750,8 +9077,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "load-json-file": { @@ -8760,11 +9087,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" }, "dependencies": { "parse-json": { @@ -8773,7 +9100,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.2" + "error-ex": "^1.2.0" } }, "pify": { @@ -8790,7 +9117,7 @@ "integrity": "sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw=", "dev": true, "requires": { - "find-cache-dir": "0.1.1", + "find-cache-dir": "^0.1.1", "mkdirp": "0.5.1" }, "dependencies": { @@ -8800,9 +9127,9 @@ "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { - "commondir": "1.0.1", - "mkdirp": "0.5.1", - "pkg-dir": "1.0.0" + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" } }, "find-up": { @@ -8811,8 +9138,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "path-exists": { @@ -8821,7 +9148,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "pkg-dir": { @@ -8830,7 +9157,7 @@ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" } } } @@ -8847,9 +9174,9 @@ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "dev": true, "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" }, "dependencies": { "json5": { @@ -8866,8 +9193,8 @@ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { @@ -8929,7 +9256,7 @@ "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=", "dev": true, "requires": { - "chalk": "2.4.1" + "chalk": "^2.0.1" } }, "loglevel": { @@ -8944,7 +9271,7 @@ "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", "dev": true, "requires": { - "js-tokens": "4.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "lower-case": { @@ -8959,8 +9286,8 @@ "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "make-dir": { @@ -8969,7 +9296,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "makeerror": { @@ -8978,7 +9305,7 @@ "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", "dev": true, "requires": { - "tmpl": "1.0.4" + "tmpl": "1.0.x" } }, "map-age-cleaner": { @@ -8987,7 +9314,7 @@ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { - "p-defer": "1.0.0" + "p-defer": "^1.0.0" } }, "map-cache": { @@ -9002,7 +9329,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "math-random": { @@ -9017,9 +9344,9 @@ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "mdn-data": { @@ -9040,9 +9367,9 @@ "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", "dev": true, "requires": { - "map-age-cleaner": "0.1.3", - "mimic-fn": "1.2.0", - "p-is-promise": "1.1.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" } }, "memory-fs": { @@ -9051,8 +9378,8 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.6" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "merge": { @@ -9073,7 +9400,7 @@ "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { - "source-map": "0.6.1" + "source-map": "^0.6.1" }, "dependencies": { "source-map": { @@ -9090,7 +9417,7 @@ "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", "dev": true, "requires": { - "readable-stream": "2.3.6" + "readable-stream": "^2.0.1" } }, "merge2": { @@ -9111,19 +9438,19 @@ "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "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.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "miller-rabin": { @@ -9132,8 +9459,8 @@ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0" + "bn.js": "^4.0.0", + "brorand": "^1.0.1" } }, "mime": { @@ -9154,7 +9481,7 @@ "integrity": "sha1-KJlaoey3cHQv5q5+WPkYHHRLP5Y=", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "mimic-fn": { @@ -9169,9 +9496,9 @@ "integrity": "sha1-wQQQoASVG9PO2sHaaQU5QPzLYl0=", "dev": true, "requires": { - "loader-utils": "1.1.0", - "schema-utils": "1.0.0", - "webpack-sources": "1.3.0" + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" }, "dependencies": { "ajv-keywords": { @@ -9186,9 +9513,9 @@ "integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -9211,7 +9538,7 @@ "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -9226,16 +9553,16 @@ "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "duplexify": "3.6.1", - "end-of-stream": "1.4.1", - "flush-write-stream": "1.0.3", - "from2": "2.3.0", - "parallel-transform": "1.1.0", - "pump": "2.0.1", - "pumpify": "1.5.1", - "stream-each": "1.2.3", - "through2": "2.0.5" + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^2.0.1", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" }, "dependencies": { "pump": { @@ -9244,8 +9571,8 @@ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } } @@ -9256,8 +9583,8 @@ "integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -9266,7 +9593,7 @@ "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -9294,12 +9621,12 @@ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", "dev": true, "requires": { - "aproba": "1.2.0", - "copy-concurrently": "1.0.5", - "fs-write-stream-atomic": "1.0.10", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" + "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": { @@ -9313,8 +9640,8 @@ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", "dev": true, "requires": { - "dns-packet": "1.3.1", - "thunky": "1.0.3" + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" } }, "multicast-dns-service-types": { @@ -9342,17 +9669,17 @@ "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "natural-compare": { @@ -9385,7 +9712,7 @@ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { - "lower-case": "1.1.4" + "lower-case": "^1.1.1" } }, "node-cache": { @@ -9394,8 +9721,8 @@ "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", "dev": true, "requires": { - "clone": "2.1.2", - "lodash": "4.17.11" + "clone": "2.x", + "lodash": "4.x" }, "dependencies": { "clone": { @@ -9435,28 +9762,28 @@ "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "dev": true, "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.2.0", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "1.2.0", - "events": "1.1.1", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.6", - "stream-browserify": "2.0.1", - "stream-http": "2.8.3", - "string_decoder": "1.1.1", - "timers-browserify": "2.0.10", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.4", + "url": "^0.11.0", + "util": "^0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { @@ -9469,15 +9796,16 @@ } }, "node-notifier": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz", - "integrity": "sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", + "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", "dev": true, "requires": { - "growly": "1.3.0", - "semver": "5.6.0", - "shellwords": "0.1.1", - "which": "1.3.1" + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" } }, "node-releases": { @@ -9486,7 +9814,7 @@ "integrity": "sha1-NBTthFlQlkWcJRaZv8tH2IMkqeQ=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.3.0" } }, "nopt": { @@ -9495,8 +9823,8 @@ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "normalize-package-data": { @@ -9505,10 +9833,10 @@ "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "dev": true, "requires": { - "hosted-git-info": "2.7.1", - "is-builtin-module": "1.0.0", - "semver": "5.6.0", - "validate-npm-package-license": "3.0.4" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -9517,7 +9845,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "normalize-range": { @@ -9538,7 +9866,7 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "nth-check": { @@ -9547,7 +9875,7 @@ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", "dev": true, "requires": { - "boolbase": "1.0.0" + "boolbase": "~1.0.0" } }, "num2fraction": { @@ -9563,9 +9891,9 @@ "dev": true }, "nwsapi": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz", - "integrity": "sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.0.tgz", + "integrity": "sha512-ZG3bLAvdHmhIjaQ/Db1qvBxsGvFMLIRpQszyqbg31VJ53UP++uZX1/gf3Ut96pdwN9AuDwlMqIYLm0UPCdUeHg==", "dev": true }, "oauth-sign": { @@ -9580,15 +9908,20 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -9597,7 +9930,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -9606,7 +9939,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -9629,7 +9962,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.assign": { @@ -9638,10 +9971,10 @@ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "define-properties": "1.1.3", - "function-bind": "1.1.1", - "has-symbols": "1.0.0", - "object-keys": "1.0.12" + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" } }, "object.getownpropertydescriptors": { @@ -9650,8 +9983,8 @@ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", "dev": true, "requires": { - "define-properties": "1.1.3", - "es-abstract": "1.12.0" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" } }, "object.omit": { @@ -9660,8 +9993,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -9670,7 +10003,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "object.values": { @@ -9679,10 +10012,10 @@ "integrity": "sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=", "dev": true, "requires": { - "define-properties": "1.1.3", - "es-abstract": "1.12.0", - "function-bind": "1.1.1", - "has": "1.0.3" + "define-properties": "^1.1.2", + "es-abstract": "^1.6.1", + "function-bind": "^1.1.0", + "has": "^1.0.1" } }, "obuf": { @@ -9712,7 +10045,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -9721,7 +10054,7 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "opener": { @@ -9736,7 +10069,7 @@ "integrity": "sha1-y1Reeqt4VivrEao7+rxwQuF2EDU=", "dev": true, "requires": { - "is-wsl": "1.1.0" + "is-wsl": "^1.1.0" } }, "optimist": { @@ -9745,8 +10078,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.10", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "minimist": { @@ -9769,12 +10102,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "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", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "ora": { @@ -9783,12 +10116,12 @@ "integrity": "sha1-bK8oMOuSSUGGHsU6FzeZ4Ai1Hls=", "dev": true, "requires": { - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0", - "strip-ansi": "4.0.0", - "wcwidth": "1.0.1" + "chalk": "^2.3.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.1.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^4.0.0", + "wcwidth": "^1.0.1" } }, "original": { @@ -9797,7 +10130,7 @@ "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { - "url-parse": "1.4.4" + "url-parse": "^1.4.3" } }, "os-browserify": { @@ -9818,9 +10151,9 @@ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { - "execa": "1.0.0", - "lcid": "2.0.0", - "mem": "4.0.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, "os-tmpdir": { @@ -9835,8 +10168,8 @@ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "p-defer": { @@ -9863,7 +10196,7 @@ "integrity": "sha1-uGvV8MJWkJEcdZD8v8IBDVSzzLg=", "dev": true, "requires": { - "p-try": "1.0.0" + "p-try": "^1.0.0" } }, "p-locate": { @@ -9872,7 +10205,7 @@ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "1.3.0" + "p-limit": "^1.1.0" } }, "p-map": { @@ -9904,9 +10237,9 @@ "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", "dev": true, "requires": { - "cyclist": "0.2.2", - "inherits": "2.0.3", - "readable-stream": "2.3.6" + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" } }, "param-case": { @@ -9915,7 +10248,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "2.3.2" + "no-case": "^2.2.0" } }, "parse-asn1": { @@ -9924,11 +10257,11 @@ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.2.0", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.17" + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" } }, "parse-glob": { @@ -9937,10 +10270,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" }, "dependencies": { "is-extglob": { @@ -9955,7 +10288,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } } } @@ -9966,8 +10299,8 @@ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "1.3.2", - "json-parse-better-errors": "1.0.2" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse5": { @@ -9976,6 +10309,22 @@ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", @@ -10042,7 +10391,7 @@ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "pbkdf2": { @@ -10051,11 +10400,11 @@ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", - "sha.js": "2.4.11" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "performance-now": { @@ -10082,7 +10431,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { @@ -10091,7 +10440,7 @@ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { - "find-up": "2.1.0" + "find-up": "^2.1.0" } }, "pluralize": { @@ -10117,9 +10466,9 @@ "integrity": "sha1-B+h5FKVSQtzaW4M9QvAY1odbWV8=", "dev": true, "requires": { - "async": "1.5.2", - "debug": "2.6.9", - "mkdirp": "0.5.1" + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" }, "dependencies": { "debug": { @@ -10145,9 +10494,9 @@ "integrity": "sha1-cOZEPjam1SCw/U51k/zKNjXun1U=", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.5.0" }, "dependencies": { "source-map": { @@ -10164,10 +10513,10 @@ "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", "dev": true, "requires": { - "css-unit-converter": "1.1.1", - "postcss": "7.0.5", - "postcss-selector-parser": "5.0.0-rc.4", - "postcss-value-parser": "3.3.1" + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" } }, "postcss-colormin": { @@ -10176,11 +10525,11 @@ "integrity": "sha512-1QJc2coIehnVFsz0otges8kQLsryi4lo19WD+U5xCWvXd0uw/Z+KKYnbiNDCnO9GP+PvErPHCG0jNvWTngk9Rw==", "dev": true, "requires": { - "browserslist": "4.3.4", - "color": "3.1.0", - "has": "1.0.3", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-convert-values": { @@ -10189,8 +10538,8 @@ "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", "dev": true, "requires": { - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-discard-comments": { @@ -10199,7 +10548,7 @@ "integrity": "sha512-Ay+rZu1Sz6g8IdzRjUgG2NafSNpp2MSMOQUb+9kkzzzP+kh07fP0yNbhtFejURnyVXSX3FYy2nVNW1QTnNjgBQ==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "postcss-discard-duplicates": { @@ -10208,7 +10557,7 @@ "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "postcss-discard-empty": { @@ -10217,7 +10566,7 @@ "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "postcss-discard-overridden": { @@ -10226,7 +10575,7 @@ "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "postcss-load-config": { @@ -10235,8 +10584,8 @@ "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", "dev": true, "requires": { - "cosmiconfig": "4.0.0", - "import-cwd": "2.1.0" + "cosmiconfig": "^4.0.0", + "import-cwd": "^2.0.0" }, "dependencies": { "cosmiconfig": { @@ -10245,10 +10594,10 @@ "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", "dev": true, "requires": { - "is-directory": "0.3.1", - "js-yaml": "3.12.0", - "parse-json": "4.0.0", - "require-from-string": "2.0.2" + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" } } } @@ -10259,10 +10608,10 @@ "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "postcss": "7.0.5", - "postcss-load-config": "2.0.0", - "schema-utils": "1.0.0" + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv-keywords": { @@ -10277,9 +10626,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -10291,9 +10640,9 @@ "dev": true, "requires": { "css-color-names": "0.0.4", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1", - "stylehacks": "4.0.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" } }, "postcss-merge-rules": { @@ -10302,12 +10651,12 @@ "integrity": "sha512-UiuXwCCJtQy9tAIxsnurfF0mrNHKc4NnNx6NxqmzNNjXpQwLSukUxELHTRF0Rg1pAmcoKLih8PwvZbiordchag==", "dev": true, "requires": { - "browserslist": "4.3.4", - "caniuse-api": "3.0.0", - "cssnano-util-same-parent": "4.0.1", - "postcss": "7.0.5", - "postcss-selector-parser": "3.1.1", - "vendors": "1.0.2" + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" }, "dependencies": { "postcss-selector-parser": { @@ -10316,9 +10665,9 @@ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", "dev": true, "requires": { - "dot-prop": "4.2.0", - "indexes-of": "1.0.1", - "uniq": "1.0.1" + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } } } @@ -10329,8 +10678,8 @@ "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", "dev": true, "requires": { - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-minify-gradients": { @@ -10339,10 +10688,10 @@ "integrity": "sha512-pySEW3E6Ly5mHm18rekbWiAjVi/Wj8KKt2vwSfVFAWdW6wOIekgqxKxLU7vJfb107o3FDNPkaYFCxGAJBFyogA==", "dev": true, "requires": { - "cssnano-util-get-arguments": "4.0.0", - "is-color-stop": "1.1.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-minify-params": { @@ -10351,12 +10700,12 @@ "integrity": "sha512-h4W0FEMEzBLxpxIVelRtMheskOKKp52ND6rJv+nBS33G1twu2tCyurYj/YtgU76+UDCvWeNs0hs8HFAWE2OUFg==", "dev": true, "requires": { - "alphanum-sort": "1.0.2", - "browserslist": "4.3.4", - "cssnano-util-get-arguments": "4.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1", - "uniqs": "2.0.0" + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" } }, "postcss-minify-selectors": { @@ -10365,10 +10714,10 @@ "integrity": "sha512-8+plQkomve3G+CodLCgbhAKrb5lekAnLYuL1d7Nz+/7RANpBEVdgBkPNwljfSKvZ9xkkZTZITd04KP+zeJTJqg==", "dev": true, "requires": { - "alphanum-sort": "1.0.2", - "has": "1.0.3", - "postcss": "7.0.5", - "postcss-selector-parser": "3.1.1" + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" }, "dependencies": { "postcss-selector-parser": { @@ -10377,9 +10726,9 @@ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", "dev": true, "requires": { - "dot-prop": "4.2.0", - "indexes-of": "1.0.1", - "uniq": "1.0.1" + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } } } @@ -10390,7 +10739,7 @@ "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", "dev": true, "requires": { - "postcss": "6.0.23" + "postcss": "^6.0.1" }, "dependencies": { "postcss": { @@ -10399,9 +10748,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -10418,8 +10767,8 @@ "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", "dev": true, "requires": { - "css-selector-tokenizer": "0.7.1", - "postcss": "6.0.23" + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" }, "dependencies": { "postcss": { @@ -10428,9 +10777,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -10447,8 +10796,8 @@ "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", "dev": true, "requires": { - "css-selector-tokenizer": "0.7.1", - "postcss": "6.0.23" + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" }, "dependencies": { "postcss": { @@ -10457,9 +10806,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -10476,8 +10825,8 @@ "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", "dev": true, "requires": { - "icss-replace-symbols": "1.1.0", - "postcss": "6.0.23" + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" }, "dependencies": { "postcss": { @@ -10486,9 +10835,9 @@ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, "source-map": { @@ -10505,7 +10854,7 @@ "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", "dev": true, "requires": { - "postcss": "7.0.5" + "postcss": "^7.0.0" } }, "postcss-normalize-display-values": { @@ -10514,9 +10863,9 @@ "integrity": "sha512-R5mC4vaDdvsrku96yXP7zak+O3Mm9Y8IslUobk7IMP+u/g+lXvcN4jngmHY5zeJnrQvE13dfAg5ViU05ZFDwdg==", "dev": true, "requires": { - "cssnano-util-get-match": "4.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-positions": { @@ -10525,10 +10874,10 @@ "integrity": "sha512-GNoOaLRBM0gvH+ZRb2vKCIujzz4aclli64MBwDuYGU2EY53LwiP7MxOZGE46UGtotrSnmarPPZ69l2S/uxdaWA==", "dev": true, "requires": { - "cssnano-util-get-arguments": "4.0.0", - "has": "1.0.3", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-repeat-style": { @@ -10537,10 +10886,10 @@ "integrity": "sha512-fFHPGIjBUyUiswY2rd9rsFcC0t3oRta4wxE1h3lpwfQZwFeFjXFSiDtdJ7APCmHQOnUZnqYBADNRPKPwFAONgA==", "dev": true, "requires": { - "cssnano-util-get-arguments": "4.0.0", - "cssnano-util-get-match": "4.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-string": { @@ -10549,9 +10898,9 @@ "integrity": "sha512-IJoexFTkAvAq5UZVxWXAGE0yLoNN/012v7TQh5nDo6imZJl2Fwgbhy3J2qnIoaDBrtUP0H7JrXlX1jjn2YcvCQ==", "dev": true, "requires": { - "has": "1.0.3", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-timing-functions": { @@ -10560,9 +10909,9 @@ "integrity": "sha512-1nOtk7ze36+63ONWD8RCaRDYsnzorrj+Q6fxkQV+mlY5+471Qx9kspqv0O/qQNMeApg8KNrRf496zHwJ3tBZ7w==", "dev": true, "requires": { - "cssnano-util-get-match": "4.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-unicode": { @@ -10571,9 +10920,9 @@ "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", "dev": true, "requires": { - "browserslist": "4.3.4", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-url": { @@ -10582,10 +10931,10 @@ "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", "dev": true, "requires": { - "is-absolute-url": "2.1.0", - "normalize-url": "3.3.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-whitespace": { @@ -10594,8 +10943,8 @@ "integrity": "sha512-U8MBODMB2L+nStzOk6VvWWjZgi5kQNShCyjRhMT3s+W9Jw93yIjOnrEkKYD3Ul7ChWbEcjDWmXq0qOL9MIAnAw==", "dev": true, "requires": { - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-ordered-values": { @@ -10604,9 +10953,9 @@ "integrity": "sha512-PeJiLgJWPzkVF8JuKSBcylaU+hDJ/TX3zqAMIjlghgn1JBi6QwQaDZoDIlqWRcCAI8SxKrt3FCPSRmOgKRB97Q==", "dev": true, "requires": { - "cssnano-util-get-arguments": "4.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-reduce-initial": { @@ -10615,10 +10964,10 @@ "integrity": "sha512-epUiC39NonKUKG+P3eAOKKZtm5OtAtQJL7Ye0CBN1f+UQTHzqotudp+hki7zxXm7tT0ZAKDMBj1uihpPjP25ug==", "dev": true, "requires": { - "browserslist": "4.3.4", - "caniuse-api": "3.0.0", - "has": "1.0.3", - "postcss": "7.0.5" + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" } }, "postcss-reduce-transforms": { @@ -10627,10 +10976,10 @@ "integrity": "sha512-sZVr3QlGs0pjh6JAIe6DzWvBaqYw05V1t3d9Tp+VnFRT5j+rsqoWsysh/iSD7YNsULjq9IAylCznIwVd5oU/zA==", "dev": true, "requires": { - "cssnano-util-get-match": "4.0.0", - "has": "1.0.3", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-selector-parser": { @@ -10639,9 +10988,9 @@ "integrity": "sha1-yl53I4vxUpZjeME+ka1tYRVo6oc=", "dev": true, "requires": { - "cssesc": "2.0.0", - "indexes-of": "1.0.1", - "uniq": "1.0.1" + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } }, "postcss-svgo": { @@ -10650,10 +10999,10 @@ "integrity": "sha512-YD5uIk5NDRySy0hcI+ZJHwqemv2WiqqzDgtvgMzO8EGSkK5aONyX8HMVFRFJSdO8wUWTuisUFn/d7yRRbBr5Qw==", "dev": true, "requires": { - "is-svg": "3.0.0", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1", - "svgo": "1.1.1" + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" } }, "postcss-unique-selectors": { @@ -10662,9 +11011,9 @@ "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", "dev": true, "requires": { - "alphanum-sort": "1.0.2", - "postcss": "7.0.5", - "uniqs": "2.0.0" + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" } }, "postcss-value-parser": { @@ -10697,7 +11046,7 @@ "integrity": "sha1-0j1B/hN1ZG3i0BBNNFSjAIgCz3s=", "dev": true, "requires": { - "fast-diff": "1.2.0" + "fast-diff": "^1.1.2" } }, "pretty": { @@ -10706,9 +11055,9 @@ "integrity": "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=", "dev": true, "requires": { - "condense-newlines": "0.2.1", - "extend-shallow": "2.0.1", - "js-beautify": "1.8.9" + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" }, "dependencies": { "extend-shallow": { @@ -10717,7 +11066,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10728,8 +11077,8 @@ "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", "dev": true, "requires": { - "renderkid": "2.0.2", - "utila": "0.4.0" + "renderkid": "^2.0.1", + "utila": "~0.4" } }, "pretty-format": { @@ -10738,8 +11087,8 @@ "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", "dev": true, "requires": { - "ansi-regex": "3.0.0", - "ansi-styles": "3.2.1" + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" } }, "private": { @@ -10778,8 +11127,8 @@ "integrity": "sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w==", "dev": true, "requires": { - "kleur": "2.0.2", - "sisteransi": "0.1.1" + "kleur": "^2.0.1", + "sisteransi": "^0.1.1" } }, "proto-list": { @@ -10794,7 +11143,7 @@ "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "dev": true, "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -10822,12 +11171,12 @@ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "parse-asn1": "5.1.1", - "randombytes": "2.0.6", - "safe-buffer": "5.1.2" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "pump": { @@ -10836,8 +11185,8 @@ "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "pumpify": { @@ -10846,9 +11195,9 @@ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { - "duplexify": "3.6.1", - "inherits": "2.0.3", - "pump": "2.0.1" + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" }, "dependencies": { "pump": { @@ -10857,8 +11206,8 @@ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } } @@ -10905,9 +11254,9 @@ "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", - "math-random": "1.0.1" + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" }, "dependencies": { "is-number": { @@ -10924,7 +11273,7 @@ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.1.0" } }, "randomfill": { @@ -10933,8 +11282,8 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.2" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, "range-parser": { @@ -10961,7 +11310,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } } } @@ -10972,9 +11321,9 @@ "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", "dev": true, "requires": { - "normalize-package-data": "2.4.0", - "parse-json": "4.0.0", - "pify": "3.0.0" + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" } }, "read-pkg-up": { @@ -10983,8 +11332,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" }, "dependencies": { "find-up": { @@ -10993,8 +11342,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "path-exists": { @@ -11003,7 +11352,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-type": { @@ -11012,9 +11361,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -11029,9 +11378,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } } } @@ -11042,13 +11391,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -11057,18 +11406,18 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "realpath-native": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.2.tgz", - "integrity": "sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g==", + "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" + "util.promisify": "^1.0.0" } }, "regenerate": { @@ -11083,7 +11432,7 @@ "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", "dev": true, "requires": { - "regenerate": "1.4.0" + "regenerate": "^1.4.0" } }, "regenerator-runtime": { @@ -11098,7 +11447,7 @@ "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", "dev": true, "requires": { - "private": "0.1.8" + "private": "^0.1.6" } }, "regex-cache": { @@ -11107,7 +11456,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" } }, "regex-not": { @@ -11116,8 +11465,8 @@ "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "regexpp": { @@ -11132,12 +11481,12 @@ "integrity": "sha1-o3RPoDgGz/4UbepEIaPnO9zEex0=", "dev": true, "requires": { - "regenerate": "1.4.0", - "regenerate-unicode-properties": "7.0.0", - "regjsgen": "0.4.0", - "regjsparser": "0.3.0", - "unicode-match-property-ecmascript": "1.0.4", - "unicode-match-property-value-ecmascript": "1.0.2" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" } }, "regjsgen": { @@ -11152,7 +11501,7 @@ "integrity": "sha1-PDJtp/z9afoNMyV1pByMDN9YjJY=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" }, "dependencies": { "jsesc": { @@ -11181,11 +11530,11 @@ "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==", "dev": true, "requires": { - "css-select": "1.2.0", - "dom-converter": "0.2.0", - "htmlparser2": "3.3.0", - "strip-ansi": "3.0.1", - "utila": "0.4.0" + "css-select": "^1.1.0", + "dom-converter": "~0.2", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" }, "dependencies": { "ansi-regex": { @@ -11200,10 +11549,10 @@ "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "dev": true, "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.2", + "boolbase": "~1.0.0", + "css-what": "2.1", "domutils": "1.5.1", - "nth-check": "1.0.2" + "nth-check": "~1.0.1" } }, "domutils": { @@ -11212,8 +11561,8 @@ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "dev": true, "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.2.1" + "dom-serializer": "0", + "domelementtype": "1" } }, "strip-ansi": { @@ -11222,7 +11571,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } } } @@ -11245,7 +11594,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "request": { @@ -11254,26 +11603,26 @@ "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.7", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.3", - "har-validator": "5.1.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.21", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" } }, "request-promise-core": { @@ -11282,7 +11631,7 @@ "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.13.1" } }, "request-promise-native": { @@ -11292,8 +11641,8 @@ "dev": true, "requires": { "request-promise-core": "1.1.1", - "stealthy-require": "1.1.1", - "tough-cookie": "2.4.3" + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" } }, "require-directory": { @@ -11320,8 +11669,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "requires-port": { @@ -11336,7 +11685,7 @@ "integrity": "sha1-gvHsGaQjrB+9CAsLqwa6NuhKeiY=", "dev": true, "requires": { - "path-parse": "1.0.6" + "path-parse": "^1.0.5" } }, "resolve-cwd": { @@ -11345,7 +11694,7 @@ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { - "resolve-from": "3.0.0" + "resolve-from": "^3.0.0" }, "dependencies": { "resolve-from": { @@ -11374,8 +11723,8 @@ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "ret": { @@ -11402,7 +11751,7 @@ "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { - "glob": "7.1.3" + "glob": "^7.0.5" } }, "ripemd160": { @@ -11411,8 +11760,8 @@ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "rsvp": { @@ -11427,7 +11776,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "2.1.0" + "is-promise": "^2.1.0" } }, "run-queue": { @@ -11436,7 +11785,7 @@ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", "dev": true, "requires": { - "aproba": "1.2.0" + "aproba": "^1.1.1" } }, "rx-lite": { @@ -11451,7 +11800,7 @@ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { - "rx-lite": "4.0.8" + "rx-lite": "*" } }, "rxjs": { @@ -11460,7 +11809,7 @@ "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "tslib": "1.9.3" + "tslib": "^1.9.0" } }, "safe-buffer": { @@ -11475,7 +11824,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -11490,15 +11839,15 @@ "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", "dev": true, "requires": { - "anymatch": "2.0.0", - "capture-exit": "1.2.0", - "exec-sh": "0.2.2", - "fb-watchman": "2.0.0", - "fsevents": "1.2.4", - "micromatch": "3.1.10", - "minimist": "1.2.0", - "walker": "1.0.7", - "watch": "0.18.0" + "anymatch": "^2.0.0", + "capture-exit": "^1.2.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.3", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" } }, "sax": { @@ -11513,8 +11862,8 @@ "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" }, "dependencies": { "ajv-keywords": { @@ -11553,18 +11902,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" }, "dependencies": { "debug": { @@ -11596,13 +11945,13 @@ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.4", "batch": "0.6.1", "debug": "2.6.9", - "escape-html": "1.0.3", - "http-errors": "1.6.3", - "mime-types": "2.1.21", - "parseurl": "1.3.2" + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" }, "dependencies": { "debug": { @@ -11622,9 +11971,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, @@ -11640,10 +11989,10 @@ "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -11652,7 +12001,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -11675,8 +12024,8 @@ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "shebang-command": { @@ -11685,7 +12034,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -11700,10 +12049,10 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, "requires": { - "array-filter": "0.0.1", - "array-map": "0.0.0", - "array-reduce": "0.0.0", - "jsonify": "0.0.0" + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" } }, "shellwords": { @@ -11730,7 +12079,7 @@ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", "dev": true, "requires": { - "is-arrayish": "0.3.2" + "is-arrayish": "^0.3.1" }, "dependencies": { "is-arrayish": { @@ -11764,7 +12113,7 @@ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0" + "is-fullwidth-code-point": "^2.0.0" } }, "snapdragon": { @@ -11773,14 +12122,14 @@ "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "debug": { @@ -11798,7 +12147,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -11807,7 +12156,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -11818,9 +12167,9 @@ "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -11829,7 +12178,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -11838,7 +12187,7 @@ "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -11847,7 +12196,7 @@ "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -11856,9 +12205,9 @@ "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -11869,7 +12218,7 @@ "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -11878,19 +12227,57 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", "dev": true, "requires": { - "faye-websocket": "0.10.0", - "uuid": "3.3.2" + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" } }, "sockjs-client": { @@ -11899,12 +12286,12 @@ "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", "dev": true, "requires": { - "debug": "3.2.6", - "eventsource": "1.0.7", - "faye-websocket": "0.11.1", - "inherits": "2.0.3", - "json3": "3.3.2", - "url-parse": "1.4.4" + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" }, "dependencies": { "debug": { @@ -11913,7 +12300,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "faye-websocket": { @@ -11922,7 +12309,7 @@ "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "ms": { @@ -11951,11 +12338,11 @@ "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-support": { @@ -11964,8 +12351,8 @@ "integrity": "sha1-QbyVOyU0Jn6i1gW8z6e/oxEc7V8=", "dev": true, "requires": { - "buffer-from": "1.1.1", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" }, "dependencies": { "source-map": { @@ -11988,8 +12375,8 @@ "integrity": "sha1-GbtAnpG0exrVQVkkP3MSqFjbPC4=", "dev": true, "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -12004,8 +12391,8 @@ "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", "dev": true, "requires": { - "spdx-exceptions": "2.2.0", - "spdx-license-ids": "3.0.2" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -12020,11 +12407,11 @@ "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", "dev": true, "requires": { - "debug": "4.1.1", - "handle-thing": "2.0.0", - "http-deceiver": "1.2.7", - "select-hose": "2.0.0", - "spdy-transport": "3.0.0" + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" }, "dependencies": { "debug": { @@ -12033,7 +12420,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -12050,12 +12437,12 @@ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "requires": { - "debug": "4.1.1", - "detect-node": "2.0.4", - "hpack.js": "2.1.6", - "obuf": "1.1.2", - "readable-stream": "3.1.1", - "wbuf": "1.7.3" + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" }, "dependencies": { "debug": { @@ -12064,7 +12451,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -12079,9 +12466,9 @@ "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", "dev": true, "requires": { - "inherits": "2.0.3", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } } } @@ -12092,7 +12479,7 @@ "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -12107,15 +12494,15 @@ "integrity": "sha1-yUbWvZsaOdDoY1dj9SQtbtbctik=", "dev": true, "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, "ssri": { @@ -12124,7 +12511,7 @@ "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "figgy-pudding": "3.5.1" + "figgy-pudding": "^3.5.1" } }, "stable": { @@ -12151,8 +12538,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -12161,7 +12548,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -12184,8 +12571,8 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.6" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" } }, "stream-each": { @@ -12194,8 +12581,8 @@ "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "stream-shift": "1.0.0" + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" } }, "stream-http": { @@ -12204,11 +12591,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" } }, "stream-shift": { @@ -12223,8 +12610,8 @@ "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", "dev": true, "requires": { - "astral-regex": "1.0.0", - "strip-ansi": "4.0.0" + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" } }, "string-width": { @@ -12233,8 +12620,8 @@ "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string.prototype.padend": { @@ -12243,9 +12630,9 @@ "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", "dev": true, "requires": { - "define-properties": "1.1.3", - "es-abstract": "1.12.0", - "function-bind": "1.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" } }, "string.prototype.padstart": { @@ -12254,9 +12641,9 @@ "integrity": "sha1-W8+tOfRkm7LQMSkuGbzwtRDUskI=", "dev": true, "requires": { - "define-properties": "1.1.3", - "es-abstract": "1.12.0", - "function-bind": "1.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" } }, "string_decoder": { @@ -12265,7 +12652,7 @@ "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -12274,7 +12661,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "strip-bom": { @@ -12283,7 +12670,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-eof": { @@ -12310,9 +12697,9 @@ "integrity": "sha512-TK5zEPeD9NyC1uPIdjikzsgWxdQQN/ry1X3d1iOz1UkYDCmcr928gWD1KHgyC27F50UnE0xCTrBOO1l6KR8M4w==", "dev": true, "requires": { - "browserslist": "4.3.4", - "postcss": "7.0.5", - "postcss-selector-parser": "3.1.1" + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" }, "dependencies": { "postcss-selector-parser": { @@ -12321,9 +12708,9 @@ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", "dev": true, "requires": { - "dot-prop": "4.2.0", - "indexes-of": "1.0.1", - "uniq": "1.0.1" + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } } } @@ -12334,7 +12721,7 @@ "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "svgo": { @@ -12343,20 +12730,20 @@ "integrity": "sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g==", "dev": true, "requires": { - "coa": "2.0.1", - "colors": "1.1.2", - "css-select": "2.0.2", - "css-select-base-adapter": "0.1.1", + "coa": "~2.0.1", + "colors": "~1.1.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "~0.1.0", "css-tree": "1.0.0-alpha.28", - "css-url-regex": "1.1.0", - "csso": "3.5.1", - "js-yaml": "3.12.0", - "mkdirp": "0.5.1", - "object.values": "1.0.4", - "sax": "1.2.4", - "stable": "0.1.8", - "unquote": "1.1.1", - "util.promisify": "1.0.0" + "css-url-regex": "^1.1.0", + "csso": "^3.5.0", + "js-yaml": "^3.12.0", + "mkdirp": "~0.5.1", + "object.values": "^1.0.4", + "sax": "~1.2.4", + "stable": "~0.1.6", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" } }, "symbol-tree": { @@ -12371,12 +12758,12 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.4.1", - "lodash": "4.17.11", + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" }, "dependencies": { "ajv": { @@ -12385,10 +12772,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "fast-deep-equal": { @@ -12417,9 +12804,9 @@ "integrity": "sha1-4GPadLGU3en68KVh86Q4xUnS2j8=", "dev": true, "requires": { - "commander": "2.17.1", - "source-map": "0.6.1", - "source-map-support": "0.5.9" + "commander": "~2.17.1", + "source-map": "~0.6.1", + "source-map-support": "~0.5.6" }, "dependencies": { "source-map": { @@ -12436,14 +12823,14 @@ "integrity": "sha1-z3wloe7iW/Eh9KWHu54ATj+A5Sg=", "dev": true, "requires": { - "cacache": "11.3.1", - "find-cache-dir": "2.0.0", - "schema-utils": "1.0.0", - "serialize-javascript": "1.5.0", - "source-map": "0.6.1", - "terser": "3.10.11", - "webpack-sources": "1.3.0", - "worker-farm": "1.6.0" + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.8.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" }, "dependencies": { "ajv-keywords": { @@ -12458,20 +12845,20 @@ "integrity": "sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA==", "dev": true, "requires": { - "bluebird": "3.5.3", - "chownr": "1.1.1", - "figgy-pudding": "3.5.1", - "glob": "7.1.3", - "graceful-fs": "4.1.15", - "lru-cache": "4.1.3", - "mississippi": "3.0.0", - "mkdirp": "0.5.1", - "move-concurrently": "1.0.1", - "promise-inflight": "1.0.1", - "rimraf": "2.6.2", - "ssri": "6.0.1", - "unique-filename": "1.1.1", - "y18n": "4.0.0" + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "figgy-pudding": "^3.1.0", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.3", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.0", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" } }, "find-cache-dir": { @@ -12480,9 +12867,9 @@ "integrity": "sha1-TB+u1Z9FGEUw+51/oSOk0EqYRy0=", "dev": true, "requires": { - "commondir": "1.0.1", - "make-dir": "1.3.0", - "pkg-dir": "3.0.0" + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" } }, "find-up": { @@ -12491,7 +12878,7 @@ "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, "locate-path": { @@ -12500,8 +12887,8 @@ "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "mississippi": { @@ -12510,16 +12897,16 @@ "integrity": "sha1-6goykfl+C16HdrNj1fChLZTGcCI=", "dev": true, "requires": { - "concat-stream": "1.6.2", - "duplexify": "3.6.1", - "end-of-stream": "1.4.1", - "flush-write-stream": "1.0.3", - "from2": "2.3.0", - "parallel-transform": "1.1.0", - "pump": "3.0.0", - "pumpify": "1.5.1", - "stream-each": "1.2.3", - "through2": "2.0.5" + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" } }, "p-limit": { @@ -12528,7 +12915,7 @@ "integrity": "sha1-5iTtVO6MRgp3izyfNnBJb/ileuw=", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -12537,7 +12924,7 @@ "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", "dev": true, "requires": { - "p-limit": "2.0.0" + "p-limit": "^2.0.0" } }, "p-try": { @@ -12552,7 +12939,7 @@ "integrity": "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM=", "dev": true, "requires": { - "find-up": "3.0.0" + "find-up": "^3.0.0" } }, "schema-utils": { @@ -12561,9 +12948,9 @@ "integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } }, "source-map": { @@ -12580,11 +12967,11 @@ "integrity": "sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA==", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "require-main-filename": "1.0.1" + "arrify": "^1.0.1", + "micromatch": "^2.3.11", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" }, "dependencies": { "arr-diff": { @@ -12593,7 +12980,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "array-unique": { @@ -12608,9 +12995,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "expand-brackets": { @@ -12619,7 +13006,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "extglob": { @@ -12628,7 +13015,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-extglob": { @@ -12643,7 +13030,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "kind-of": { @@ -12652,7 +13039,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "micromatch": { @@ -12661,19 +13048,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } } } @@ -12690,9 +13077,9 @@ "integrity": "sha512-acJ0rvUk53+ly9cqYWNOpPqOgCkNpmHLPDGduNm4hDQWF7EDKEJXAopG9iEWsPPcml09wePkq3NF+ZUqnO6tbg==", "dev": true, "requires": { - "async": "2.6.1", - "loader-runner": "2.3.1", - "loader-utils": "1.1.0" + "async": "^2.3.0", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0" }, "dependencies": { "async": { @@ -12701,7 +13088,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.10" } } } @@ -12724,8 +13111,8 @@ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { - "readable-stream": "2.3.6", - "xtend": "4.0.1" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, "thunky": { @@ -12740,7 +13127,7 @@ "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "dev": true, "requires": { - "setimmediate": "1.0.5" + "setimmediate": "^1.0.4" } }, "timsort": { @@ -12755,7 +13142,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "tmpl": { @@ -12764,6 +13151,11 @@ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "dev": true }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -12782,7 +13174,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -12791,7 +13183,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -12802,10 +13194,10 @@ "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -12814,8 +13206,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "toastr": { @@ -12823,7 +13215,7 @@ "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", "integrity": "sha1-i0O+ZPudDEFIcURvLbjoyk6V8YE=", "requires": { - "jquery": "3.3.1" + "jquery": ">=1.12.0" } }, "topo": { @@ -12832,7 +13224,7 @@ "integrity": "sha1-1aZ/suaTB+vusIQC7Coqb1962Vw=", "dev": true, "requires": { - "hoek": "6.0.3" + "hoek": "6.x.x" }, "dependencies": { "hoek": { @@ -12855,8 +13247,8 @@ "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", "dev": true, "requires": { - "psl": "1.1.29", - "punycode": "1.4.1" + "psl": "^1.1.24", + "punycode": "^1.4.1" }, "dependencies": { "punycode": { @@ -12873,7 +13265,7 @@ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "requires": { - "punycode": "2.1.1" + "punycode": "^2.1.0" } }, "trim-right": { @@ -12894,10 +13286,10 @@ "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", "dev": true, "requires": { - "@types/strip-bom": "3.0.0", + "@types/strip-bom": "^3.0.0", "@types/strip-json-comments": "0.0.30", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1" + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" }, "dependencies": { "strip-bom": { @@ -12926,7 +13318,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -12941,7 +13333,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-is": { @@ -12951,7 +13343,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "typedarray": { @@ -12966,8 +13358,8 @@ "integrity": "sha1-rwLxgMEgfXZDLkc+0koo9KeCuuM=", "dev": true, "requires": { - "commander": "2.17.1", - "source-map": "0.6.1" + "commander": "~2.17.1", + "source-map": "~0.6.1" }, "dependencies": { "source-map": { @@ -12984,14 +13376,14 @@ "integrity": "sha1-dfVIFghYFjoIZD4IbV/v4YpdZ94=", "dev": true, "requires": { - "cacache": "10.0.4", - "find-cache-dir": "1.0.0", - "schema-utils": "0.4.7", - "serialize-javascript": "1.5.0", - "source-map": "0.6.1", - "uglify-es": "3.3.9", - "webpack-sources": "1.3.0", - "worker-farm": "1.6.0" + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "schema-utils": "^0.4.5", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "uglify-es": "^3.3.4", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" }, "dependencies": { "commander": { @@ -13012,8 +13404,8 @@ "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", "dev": true, "requires": { - "commander": "2.13.0", - "source-map": "0.6.1" + "commander": "~2.13.0", + "source-map": "~0.6.1" } } } @@ -13030,8 +13422,8 @@ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", "dev": true, "requires": { - "unicode-canonical-property-names-ecmascript": "1.0.4", - "unicode-property-aliases-ecmascript": "1.0.4" + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" } }, "unicode-match-property-value-ecmascript": { @@ -13052,10 +13444,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -13064,7 +13456,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -13073,10 +13465,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -13099,7 +13491,7 @@ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { - "unique-slug": "2.0.1" + "unique-slug": "^2.0.0" } }, "unique-slug": { @@ -13108,7 +13500,7 @@ "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", "dev": true, "requires": { - "imurmurhash": "0.1.4" + "imurmurhash": "^0.1.4" } }, "universalify": { @@ -13135,8 +13527,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -13145,9 +13537,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -13184,10 +13576,10 @@ "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { - "punycode": "2.1.1" + "punycode": "^2.1.0" } }, "urix": { @@ -13220,9 +13612,9 @@ "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "mime": "2.3.1", - "schema-utils": "1.0.0" + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv-keywords": { @@ -13237,9 +13629,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -13250,8 +13642,8 @@ "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "dev": true, "requires": { - "querystringify": "2.1.0", - "requires-port": "1.0.0" + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" } }, "use": { @@ -13281,8 +13673,8 @@ "integrity": "sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA=", "dev": true, "requires": { - "define-properties": "1.1.3", - "object.getownpropertydescriptors": "2.0.3" + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" } }, "utila": { @@ -13303,14 +13695,19 @@ "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=", "dev": true }, + "v-lazy-image": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/v-lazy-image/-/v-lazy-image-1.3.2.tgz", + "integrity": "sha512-yZYMLoy95S4K9mWE/2DMZcwvaWnGiAHGXcKRruyrFvAdFm2fsnfyL0yj2UwXEGliNZO7I4mRy9/RB7J4CT0HAQ==" + }, "v-tooltip": { "version": "2.0.0-rc.33", "resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.0-rc.33.tgz", "integrity": "sha1-ePfY6cNCZWIr5lup3HjGfx3AK3M=", "requires": { - "lodash.merge": "4.6.1", - "popper.js": "1.14.5", - "vue-resize": "0.4.4" + "lodash.merge": "^4.6.0", + "popper.js": "^1.12.9", + "vue-resize": "^0.4.3" } }, "validate-npm-package-license": { @@ -13319,8 +13716,8 @@ "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=", "dev": true, "requires": { - "spdx-correct": "3.0.2", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "vary": { @@ -13341,9 +13738,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "vm-browserify": { @@ -13366,12 +13763,12 @@ "integrity": "sha1-wmjJbG2Uz+PZOKX3WTlZsMozYNE=", "dev": true, "requires": { - "debug": "3.1.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.4", - "esquery": "1.0.1", - "lodash": "4.17.11" + "debug": "^3.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.2", + "esquery": "^1.0.0", + "lodash": "^4.17.4" } }, "vue-hot-reload-api": { @@ -13381,21 +13778,21 @@ "dev": true }, "vue-jest": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.2.tgz", - "integrity": "sha512-5XIQ1xQFW0ZnWxHWM7adVA2IqbDsdw1vhgZfGFX4oWd75J38KIS3YT41PtiE7lpMLmNM6+VJ0uprT2mhHjUgkA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.3.tgz", + "integrity": "sha512-QwFQjkv2vXYPKUkNZkMbV/ZTHyQhRM1JY8nP68dRLQmdvCN+VUEKhlByH/PgPqDr2p/NuhaM3PUjJ9nreR++3w==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", - "chalk": "2.4.1", - "extract-from-css": "0.4.4", - "find-babel-config": "1.1.0", - "js-beautify": "1.8.9", - "node-cache": "4.2.0", - "object-assign": "4.1.1", - "source-map": "0.5.7", - "tsconfig": "7.0.0", - "vue-template-es2015-compiler": "1.6.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "chalk": "^2.1.0", + "extract-from-css": "^0.4.4", + "find-babel-config": "^1.1.0", + "js-beautify": "^1.6.14", + "node-cache": "^4.1.1", + "object-assign": "^4.1.1", + "source-map": "^0.5.6", + "tsconfig": "^7.0.0", + "vue-template-es2015-compiler": "^1.6.0" } }, "vue-loader": { @@ -13404,11 +13801,11 @@ "integrity": "sha512-nVV27GNIA9MeoD8yQ3dkUzwlAaAsWeYSWZHsu/K04KCD339lW0Jv2sJWsjj3721SP7sl2lYdPmjcHgkWQSp5bg==", "dev": true, "requires": { - "@vue/component-compiler-utils": "2.3.0", - "hash-sum": "1.0.2", - "loader-utils": "1.1.0", - "vue-hot-reload-api": "2.3.1", - "vue-style-loader": "4.1.2" + "@vue/component-compiler-utils": "^2.0.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" } }, "vue-loading-overlay": { @@ -13426,14 +13823,22 @@ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.2.tgz", "integrity": "sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg==" }, + "vue-socket.io": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/vue-socket.io/-/vue-socket.io-3.0.5.tgz", + "integrity": "sha512-+caWHVSphz0iEJOdHK8inAth7E4r97/9w3XD+vxMxCkfKtZNf/D07/ZmRrwFUSlCLJ1EDph/gYFoHy06KBUBCg==", + "requires": { + "socket.io-client": "^2.1.1" + } + }, "vue-style-loader": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", "dev": true, "requires": { - "hash-sum": "1.0.2", - "loader-utils": "1.1.0" + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" } }, "vue-template-compiler": { @@ -13442,8 +13847,8 @@ "integrity": "sha1-UqSgeMMn3rk3SCpQmuhcBvNGw8s=", "dev": true, "requires": { - "de-indent": "1.0.2", - "he": "1.2.0" + "de-indent": "^1.0.2", + "he": "^1.1.0" } }, "vue-template-es2015-compiler": { @@ -13469,7 +13874,7 @@ "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", "dev": true, "requires": { - "browser-process-hrtime": "0.1.3" + "browser-process-hrtime": "^0.1.2" } }, "walker": { @@ -13478,7 +13883,7 @@ "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", "dev": true, "requires": { - "makeerror": "1.0.11" + "makeerror": "1.0.x" } }, "watch": { @@ -13487,8 +13892,8 @@ "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", "dev": true, "requires": { - "exec-sh": "0.2.2", - "minimist": "1.2.0" + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" } }, "watchpack": { @@ -13497,9 +13902,9 @@ "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "dev": true, "requires": { - "chokidar": "2.0.4", - "graceful-fs": "4.1.15", - "neo-async": "2.6.0" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" } }, "wbuf": { @@ -13508,7 +13913,7 @@ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "requires": { - "minimalistic-assert": "1.0.1" + "minimalistic-assert": "^1.0.0" } }, "wcwidth": { @@ -13517,7 +13922,7 @@ "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, "requires": { - "defaults": "1.0.3" + "defaults": "^1.0.3" } }, "webidl-conversions": { @@ -13536,26 +13941,26 @@ "@webassemblyjs/helper-module-context": "1.7.11", "@webassemblyjs/wasm-edit": "1.7.11", "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "5.7.3", - "acorn-dynamic-import": "3.0.0", - "ajv": "6.5.5", - "ajv-keywords": "3.2.0", - "chrome-trace-event": "1.0.0", - "enhanced-resolve": "4.1.0", - "eslint-scope": "4.0.0", - "json-parse-better-errors": "1.0.2", - "loader-runner": "2.3.1", - "loader-utils": "1.1.0", - "memory-fs": "0.4.1", - "micromatch": "3.1.10", - "mkdirp": "0.5.1", - "neo-async": "2.6.0", - "node-libs-browser": "2.1.0", - "schema-utils": "0.4.7", - "tapable": "1.1.0", - "uglifyjs-webpack-plugin": "1.3.0", - "watchpack": "1.6.0", - "webpack-sources": "1.3.0" + "acorn": "^5.6.2", + "acorn-dynamic-import": "^3.0.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", + "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", + "schema-utils": "^0.4.4", + "tapable": "^1.1.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" }, "dependencies": { "ajv-keywords": { @@ -13570,8 +13975,8 @@ "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } } } @@ -13582,18 +13987,18 @@ "integrity": "sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==", "dev": true, "requires": { - "acorn": "5.7.3", - "bfj": "6.1.1", - "chalk": "2.4.1", - "commander": "2.19.0", - "ejs": "2.6.1", - "express": "4.16.4", - "filesize": "3.6.1", - "gzip-size": "5.0.0", - "lodash": "4.17.11", - "mkdirp": "0.5.1", - "opener": "1.5.1", - "ws": "6.1.0" + "acorn": "^5.7.3", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.10", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" }, "dependencies": { "commander": { @@ -13610,8 +14015,8 @@ "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", "dev": true, "requires": { - "deepmerge": "1.5.2", - "javascript-stringify": "1.6.0" + "deepmerge": "^1.5.2", + "javascript-stringify": "^1.6.0" } }, "webpack-dev-middleware": { @@ -13620,10 +14025,10 @@ "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", "dev": true, "requires": { - "memory-fs": "0.4.1", - "mime": "2.3.1", - "range-parser": "1.2.0", - "webpack-log": "2.0.0" + "memory-fs": "~0.4.1", + "mime": "^2.3.1", + "range-parser": "^1.0.3", + "webpack-log": "^2.0.0" } }, "webpack-dev-server": { @@ -13633,34 +14038,34 @@ "dev": true, "requires": { "ansi-html": "0.0.7", - "bonjour": "3.5.0", - "chokidar": "2.0.4", - "compression": "1.7.3", - "connect-history-api-fallback": "1.6.0", - "debug": "3.1.0", - "del": "3.0.0", - "express": "4.16.4", - "html-entities": "1.2.1", - "http-proxy-middleware": "0.18.0", - "import-local": "2.0.0", - "internal-ip": "3.0.1", - "ip": "1.1.5", - "killable": "1.0.1", - "loglevel": "1.6.1", - "opn": "5.4.0", - "portfinder": "1.0.19", - "schema-utils": "1.0.0", - "selfsigned": "1.10.4", - "semver": "5.6.0", - "serve-index": "1.9.1", + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "~0.18.0", + "import-local": "^2.0.0", + "internal-ip": "^3.0.1", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "schema-utils": "^1.0.0", + "selfsigned": "^1.9.1", + "semver": "^5.6.0", + "serve-index": "^1.7.2", "sockjs": "0.3.19", "sockjs-client": "1.3.0", - "spdy": "4.0.0", - "strip-ansi": "3.0.1", - "supports-color": "5.5.0", - "url": "0.11.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^5.1.0", + "url": "^0.11.0", "webpack-dev-middleware": "3.4.0", - "webpack-log": "2.0.0", + "webpack-log": "^2.0.0", "yargs": "12.0.2" }, "dependencies": { @@ -13682,9 +14087,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.5.5", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } }, "strip-ansi": { @@ -13693,7 +14098,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } } } @@ -13704,8 +14109,8 @@ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", "dev": true, "requires": { - "ansi-colors": "3.2.3", - "uuid": "3.3.2" + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" } }, "webpack-merge": { @@ -13714,7 +14119,7 @@ "integrity": "sha1-D9446r8tX9hSUcJKWoxI+KP063s=", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.5" } }, "webpack-sources": { @@ -13723,8 +14128,8 @@ "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", "dev": true, "requires": { - "source-list-map": "2.0.1", - "source-map": "0.6.1" + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" }, "dependencies": { "source-map": { @@ -13741,8 +14146,8 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.5.0", - "websocket-extensions": "0.1.3" + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { @@ -13772,9 +14177,9 @@ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", "dev": true, "requires": { - "lodash.sortby": "4.7.0", - "tr46": "1.0.1", - "webidl-conversions": "4.0.2" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, "which": { @@ -13783,7 +14188,7 @@ "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { @@ -13804,7 +14209,7 @@ "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", "dev": true, "requires": { - "errno": "0.1.7" + "errno": "~0.1.7" } }, "wrap-ansi": { @@ -13813,8 +14218,8 @@ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { @@ -13829,7 +14234,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -13838,9 +14243,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "strip-ansi": { @@ -13849,7 +14254,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } } } @@ -13866,27 +14271,26 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "ws": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz", "integrity": "sha1-EZqdv5LFThkOwY0Q6HHVXJXPk3M=", - "dev": true, "requires": { - "async-limiter": "1.0.0" + "async-limiter": "~1.0.0" } }, "xml-name-validator": { @@ -13895,6 +14299,11 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xregexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", @@ -13925,18 +14334,18 @@ "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "2.0.0", - "find-up": "3.0.0", - "get-caller-file": "1.0.3", - "os-locale": "3.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "4.0.0", - "yargs-parser": "10.1.0" + "cliui": "^4.0.0", + "decamelize": "^2.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^10.1.0" }, "dependencies": { "find-up": { @@ -13945,7 +14354,7 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, "locate-path": { @@ -13954,8 +14363,8 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "p-limit": { @@ -13964,7 +14373,7 @@ "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -13973,7 +14382,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { @@ -13990,19 +14399,24 @@ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yorkie": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==", "dev": true, "requires": { - "execa": "0.8.0", - "is-ci": "1.2.1", - "normalize-path": "1.0.0", - "strip-indent": "2.0.0" + "execa": "^0.8.0", + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" }, "dependencies": { "cross-spawn": { @@ -14011,9 +14425,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "execa": { @@ -14022,13 +14436,13 @@ "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.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": { diff --git a/client/package.json b/client/package.json index d2f4440b..32f7df34 100755 --- a/client/package.json +++ b/client/package.json @@ -11,27 +11,30 @@ "dependencies": { "axios": "^0.18.0", "bootstrap": "^4.1.3", + "intersection-observer": "^0.5.1", "jquery": "^3.3.1", "paper": "^0.11.8", "popper.js": "^1.14.5", "simplify-js": "^1.2.3", "toastr": "^2.1.4", + "v-lazy-image": "^1.3.2", "v-tooltip": "^2.0.0-rc.33", "vue": "^2.5.17", "vue-loading-overlay": "^3.1.1", "vue-router": "^3.0.2", + "vue-socket.io": "^3.0.5", "vuex": "^3.0.1" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.1.1", "@vue/cli-plugin-eslint": "^3.1.1", - "@vue/cli-plugin-unit-jest": "^3.3.0", + "@vue/cli-plugin-unit-jest": "^3.4.0", "@vue/cli-service": "^3.1.1", "@vue/eslint-config-prettier": "^4.0.0", "@vue/test-utils": "^1.0.0-beta.20", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.0.1", - "babel-jest": "^23.6.0", + "babel-jest": "^24.1.0", "eslint": "^5.8.0", "eslint-plugin-vue": "^5.0.0-0", "vue-template-compiler": "^2.5.17", diff --git a/client/src/App.vue b/client/src/App.vue index 5673c4b1..24402735 100755 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,6 +1,6 @@ @@ -14,7 +14,7 @@ export default { components: { NavBar }, methods: { ...mapMutations("user", ["setUserInfo"]), - ...mapMutations("info", ["getServerInfo"]), + ...mapMutations("info", ["getServerInfo", "socket"]), toAuthPage() { this.$router.push({ name: "authentication" @@ -43,6 +43,9 @@ export default { }, loading() { return this.$store.state.info.loading; + }, + socketConnection() { + return this.$store.state.info.socket; } }, watch: { @@ -51,6 +54,22 @@ export default { this.loader.hide(); } }, + socketConnection() { + if (this.socketConnection) return; + + setTimeout(() => { + if (this.socketConnection) return; + let options = { + positionClass: "toast-bottom-left" + }; + + this.$toastr.warning( + "Connection lost to the backend", + "Connection Lost", + options + ); + }, 1000); + }, loginRequired: { handler(newValue) { if (newValue) { @@ -66,6 +85,14 @@ export default { immediate: true } }, + sockets: { + connect() { + this.socket(true); + }, + disconnect() { + this.socket(false); + } + }, mounted() { if (this.$route.name.toLowerCase() !== "annotate") { this.loader = this.$loading.show({ diff --git a/client/src/assets/loader.gif b/client/src/assets/loader.gif new file mode 100644 index 00000000..33fac914 Binary files /dev/null and b/client/src/assets/loader.gif differ diff --git a/client/src/components/Metadata.vue b/client/src/components/Metadata.vue index 73aaa7b2..eab9ec1c 100755 --- a/client/src/components/Metadata.vue +++ b/client/src/components/Metadata.vue @@ -1,6 +1,10 @@ diff --git a/client/src/components/PanelText.vue b/client/src/components/PanelText.vue new file mode 100755 index 00000000..8b8a25d3 --- /dev/null +++ b/client/src/components/PanelText.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/client/src/components/annotator/panels/PanelToggle.vue b/client/src/components/PanelToggle.vue similarity index 79% rename from client/src/components/annotator/panels/PanelToggle.vue rename to client/src/components/PanelToggle.vue index ccea7721..3ad48c91 100755 --- a/client/src/components/annotator/panels/PanelToggle.vue +++ b/client/src/components/PanelToggle.vue @@ -1,5 +1,9 @@ diff --git a/client/src/components/Status.vue b/client/src/components/Status.vue index 5ed4f4e6..d9fe847c 100755 --- a/client/src/components/Status.vue +++ b/client/src/components/Status.vue @@ -1,7 +1,16 @@