From 4f62a6a2a5839d865440953a002e723a614977be Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 26 Feb 2019 16:57:20 +0100 Subject: [PATCH 01/25] DataSource interface, ImageLoader class and test --- lib/provider/opencv/data-source.interface.ts | 12 ++++++++ .../opencv/image-loader.class.spec.ts | 29 +++++++++++++++++++ lib/provider/opencv/image-loader.class.ts | 16 ++++++++++ 3 files changed, 57 insertions(+) create mode 100644 lib/provider/opencv/data-source.interface.ts create mode 100644 lib/provider/opencv/image-loader.class.spec.ts create mode 100644 lib/provider/opencv/image-loader.class.ts diff --git a/lib/provider/opencv/data-source.interface.ts b/lib/provider/opencv/data-source.interface.ts new file mode 100644 index 00000000..f59d06b7 --- /dev/null +++ b/lib/provider/opencv/data-source.interface.ts @@ -0,0 +1,12 @@ +/** + * A DataSource should provide methods to load data + * + * @interface DataSource + */ +export interface DataSource { + /** + * load will load image data from disk + * @param path Absolute path to output file + */ + load(path: string): Promise; +} diff --git a/lib/provider/opencv/image-loader.class.spec.ts b/lib/provider/opencv/image-loader.class.spec.ts new file mode 100644 index 00000000..a040ec2e --- /dev/null +++ b/lib/provider/opencv/image-loader.class.spec.ts @@ -0,0 +1,29 @@ +import * as path from "path"; +import { ImageLoader } from "./image-loader.class"; + +describe("Image loader", () => { + it("should resolve to a non-empty Mat on successful load", async () => { + // GIVEN + const SUT = new ImageLoader(); + const imagePath = path.resolve(__dirname, "./__mocks__/mouse.png"); + + // WHEN + const result = await SUT.load(imagePath); + + // THEN + expect(result.height).toBeGreaterThan(0); + expect(result.width).toBeGreaterThan(0); + }); + + it("loadImage should reject on unsuccessful load", async () => { + // GIVEN + const SUT = new ImageLoader(); + const imagePath = "./__mocks__/foo.png"; + + // WHEN + const call = SUT.load; + + // THEN + await expect(call(imagePath)).rejects.toEqual(`Failed to load image from '${imagePath}'`); + }); +}); diff --git a/lib/provider/opencv/image-loader.class.ts b/lib/provider/opencv/image-loader.class.ts new file mode 100644 index 00000000..5403f4c4 --- /dev/null +++ b/lib/provider/opencv/image-loader.class.ts @@ -0,0 +1,16 @@ +import * as cv from "opencv4nodejs"; +import { Image } from "../../image.class"; +import { DataSource } from "./data-source.interface"; + +export class ImageLoader implements DataSource { + public async load(path: string): Promise { + return new Promise(async (resolve, reject) => { + try { + const image = await cv.imreadAsync(path); + resolve(new Image(image.cols, image.rows, image.getData(), image.channels)); + } catch (e) { + reject(`Failed to load image from '${path}'`); + } + }); + } +} From 404fb7b6694b63b9db3bf69d1cdfaaccdb5d1f02 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 18:35:25 +0100 Subject: [PATCH 02/25] Renamed ImageLoader to ImageReader --- ...mage-loader.class.spec.ts => image-reader.class.spec.ts} | 6 +++--- .../opencv/{image-loader.class.ts => image-reader.class.ts} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename lib/provider/opencv/{image-loader.class.spec.ts => image-reader.class.spec.ts} (84%) rename lib/provider/opencv/{image-loader.class.ts => image-reader.class.ts} (90%) diff --git a/lib/provider/opencv/image-loader.class.spec.ts b/lib/provider/opencv/image-reader.class.spec.ts similarity index 84% rename from lib/provider/opencv/image-loader.class.spec.ts rename to lib/provider/opencv/image-reader.class.spec.ts index a040ec2e..f51d93bb 100644 --- a/lib/provider/opencv/image-loader.class.spec.ts +++ b/lib/provider/opencv/image-reader.class.spec.ts @@ -1,10 +1,10 @@ import * as path from "path"; -import { ImageLoader } from "./image-loader.class"; +import { ImageReader } from "./image-reader.class"; describe("Image loader", () => { it("should resolve to a non-empty Mat on successful load", async () => { // GIVEN - const SUT = new ImageLoader(); + const SUT = new ImageReader(); const imagePath = path.resolve(__dirname, "./__mocks__/mouse.png"); // WHEN @@ -17,7 +17,7 @@ describe("Image loader", () => { it("loadImage should reject on unsuccessful load", async () => { // GIVEN - const SUT = new ImageLoader(); + const SUT = new ImageReader(); const imagePath = "./__mocks__/foo.png"; // WHEN diff --git a/lib/provider/opencv/image-loader.class.ts b/lib/provider/opencv/image-reader.class.ts similarity index 90% rename from lib/provider/opencv/image-loader.class.ts rename to lib/provider/opencv/image-reader.class.ts index 5403f4c4..ff6d7e3c 100644 --- a/lib/provider/opencv/image-loader.class.ts +++ b/lib/provider/opencv/image-reader.class.ts @@ -2,7 +2,7 @@ import * as cv from "opencv4nodejs"; import { Image } from "../../image.class"; import { DataSource } from "./data-source.interface"; -export class ImageLoader implements DataSource { +export class ImageReader implements DataSource { public async load(path: string): Promise { return new Promise(async (resolve, reject) => { try { From a0d04084da30625ec79e15c5c0c1aa7cd1fcbea3 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 19:23:34 +0100 Subject: [PATCH 03/25] Added test image with alpha channel --- lib/provider/opencv/__mocks__/alpha_channel.png | Bin 0 -> 12800 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/provider/opencv/__mocks__/alpha_channel.png diff --git a/lib/provider/opencv/__mocks__/alpha_channel.png b/lib/provider/opencv/__mocks__/alpha_channel.png new file mode 100644 index 0000000000000000000000000000000000000000..5214843c8af02445724355db1e813d7e9cf3884a GIT binary patch literal 12800 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 WQb7E=Ch(shH)JFf#VbXP0{#y*7mY#y literal 0 HcmV?d00001 From d37a149eb525622ee07d0ce44143aadd3a7ec118 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 19:24:39 +0100 Subject: [PATCH 04/25] Set imread to unchanged mode --- lib/provider/opencv/image-reader.class.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/provider/opencv/image-reader.class.ts b/lib/provider/opencv/image-reader.class.ts index ff6d7e3c..702b4899 100644 --- a/lib/provider/opencv/image-reader.class.ts +++ b/lib/provider/opencv/image-reader.class.ts @@ -6,7 +6,7 @@ export class ImageReader implements DataSource { public async load(path: string): Promise { return new Promise(async (resolve, reject) => { try { - const image = await cv.imreadAsync(path); + const image = await cv.imreadAsync(path, cv.IMREAD_UNCHANGED); resolve(new Image(image.cols, image.rows, image.getData(), image.channels)); } catch (e) { reject(`Failed to load image from '${path}'`); From e1287cadef9320a4ca6bc4bea05f054b87118cd5 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 19:25:28 +0100 Subject: [PATCH 05/25] Created data-sink interface + image-writer implementation --- lib/provider/opencv/data-sink.interface.ts | 13 ++++++++ .../opencv/image-writer.class.spec.ts | 32 +++++++++++++++++++ lib/provider/opencv/image-writer.class.ts | 16 ++++++++++ 3 files changed, 61 insertions(+) create mode 100644 lib/provider/opencv/data-sink.interface.ts create mode 100644 lib/provider/opencv/image-writer.class.spec.ts create mode 100644 lib/provider/opencv/image-writer.class.ts diff --git a/lib/provider/opencv/data-sink.interface.ts b/lib/provider/opencv/data-sink.interface.ts new file mode 100644 index 00000000..79f15b1c --- /dev/null +++ b/lib/provider/opencv/data-sink.interface.ts @@ -0,0 +1,13 @@ +/** + * A DataSink should provide methods to store data + * + * @interface DataSink + */ +export interface DataSink { + /** + * store will write data to disk + * @param data Data to write + * @param path Absolute output file path + */ + store(data: any, path: string): Promise; +} diff --git a/lib/provider/opencv/image-writer.class.spec.ts b/lib/provider/opencv/image-writer.class.spec.ts new file mode 100644 index 00000000..d672ed9a --- /dev/null +++ b/lib/provider/opencv/image-writer.class.spec.ts @@ -0,0 +1,32 @@ +import { existsSync, unlinkSync } from "fs"; +import { resolve } from "path"; +import { ImageReader } from "./image-reader.class"; +import { ImageWriter } from "./image-writer.class"; + +const INPUT_PATH = resolve(__dirname, "./__mocks__/mouse.png"); +const OUTPUT_PATH_PNG = resolve(__dirname, "./__mocks__/output.png"); +const OUTPUT_PATH_JPG = resolve(__dirname, "./__mocks__/output.jpg"); + +beforeEach(() => { + for (const file of [OUTPUT_PATH_JPG, OUTPUT_PATH_PNG]) { + if (existsSync(file)) { + unlinkSync(file); + } + } +}); + +describe.each([[OUTPUT_PATH_PNG], [OUTPUT_PATH_JPG]])( + "Image writer", (outputPath) => { + test("should allow to store image data to disk", async () => { + // GIVEN + const imageReader = new ImageReader(); + const image = await imageReader.load(INPUT_PATH); + const imageWriter = new ImageWriter(); + + // WHEN + await imageWriter.store(image, outputPath); + + // THEN + expect(existsSync(outputPath)).toBeTruthy(); + }); + }); diff --git a/lib/provider/opencv/image-writer.class.ts b/lib/provider/opencv/image-writer.class.ts new file mode 100644 index 00000000..8048254a --- /dev/null +++ b/lib/provider/opencv/image-writer.class.ts @@ -0,0 +1,16 @@ +import * as cv from "opencv4nodejs"; +import { Image } from "../../image.class"; +import { DataSink } from "./data-sink.interface"; +import { ImageProcessor } from "./image-processor.class"; + +export class ImageWriter implements DataSink { + public async store(data: Image, path: string): Promise { + let outputMat: cv.Mat; + if (data.hasAlphaChannel) { + outputMat = await ImageProcessor.fromImageWithAlphaChannel(data); + } else { + outputMat = await ImageProcessor.fromImageWithoutAlphaChannel(data); + } + return cv.imwriteAsync(path, outputMat); + } +} From 4a5a6f670313d089cccb4ac25106841c30e2ec73 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 19:25:50 +0100 Subject: [PATCH 06/25] Created image-processor --- .../opencv/image-processor.class.spec.ts | 39 +++++++++++++++ lib/provider/opencv/image-processor.class.ts | 47 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 lib/provider/opencv/image-processor.class.spec.ts create mode 100644 lib/provider/opencv/image-processor.class.ts diff --git a/lib/provider/opencv/image-processor.class.spec.ts b/lib/provider/opencv/image-processor.class.spec.ts new file mode 100644 index 00000000..1e331cf3 --- /dev/null +++ b/lib/provider/opencv/image-processor.class.spec.ts @@ -0,0 +1,39 @@ +import { resolve } from "path"; +import { ImageProcessor } from "./image-processor.class"; +import { ImageReader } from "./image-reader.class"; + +describe("ImageProcessor", () => { + it("should allow to create a cv.Mat from an Image with alpha channel, alpha channel is dropped", async () => { + // GIVEN + const imageReader = new ImageReader(); + const imagePath = resolve(__dirname, "./__mocks__/alpha_channel.png"); + const image = await imageReader.load(imagePath); + + // WHEN + const mat = await ImageProcessor.fromImageWithAlphaChannel(image); + + // THEN + expect(image.hasAlphaChannel).toBeTruthy(); + expect(mat.channels).toEqual(3); + expect(mat.rows).toEqual(image.height); + expect(mat.cols).toEqual(image.width); + expect(mat.empty).toBeFalsy(); + }); + + it("should allow to create a cv.Mat from an Image without alpha channel", async () => { + // GIVEN + const imageReader = new ImageReader(); + const imagePath = resolve(__dirname, "./__mocks__/mouse.png"); + const image = await imageReader.load(imagePath); + + // WHEN + const mat = await ImageProcessor.fromImageWithoutAlphaChannel(image); + + // THEN + expect(image.hasAlphaChannel).toBeFalsy(); + expect(mat.channels).toEqual(3); + expect(mat.rows).toEqual(image.height); + expect(mat.cols).toEqual(image.width); + expect(mat.empty).toBeFalsy(); + }); +}); diff --git a/lib/provider/opencv/image-processor.class.ts b/lib/provider/opencv/image-processor.class.ts new file mode 100644 index 00000000..bdce2969 --- /dev/null +++ b/lib/provider/opencv/image-processor.class.ts @@ -0,0 +1,47 @@ +import * as cv from "opencv4nodejs"; +import { Image } from "../../image.class"; +import { Region } from "../../region.class"; + +export class ImageProcessor { + /** + * fromImageWithAlphaChannel should provide a way to create a library specific + * image with alpha channel from an abstract Image object holding raw data and image dimension + * + * @param {Image} img The input Image + * @param {Region} [roi] An optional Region to specify a ROI + * @returns {Promise} An image + * @memberof VisionProviderInterface + */ + public static async fromImageWithAlphaChannel( + img: Image, + roi?: Region, + ): Promise { + const mat = await new cv.Mat(img.data, img.height, img.width, cv.CV_8UC4).cvtColorAsync(cv.COLOR_BGRA2BGR); + if (roi) { + return mat.getRegion(new cv.Rect(roi.left, roi.top, roi.width, roi.height)); + } else { + return mat; + } + } + + /** + * fromImageWithoutAlphaChannel should provide a way to create a library specific + * image without alpha channel from an abstract Image object holding raw data and image dimension + * + * @param {Image} img The input Image + * @param {Region} [roi] An optional Region to specify a ROI + * @returns {Promise} An image + * @memberof VisionProviderInterface + */ + public static async fromImageWithoutAlphaChannel( + img: Image, + roi?: Region, + ): Promise { + const mat = new cv.Mat(img.data, img.height, img.width, cv.CV_8UC3); + if (roi) { + return mat.getRegion(new cv.Rect(roi.left, roi.top, roi.width, roi.height)); + } else { + return mat; + } + } +} From 988a245f4319c463429fee2a4a85510e4845ffa4 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 28 Feb 2019 19:27:20 +0100 Subject: [PATCH 07/25] Updated finder interface and implementation according to restructured code --- lib/provider/opencv/finder.interface.ts | 42 ---------- .../template-matching-finder.class.spec.ts | 52 +++++-------- .../opencv/template-matching-finder.class.ts | 76 +++++++------------ 3 files changed, 45 insertions(+), 125 deletions(-) diff --git a/lib/provider/opencv/finder.interface.ts b/lib/provider/opencv/finder.interface.ts index d095de9a..83da0d00 100644 --- a/lib/provider/opencv/finder.interface.ts +++ b/lib/provider/opencv/finder.interface.ts @@ -1,7 +1,5 @@ -import { Image } from "../../image.class"; import { MatchRequest } from "../../match-request.class"; import { MatchResult } from "../../match-result.class"; -import { Region } from "../../region.class"; /** * A Finder should provide an abstraction layer to perform @@ -10,15 +8,6 @@ import { Region } from "../../region.class"; * @interface FinderInterface */ export interface FinderInterface { - /** - * loadImage should allow to load an image from filesystem - * - * @param {string} path The filesystem path to the image - * @returns {*} An image - * @memberof VisionProviderInterface - */ - loadImage(path: string): any; - /** * findMatch should provide an abstraction to search for an image needle * in another image haystack @@ -38,35 +27,4 @@ export interface FinderInterface { * @memberof FinderInterface */ findMatches(matchRequest: MatchRequest): Promise; - - /** - * fromImageWithAlphaChannel should provide a way to create a library specific - * image with alpha channel from an abstract Image object holding raw data and image dimension - * - * @param {Image} img The input Image - * @param {Region} [roi] An optional Region to specify a ROI - * @returns {Promise} An image - * @memberof VisionProviderInterface - */ - fromImageWithAlphaChannel(img: Image, roi?: Region): Promise; - - /** - * fromImageWithoutAlphaChannel should provide a way to create a library specific - * image without alpha channel from an abstract Image object holding raw data and image dimension - * - * @param {Image} img The input Image - * @param {Region} [roi] An optional Region to specify a ROI - * @returns {Promise} An image - * @memberof VisionProviderInterface - */ - fromImageWithoutAlphaChannel(img: Image, roi?: Region): Promise; - - /** - * rgbToGrayScale should provide a way to convert an image from RGB to grayscale - * - * @param {*} img Input image, RGB - * @returns {Promise} Output image, grayscale - * @memberof VisionProviderInterface - */ - rgbToGrayScale(img: any): Promise; } diff --git a/lib/provider/opencv/template-matching-finder.class.spec.ts b/lib/provider/opencv/template-matching-finder.class.spec.ts index e72a0429..470e8334 100644 --- a/lib/provider/opencv/template-matching-finder.class.spec.ts +++ b/lib/provider/opencv/template-matching-finder.class.spec.ts @@ -2,43 +2,19 @@ import * as path from "path"; import { Image } from "../../image.class"; import { MatchRequest } from "../../match-request.class"; import { Region } from "../../region.class"; +import { ImageReader } from "./image-reader.class"; import { TemplateMatchingFinder } from "./template-matching-finder.class"; describe("Template-matching finder", () => { - it("loadImage should resolve to a non-empty Mat on successful load", async () => { - // GIVEN - const SUT = new TemplateMatchingFinder(); - const imagePath = path.resolve(__dirname, "./__mocks__/mouse.png"); - - // WHEN - const result = await SUT.loadImage(imagePath); - - // THEN - expect(result.rows).toBeGreaterThan(0); - expect(result.cols).toBeGreaterThan(0); - expect(result.empty).toBeFalsy(); - }); - - it("loadImage should reject on unsuccessful load", async () => { - // GIVEN - const SUT = new TemplateMatchingFinder(); - const imagePath = "./__mocks__/foo.png"; - - // WHEN - const call = SUT.loadImage; - - // THEN - await expect(call(imagePath)).rejects.toEqual("empty Mat"); - }); - it("findMatch should return a match when present in image", async () => { // GIVEN + const imageLoader = new ImageReader(); const SUT = new TemplateMatchingFinder(); const imagePath = path.resolve(__dirname, "./__mocks__/mouse.png"); - const needle = await SUT.loadImage(imagePath); + const needle = await imageLoader.load(imagePath); const minConfidence = 0.99; - const searchRegion = new Region(0, 0, needle.cols, needle.rows); - const haystack = new Image(needle.cols, needle.rows, needle.getData(), 3); + const searchRegion = new Region(0, 0, needle.width, needle.height); + const haystack = new Image(needle.width, needle.height, needle.data, 3); const matchRequest = new MatchRequest(haystack, imagePath, searchRegion, minConfidence); // WHEN @@ -51,12 +27,13 @@ describe("Template-matching finder", () => { it("findMatch should return a match within a search region when present in image", async () => { // GIVEN + const imageLoader = new ImageReader(); const SUT = new TemplateMatchingFinder(); const imagePath = path.resolve(__dirname, "./__mocks__/mouse.png"); - const needle = await SUT.loadImage(imagePath); + const needle = await imageLoader.load(imagePath); const minConfidence = 0.99; const searchRegion = new Region(10, 20, 100, 100); - const haystack = new Image(needle.cols, needle.rows, needle.getData(), 3); + const haystack = new Image(needle.width, needle.height, needle.data, 3); const matchRequest = new MatchRequest(haystack, imagePath, searchRegion, minConfidence); // WHEN @@ -69,13 +46,20 @@ describe("Template-matching finder", () => { it("findMatch should throw on invalid image paths", async () => { // GIVEN + const imageLoader = new ImageReader(); const SUT = new TemplateMatchingFinder(); - const imagePath = path.resolve(__dirname, "./__mocks__/foo.png"); + const pathToNeedle = path.resolve(__dirname, "./__mocks__/mouse.png"); + const pathToHaystack = "./__mocks__/foo.png"; + const needle = await imageLoader.load(pathToNeedle); + const minConfidence = 0.99; + const searchRegion = new Region(0, 0, 100, 100); + const haystack = new Image(needle.width, needle.height, needle.data, 3); + const matchRequest = new MatchRequest(haystack, pathToHaystack, searchRegion, minConfidence); // WHEN - const call = await SUT.loadImage; + const result = SUT.findMatch(matchRequest); // THEN - await expect(call(imagePath)).rejects.toEqual("empty Mat"); + expect(result).rejects.toEqual(`Failed to load image from '${pathToHaystack}'`); }); }); diff --git a/lib/provider/opencv/template-matching-finder.class.ts b/lib/provider/opencv/template-matching-finder.class.ts index 0ad11599..01bb46d4 100644 --- a/lib/provider/opencv/template-matching-finder.class.ts +++ b/lib/provider/opencv/template-matching-finder.class.ts @@ -4,7 +4,10 @@ import { Image } from "../../image.class"; import { MatchRequest } from "../../match-request.class"; import { MatchResult } from "../../match-result.class"; import { Region } from "../../region.class"; +import { DataSource } from "./data-source.interface"; import { FinderInterface } from "./finder.interface"; +import { ImageProcessor } from "./image-processor.class"; +import { ImageReader } from "./image-reader.class"; export class TemplateMatchingFinder implements FinderInterface { private static scaleStep = 0.5; @@ -101,19 +104,23 @@ export class TemplateMatchingFinder implements FinderInterface { } private static async debugResult(image: cv.Mat, result: MatchResult, filename: string, suffix?: string) { - const roiRect = new cv.Rect( - result.location.left, - result.location.top, - result.location.width, - result.location.height); - this.debugImage(image.getRegion(roiRect), filename, suffix); + const roiRect = new cv.Rect( + result.location.left, + result.location.top, + result.location.width, + result.location.height); + this.debugImage(image.getRegion(roiRect), filename, suffix); } - constructor() { + constructor( + private source: DataSource = new ImageReader(), + ) { } public async findMatches(matchRequest: MatchRequest, debug: boolean = false): Promise { - const needle = await this.loadImage(matchRequest.pathToNeedle); + const needle = await this.loadNeedle( + await this.source.load(matchRequest.pathToNeedle) + ); if (needle.empty) { throw new Error( `Failed to load ${matchRequest.pathToNeedle}, got empty image.`, @@ -178,59 +185,30 @@ export class TemplateMatchingFinder implements FinderInterface { public async findMatch(matchRequest: MatchRequest, debug: boolean = false): Promise { const matches = await this.findMatches(matchRequest, debug); - if (matches.length === 0) { - throw new Error( - `Unable to locate ${matchRequest.pathToNeedle}, no match!`, - ); - } - return matches[0]; - } - - public async loadImage(imagePath: string): Promise { - return cv.imreadAsync(imagePath); - } - - public async fromImageWithAlphaChannel( - img: Image, - roi?: Region, - ): Promise { - const mat = await new cv.Mat(img.data, img.height, img.width, cv.CV_8UC4).cvtColorAsync(cv.COLOR_BGRA2BGR); - if (roi) { - return Promise.resolve( - mat.getRegion(new cv.Rect(roi.left, roi.top, roi.width, roi.height)), - ); - } else { - return Promise.resolve(mat); - } - } - - public async rgbToGrayScale(img: cv.Mat): Promise { - return img.cvtColorAsync(cv.COLOR_BGR2GRAY); + return new Promise((resolve, reject) => { + if (matches.length === 0) { + reject(`Unable to locate ${matchRequest.pathToNeedle}, no match!`); + } + resolve(matches[0]); + }); } - public async fromImageWithoutAlphaChannel( - img: Image, - roi?: Region, - ): Promise { - const mat = new cv.Mat(img.data, img.height, img.width, cv.CV_8UC3); - if (roi) { - return Promise.resolve( - mat.getRegion(new cv.Rect(roi.left, roi.top, roi.width, roi.height)), - ); - } else { - return Promise.resolve(mat); + private async loadNeedle(image: Image): Promise { + if (image.hasAlphaChannel) { + return ImageProcessor.fromImageWithAlphaChannel(image); } + return ImageProcessor.fromImageWithoutAlphaChannel(image); } private async loadHaystack(matchRequest: MatchRequest): Promise { const searchRegion = TemplateMatchingFinder.determineScaledSearchRegion(matchRequest); if (matchRequest.haystack.hasAlphaChannel) { - return await this.fromImageWithAlphaChannel( + return ImageProcessor.fromImageWithAlphaChannel( matchRequest.haystack, searchRegion, ); } else { - return await this.fromImageWithoutAlphaChannel( + return ImageProcessor.fromImageWithoutAlphaChannel( matchRequest.haystack, searchRegion, ); From 7de978b17032e7c36d802ccfbaed3627d3bdb61c Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:43:39 +0100 Subject: [PATCH 08/25] Added sleep function --- lib/sleep.function.spec.ts | 16 ++++++++++++++++ lib/sleep.function.ts | 3 +++ 2 files changed, 19 insertions(+) create mode 100644 lib/sleep.function.spec.ts create mode 100644 lib/sleep.function.ts diff --git a/lib/sleep.function.spec.ts b/lib/sleep.function.spec.ts new file mode 100644 index 00000000..a437d6c3 --- /dev/null +++ b/lib/sleep.function.spec.ts @@ -0,0 +1,16 @@ +import { sleep } from "./sleep.function"; + +describe("sleep", () => { + it("should resolve after x ms", async () => { + // GIVEN + const timeout = 500; + + // WHEN + const before = Date.now(); + await sleep(timeout); + const after = Date.now(); + + // THEN + expect(after - before).toBeGreaterThanOrEqual(timeout); + }); +}); diff --git a/lib/sleep.function.ts b/lib/sleep.function.ts new file mode 100644 index 00000000..f49345de --- /dev/null +++ b/lib/sleep.function.ts @@ -0,0 +1,3 @@ +export const sleep = async (ms: number) => { + return new Promise(resolve => setTimeout(resolve, ms)); +}; From cb72d2bcf7fe1b9265fc5d28220ffd0b9a6518c7 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:44:36 +0100 Subject: [PATCH 09/25] FileType Enum --- lib/file-type.enum.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lib/file-type.enum.ts diff --git a/lib/file-type.enum.ts b/lib/file-type.enum.ts new file mode 100644 index 00000000..d8b36663 --- /dev/null +++ b/lib/file-type.enum.ts @@ -0,0 +1,4 @@ +export enum FileType { + PNG = ".png", + JPG = ".jpg" +} From f3639c2d41839d28c4d54aaea963a9dd6b4b7baa Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:45:23 +0100 Subject: [PATCH 10/25] Added function to generate output filenames --- lib/generate-output-path.function.spec.ts | 112 ++++++++++++++++++++++ lib/generate-output-path.function.ts | 20 ++++ 2 files changed, 132 insertions(+) create mode 100644 lib/generate-output-path.function.spec.ts create mode 100644 lib/generate-output-path.function.ts diff --git a/lib/generate-output-path.function.spec.ts b/lib/generate-output-path.function.spec.ts new file mode 100644 index 00000000..2187b5e1 --- /dev/null +++ b/lib/generate-output-path.function.spec.ts @@ -0,0 +1,112 @@ +import { join } from "path"; +import { cwd } from "process"; +import { FileType } from "./file-type.enum"; +import { generateOutputPath } from "./generate-output-path.function"; + +describe("generate-output-path", () => { + it("should default to a PNG file without pre- or postfix in the current directory", () => { + // GIVEN + const filename = "asdf"; + const ext = FileType.PNG; + const expectedPath = join(cwd(), `${filename}${ext}`); + + // WHEN + const result = generateOutputPath(filename); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should should allow to add a prefix to the filename", () => { + // GIVEN + const filename = "asdf"; + const pre = "foo_"; + const ext = FileType.PNG; + const expectedPath = join(cwd(), `${pre}${filename}${ext}`); + + // WHEN + const result = generateOutputPath(filename, {prefix: pre}); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should should allow to add a postfix to the filename", () => { + // GIVEN + const filename = "asdf"; + const post = "_bar"; + const ext = FileType.PNG; + const expectedPath = join(cwd(), `${filename}${post}${ext}`); + + // WHEN + const result = generateOutputPath(filename, {postfix: post}); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should should allow to add both a prefix and a postfix to the filename", () => { + // GIVEN + const filename = "asdf"; + const pre = "foo_"; + const post = "_bar"; + const ext = FileType.PNG; + const expectedPath = join(cwd(), `${pre}${filename}${post}${ext}`); + + // WHEN + const result = generateOutputPath(filename, { + postfix: post, + prefix: pre, + }); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should should allow to configure the file path", () => { + // GIVEN + const filename = "asdf"; + const filepath = "/foo/test/bar"; + const ext = FileType.PNG; + const expectedPath = join(filepath, `${filename}${ext}`); + + // WHEN + const result = generateOutputPath(filename, { + path: filepath, + }); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should handle relative file path", () => { + // GIVEN + const filename = "asdf"; + const filepath = "/foo/../bar"; + const ext = FileType.PNG; + const expectedPath = join(filepath, `${filename}${ext}`); + + // WHEN + const result = generateOutputPath(filename, { + path: filepath, + }); + + // THEN + expect(result).toEqual(expectedPath); + }); + + it("should handle different file types", () => { + // GIVEN + const filename = "asdf"; + const ext = FileType.JPG; + const expectedPath = join(cwd(), `${filename}${ext}`); + + // WHEN + const result = generateOutputPath(filename, { + type: FileType.JPG + }); + + // THEN + expect(result).toEqual(expectedPath); + }); +}); diff --git a/lib/generate-output-path.function.ts b/lib/generate-output-path.function.ts new file mode 100644 index 00000000..11629020 --- /dev/null +++ b/lib/generate-output-path.function.ts @@ -0,0 +1,20 @@ +import { join, parse } from "path"; +import { cwd } from "process"; +import { FileType } from "./file-type.enum"; + +export const generateOutputPath = ( + filename: string, + params?: { + type?: FileType, + path?: string, + prefix?: string, + postfix?: string + } +) => { + const name = parse(filename).name; + const imageType = (params && params.type) ? params.type : FileType.PNG; + const path = (params && params.path) ? params.path : cwd(); + const prefix = (params && params.prefix) ? params.prefix : ""; + const postfix = (params && params.postfix) ? params.postfix : ""; + return join(path, `${prefix}${name}${postfix}${imageType}`); +}; From 3183b91ce2b1179d63a61e5c858d3f1b0f3092e2 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:47:10 +0100 Subject: [PATCH 11/25] Moved screen related methods from Native to VisionAdapter, added saveImage method --- lib/adapter/native.adapter.class.spec.ts | 124 +++-------------------- lib/adapter/native.adapter.class.ts | 62 ------------ lib/adapter/vision.adapter.class.spec.ts | 71 ++++++++++++- lib/adapter/vision.adapter.class.ts | 83 ++++++++++++++- 4 files changed, 166 insertions(+), 174 deletions(-) diff --git a/lib/adapter/native.adapter.class.spec.ts b/lib/adapter/native.adapter.class.spec.ts index 0f478bd4..086e2286 100644 --- a/lib/adapter/native.adapter.class.spec.ts +++ b/lib/adapter/native.adapter.class.spec.ts @@ -4,55 +4,19 @@ import { Point } from "../point.class"; import { ClipboardAction } from "../provider/native/clipboardy-clipboard-action.class"; import { KeyboardAction } from "../provider/native/robotjs-keyboard-action.class"; import { MouseAction } from "../provider/native/robotjs-mouse-action.class"; -import { ScreenAction } from "../provider/native/robotjs-screen-action.class"; -import { Region } from "../region.class"; import { NativeAdapter } from "./native.adapter.class"; jest.mock("../provider/native/clipboardy-clipboard-action.class"); jest.mock("../provider/native/robotjs-mouse-action.class"); jest.mock("../provider/native/robotjs-keyboard-action.class"); -jest.mock("../provider/native/robotjs-screen-action.class"); - -describe("Native adapter class", () => { - it("should delegate calls to grabScreen", () => { - // GIVEN - const clipboardMock = new ClipboardAction(); - const keyboardMock = new KeyboardAction(); - const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); - - // WHEN - SUT.grabScreen(); - - // THEN - expect(screenMock.grabScreen).toBeCalledTimes(1); - }); - - it("should delegate calls to grabScreenRegion", () => { - // GIVEN - const clipboardMock = new ClipboardAction(); - const keyboardMock = new KeyboardAction(); - const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); - const screenRegion = new Region(0, 0, 100, 100); - - // WHEN - SUT.grabScreenRegion(screenRegion); - - // THEN - expect(screenMock.grabScreenRegion).toBeCalledTimes(1); - expect(screenMock.grabScreenRegion).toBeCalledWith(screenRegion); - }); +describe("NativeAdapter class", () => { it("should delegate calls to setMouseDelay", () => { // GIVEN const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const delay = 5; // WHEN @@ -68,8 +32,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const newPosition = new Point(10, 10); // WHEN @@ -85,8 +48,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); // WHEN SUT.currentMousePosition(); @@ -95,58 +57,12 @@ describe("Native adapter class", () => { expect(mouseMock.currentMousePosition).toBeCalledTimes(1); }); - it("should delegate calls to screenWidth", () => { - // GIVEN - const clipboardMock = new ClipboardAction(); - const keyboardMock = new KeyboardAction(); - const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); - - // WHEN - SUT.screenWidth(); - - // THEN - expect(screenMock.screenWidth).toBeCalledTimes(1); - }); - - it("should delegate calls to screenHeight", () => { - // GIVEN - const clipboardMock = new ClipboardAction(); - const keyboardMock = new KeyboardAction(); - const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); - - // WHEN - SUT.screenHeight(); - - // THEN - expect(screenMock.screenHeight).toBeCalledTimes(1); - }); - - it("should delegate calls to screenSize", () => { - // GIVEN - const clipboardMock = new ClipboardAction(); - const keyboardMock = new KeyboardAction(); - const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); - - // WHEN - SUT.screenSize(); - - // THEN - expect(screenMock.screenSize).toBeCalledTimes(1); - }); - it("should delegate calls to leftClick", () => { // GIVEN const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); // WHEN SUT.leftClick(); @@ -160,8 +76,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); // WHEN SUT.rightClick(); @@ -175,8 +90,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); // WHEN SUT.middleClick(); @@ -190,8 +104,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const buttonToPress = Button.LEFT; // WHEN @@ -207,8 +120,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const buttonToRelease = Button.LEFT; // WHEN @@ -224,8 +136,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const keyToPress = Key.A; // WHEN @@ -241,8 +152,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const keyToRelease = Key.A; // WHEN @@ -258,8 +168,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const keyToClick = Key.A; // WHEN @@ -275,8 +184,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const stringToType = "testString"; // WHEN @@ -292,8 +200,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); const stringToCopy = "testString"; // WHEN @@ -309,8 +216,7 @@ describe("Native adapter class", () => { const clipboardMock = new ClipboardAction(); const keyboardMock = new KeyboardAction(); const mouseMock = new MouseAction(); - const screenMock = new ScreenAction(); - const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock, screenMock); + const SUT = new NativeAdapter(clipboardMock, keyboardMock, mouseMock); // WHEN SUT.paste(); diff --git a/lib/adapter/native.adapter.class.ts b/lib/adapter/native.adapter.class.ts index 92216a9c..d513e66e 100644 --- a/lib/adapter/native.adapter.class.ts +++ b/lib/adapter/native.adapter.class.ts @@ -1,5 +1,4 @@ import { Button } from "../button.enum"; -import { Image } from "../image.class"; import { Key } from "../key.enum"; import { Point } from "../point.class"; import { ClipboardActionProvider } from "../provider/native/clipboard-action-provider.interface"; @@ -8,9 +7,6 @@ import { KeyboardActionProvider } from "../provider/native/keyboard-action-provi import { MouseActionInterface } from "../provider/native/mouse-action-provider.interface"; import { KeyboardAction } from "../provider/native/robotjs-keyboard-action.class"; import { MouseAction } from "../provider/native/robotjs-mouse-action.class"; -import { ScreenAction } from "../provider/native/robotjs-screen-action.class"; -import { ScreenActionProvider } from "../provider/native/screen-action-provider.interface"; -import { Region } from "../region.class"; /** * NativeAdapter serves as an abstraction layer for all OS level interactions. @@ -24,30 +20,8 @@ export class NativeAdapter { private clipboard: ClipboardActionProvider = new ClipboardAction(), private keyboard: KeyboardActionProvider = new KeyboardAction(), private mouse: MouseActionInterface = new MouseAction(), - private screen: ScreenActionProvider = new ScreenAction(), ) {} - /** - * grabScreen will return an Image containing the current screen image - * - * @returns {Promise} Image will contain screenshot data as well as dimensions - * @memberof NativeAdapter - */ - public grabScreen(): Promise { - return this.screen.grabScreen(); - } - - /** - * grabScreenRegion essentially does the same as grabScreen, but only returns a specified Region - * - * @param {Region} region The screen region we want to grab - * @returns {Promise} Image will contain screenshot data of the specified region as well as dimensions - * @memberof NativeAdapter - */ - public grabScreenRegion(region: Region): Promise { - return this.screen.grabScreenRegion(region); - } - /** * setMouseDelay configures mouse speed for movement * @@ -88,42 +62,6 @@ export class NativeAdapter { return this.mouse.currentMousePosition(); } - /** - * screenWidth returns the main screen's width as reported by the OS. - * Please notice that on e.g. Apples Retina display the reported width - * and the actual pixel size may differ - * - * @returns {Promise} The main screen's width as reported by the OS - * @memberof NativeAdapter - */ - public screenWidth(): Promise { - return this.screen.screenWidth(); - } - - /** - * screenHeight returns the main screen's height as reported by the OS. - * Please notice that on e.g. Apples Retina display the reported width - * and the actual pixel size may differ - * - * @returns {Promise} The main screen's height as reported by the OS - * @memberof NativeAdapter - */ - public screenHeight(): Promise { - return this.screen.screenHeight(); - } - - /** - * screenSize returns a Region object with the main screen's size. - * Please notice that on e.g. Apples Retina display the reported width - * and the actual pixel size may differ - * - * @returns {Promise} The Region object the size of your main screen - * @memberof NativeAdapter - */ - public screenSize(): Promise { - return this.screen.screenSize(); - } - /** * leftClick triggers a native left-click event via OS API * diff --git a/lib/adapter/vision.adapter.class.spec.ts b/lib/adapter/vision.adapter.class.spec.ts index e94ca3de..f336ea40 100644 --- a/lib/adapter/vision.adapter.class.spec.ts +++ b/lib/adapter/vision.adapter.class.spec.ts @@ -1,12 +1,81 @@ import { Image } from "../image.class"; import { MatchRequest } from "../match-request.class"; +import { ScreenAction } from "../provider/native/robotjs-screen-action.class"; import { TemplateMatchingFinder } from "../provider/opencv/template-matching-finder.class"; import { Region } from "../region.class"; import { VisionAdapter } from "./vision.adapter.class"; jest.mock("../provider/opencv/template-matching-finder.class"); +jest.mock("../provider/native/robotjs-screen-action.class"); + +describe("VisionAdapter class", () => { + it("should delegate calls to grabScreen", () => { + // GIVEN + const finderMock = new TemplateMatchingFinder(); + const screenMock = new ScreenAction(); + const SUT = new VisionAdapter(finderMock, screenMock); + + // WHEN + SUT.grabScreen(); + + // THEN + expect(screenMock.grabScreen).toBeCalledTimes(1); + }); + + it("should delegate calls to grabScreenRegion", () => { + // GIVEN + const finderMock = new TemplateMatchingFinder(); + const screenMock = new ScreenAction(); + const SUT = new VisionAdapter(finderMock, screenMock); + const screenRegion = new Region(0, 0, 100, 100); + + // WHEN + SUT.grabScreenRegion(screenRegion); + + // THEN + expect(screenMock.grabScreenRegion).toBeCalledTimes(1); + expect(screenMock.grabScreenRegion).toBeCalledWith(screenRegion); + }); + + it("should delegate calls to screenWidth", () => { + // GIVEN + const finderMock = new TemplateMatchingFinder(); + const screenMock = new ScreenAction(); + const SUT = new VisionAdapter(finderMock, screenMock); + + // WHEN + SUT.screenWidth(); + + // THEN + expect(screenMock.screenWidth).toBeCalledTimes(1); + }); + + it("should delegate calls to screenHeight", () => { + // GIVEN + const finderMock = new TemplateMatchingFinder(); + const screenMock = new ScreenAction(); + const SUT = new VisionAdapter(finderMock, screenMock); + + // WHEN + SUT.screenHeight(); + + // THEN + expect(screenMock.screenHeight).toBeCalledTimes(1); + }); + + it("should delegate calls to screenSize", () => { + // GIVEN + const finderMock = new TemplateMatchingFinder(); + const screenMock = new ScreenAction(); + const SUT = new VisionAdapter(finderMock, screenMock); + + // WHEN + SUT.screenSize(); + + // THEN + expect(screenMock.screenSize).toBeCalledTimes(1); + }); -describe("Native adapter class", () => { it("should delegate calls to findImage", () => { // GIVEN const finderMock = new TemplateMatchingFinder(); diff --git a/lib/adapter/vision.adapter.class.ts b/lib/adapter/vision.adapter.class.ts index cf830817..8416b1b5 100644 --- a/lib/adapter/vision.adapter.class.ts +++ b/lib/adapter/vision.adapter.class.ts @@ -1,7 +1,13 @@ +import { Image } from "../image.class"; import { MatchRequest } from "../match-request.class"; import { MatchResult } from "../match-result.class"; +import { ScreenAction } from "../provider/native/robotjs-screen-action.class"; +import { ScreenActionProvider } from "../provider/native/screen-action-provider.interface"; +import { DataSink } from "../provider/opencv/data-sink.interface"; import { FinderInterface } from "../provider/opencv/finder.interface"; +import { ImageWriter } from "../provider/opencv/image-writer.class"; import { TemplateMatchingFinder } from "../provider/opencv/template-matching-finder.class"; +import { Region } from "../region.class"; /** * OpenCVAdapter serves as an abstraction layer for all image based interactions. @@ -11,7 +17,33 @@ import { TemplateMatchingFinder } from "../provider/opencv/template-matching-fin * All actions which involve screenshots / images are bundled in this adapter. */ export class VisionAdapter { - constructor(private finder: FinderInterface = new TemplateMatchingFinder()) {} + constructor( + private finder: FinderInterface = new TemplateMatchingFinder(), + private screen: ScreenActionProvider = new ScreenAction(), + private dataSink: DataSink = new ImageWriter() + ) { + } + + /** + * grabScreen will return an Image containing the current screen image + * + * @returns {Promise} Image will contain screenshot data as well as dimensions + * @memberof VisionAdapter + */ + public grabScreen(): Promise { + return this.screen.grabScreen(); + } + + /** + * grabScreenRegion essentially does the same as grabScreen, but only returns a specified Region + * + * @param {Region} region The screen region we want to grab + * @returns {Promise} Image will contain screenshot data of the specified region as well as dimensions + * @memberof VisionAdapter + */ + public grabScreenRegion(region: Region): Promise { + return this.screen.grabScreenRegion(region); + } /** * findOnScreenRegion will search for a given pattern inside a region of an image. @@ -20,7 +52,7 @@ export class VisionAdapter { * * @param {MatchRequest} matchRequest A match request which holds all required matching data * @returns {Promise} MatchResult will contain location and probability of a possible match - * @memberof OpenCVAdapter + * @memberof VisionAdapter */ public async findOnScreenRegion( matchRequest: MatchRequest, @@ -28,4 +60,51 @@ export class VisionAdapter { const matchResult = await this.finder.findMatch(matchRequest); return Promise.resolve(matchResult); } + + /** + * screenWidth returns the main screen's width as reported by the OS. + * Please notice that on e.g. Apples Retina display the reported width + * and the actual pixel size may differ + * + * @returns {Promise} The main screen's width as reported by the OS + * @memberof VisionAdapter + */ + public screenWidth(): Promise { + return this.screen.screenWidth(); + } + + /** + * screenHeight returns the main screen's height as reported by the OS. + * Please notice that on e.g. Apples Retina display the reported width + * and the actual pixel size may differ + * + * @returns {Promise} The main screen's height as reported by the OS + * @memberof VisionAdapter + */ + public screenHeight(): Promise { + return this.screen.screenHeight(); + } + + /** + * screenSize returns a Region object with the main screen's size. + * Please notice that on e.g. Apples Retina display the reported width + * and the actual pixel size may differ + * + * @returns {Promise} The Region object the size of your main screen + * @memberof VisionAdapter + */ + public screenSize(): Promise { + return this.screen.screenSize(); + } + + /** + * saveImage saves an Image to a given path on disk. + * + * @param image The Image to store + * @param path The storage path + * @memberof VisionAdapter + */ + public saveImage(image: Image, path: string) { + (this.dataSink as ImageWriter).store(image, path); + } } From cc8516993d6c6f3ca5d0b499d3c699b61ce45724 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:49:09 +0100 Subject: [PATCH 12/25] Updated Screen class to Adapter changes, added capture method --- lib/screen.class.ts | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/screen.class.ts b/lib/screen.class.ts index 1e4b565c..c1769e95 100644 --- a/lib/screen.class.ts +++ b/lib/screen.class.ts @@ -1,6 +1,8 @@ import { join, normalize } from "path"; -import { NativeAdapter } from "./adapter/native.adapter.class"; +import { cwd } from "process"; import { VisionAdapter } from "./adapter/vision.adapter.class"; +import { FileType } from "./file-type.enum"; +import { generateOutputPath } from "./generate-output-path.function"; import { LocationParameters } from "./locationparameters.class"; import { MatchRequest } from "./match-request.class"; import { Region } from "./region.class"; @@ -11,14 +13,15 @@ export class Screen { resourceDirectory: "./", }; - constructor(private vision: VisionAdapter, private native: NativeAdapter) {} + constructor(private vision: VisionAdapter) { + } public width() { - return this.native.screenWidth(); + return this.vision.screenWidth(); } public height() { - return this.native.screenHeight(); + return this.vision.screenHeight(); } public async findOnScreen( @@ -27,12 +30,12 @@ export class Screen { ): Promise { const minMatch = (params && params.confidence) || this.config.confidence; const searchRegion = - (params && params.searchRegion) || await this.native.screenSize(); + (params && params.searchRegion) || await this.vision.screenSize(); const fullPathToNeedle = normalize(join(this.config.resourceDirectory, pathToNeedle)); - console.log(`Full path to needle: ${fullPathToNeedle}`); + // console.log(`Full path to needle: ${fullPathToNeedle}`); - const screenImage = await this.native.grabScreen(); + const screenImage = await this.vision.grabScreen(); const matchRequest = new MatchRequest( screenImage, @@ -50,9 +53,27 @@ export class Screen { reject( `No match for ${pathToNeedle}. Required: ${minMatch}, given: ${ matchResult.confidence - }`, + }`, ); } }); } + + public async capture( + fileName: string, + fileFormat: FileType = FileType.PNG, + filePath: string = cwd(), + fileNamePrefix: string = "", + fileNamePostfix: string = ""): Promise { + const outputPath = generateOutputPath(fileName, { + path: filePath, + postfix: fileNamePostfix, + prefix: fileNamePrefix, + type: fileFormat, + }); + + const currentScreen = await this.vision.grabScreen(); + this.vision.saveImage(currentScreen, outputPath); + return outputPath; + } } From 36df50e607b4ec8bf0edf40ffb105d1b1e019f0e Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:49:56 +0100 Subject: [PATCH 13/25] Updated tests, added E2E tests --- lib/screen.class.e2e.spec.ts | 35 +++++++++++++++++++++++++++++++++++ lib/screen.class.spec.ts | 34 ++++++++++++++-------------------- 2 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 lib/screen.class.e2e.spec.ts diff --git a/lib/screen.class.e2e.spec.ts b/lib/screen.class.e2e.spec.ts new file mode 100644 index 00000000..4d86ef13 --- /dev/null +++ b/lib/screen.class.e2e.spec.ts @@ -0,0 +1,35 @@ +import { existsSync } from "fs"; +import { VisionAdapter } from "./adapter/vision.adapter.class"; +import { FileType } from "./file-type.enum"; +import { Screen } from "./screen.class"; +import { sleep } from "./sleep.function"; + +describe("Screen.", () => { + it("should capture the screen", async () => { + // GIVEN + const visionAdapter = new VisionAdapter(); + const SUT = new Screen(visionAdapter); + + // WHEN + const filename = await SUT.capture("asdf.txt", FileType.PNG); + + // THEN + expect(filename).not.toBeNull(); + await sleep(1000); + expect(existsSync(filename)).toBeTruthy(); + }); + + it("should capture the screen and save to JPG", async () => { + // GIVEN + const visionAdapter = new VisionAdapter(); + const SUT = new Screen(visionAdapter); + + // WHEN + const filename = await SUT.capture("asdf.txt", FileType.JPG); + + // THEN + expect(filename).not.toBeNull(); + await sleep(1000); + expect(existsSync(filename)).toBeTruthy(); + }); +}); diff --git a/lib/screen.class.spec.ts b/lib/screen.class.spec.ts index d6ca34ab..ef8a8777 100644 --- a/lib/screen.class.spec.ts +++ b/lib/screen.class.spec.ts @@ -1,11 +1,10 @@ -import {NativeAdapter} from "./adapter/native.adapter.class"; -import {VisionAdapter} from "./adapter/vision.adapter.class"; -import {Image} from "./image.class"; -import {LocationParameters} from "./locationparameters.class"; -import {MatchRequest} from "./match-request.class"; -import {MatchResult} from "./match-result.class"; -import {Region} from "./region.class"; -import {Screen} from "./screen.class"; +import { VisionAdapter } from "./adapter/vision.adapter.class"; +import { Image } from "./image.class"; +import { LocationParameters } from "./locationparameters.class"; +import { MatchRequest } from "./match-request.class"; +import { MatchResult } from "./match-result.class"; +import { Region } from "./region.class"; +import { Screen } from "./screen.class"; jest.mock("./adapter/native.adapter.class"); jest.mock("./adapter/vision.adapter.class"); @@ -13,11 +12,11 @@ jest.mock("./adapter/vision.adapter.class"); const searchRegion = new Region(0, 0, 100, 100); beforeAll(() => { - NativeAdapter.prototype.grabScreen = jest.fn(() => { + VisionAdapter.prototype.grabScreen = jest.fn(() => { return new Image(searchRegion.width, searchRegion.height, new ArrayBuffer(0), 3); }); - NativeAdapter.prototype.screenSize = jest.fn(() => { + VisionAdapter.prototype.screenSize = jest.fn(() => { return searchRegion; }); }); @@ -31,9 +30,8 @@ describe("Screen.", () => { }); const visionAdapterMock = new VisionAdapter(); - const nativeAdapterMock = new NativeAdapter(); - const SUT = new Screen(visionAdapterMock, nativeAdapterMock); + const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; await expect(SUT.findOnScreen(imagePath)).resolves.toEqual(matchResult.location); const matchRequest = new MatchRequest( @@ -53,9 +51,8 @@ describe("Screen.", () => { }); const visionAdapterMock = new VisionAdapter(); - const nativeAdapterMock = new NativeAdapter(); - const SUT = new Screen(visionAdapterMock, nativeAdapterMock); + const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; await expect(SUT.findOnScreen(imagePath)) .rejects @@ -71,9 +68,8 @@ describe("Screen.", () => { }); const visionAdapterMock = new VisionAdapter(); - const nativeAdapterMock = new NativeAdapter(); - const SUT = new Screen(visionAdapterMock, nativeAdapterMock); + const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(undefined, minMatch); @@ -96,9 +92,8 @@ describe("Screen.", () => { }); const visionAdapterMock = new VisionAdapter(); - const nativeAdapterMock = new NativeAdapter(); - const SUT = new Screen(visionAdapterMock, nativeAdapterMock); + const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(customSearchRegion); @@ -122,9 +117,8 @@ describe("Screen.", () => { }); const visionAdapterMock = new VisionAdapter(); - const nativeAdapterMock = new NativeAdapter(); - const SUT = new Screen(visionAdapterMock, nativeAdapterMock); + const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(customSearchRegion, minMatch); From b644effa87d921845daf2757c7e6832801d27249 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 10:50:26 +0100 Subject: [PATCH 14/25] Updated to Adapter changes --- index.ts | 2 +- lib/assert.class.spec.ts | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/index.ts b/index.ts index 7adcaad1..46aed596 100644 --- a/index.ts +++ b/index.ts @@ -25,7 +25,7 @@ const clipboard = new Clipboard(nativeActions); const keyboard = new Keyboard(nativeActions); const mouse = new Mouse(nativeActions); const movement = new Movement(nativeActions, new LineHelper()); -const screen = new Screen(screenActions, nativeActions); +const screen = new Screen(screenActions); const assert = new Assert(screen); export { clipboard, keyboard, mouse, movement, screen, assert }; diff --git a/lib/assert.class.spec.ts b/lib/assert.class.spec.ts index b36708b2..17c38ad5 100644 --- a/lib/assert.class.spec.ts +++ b/lib/assert.class.spec.ts @@ -1,4 +1,3 @@ -import { NativeAdapter } from "./adapter/native.adapter.class"; import { VisionAdapter } from "./adapter/vision.adapter.class"; import { Assert } from "./assert.class"; import { Region } from "./region.class"; @@ -11,7 +10,7 @@ jest.mock("./screen.class"); describe("Assert", () => { it("isVisible should not throw if a match is found.", async () => { Screen.prototype.findOnScreen = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); - const screenMock = new Screen(new VisionAdapter(), new NativeAdapter()); + const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); await expect(SUT.isVisible("foo")).resolves.not.toThrowError(); @@ -19,7 +18,7 @@ describe("Assert", () => { it("isVisible should throw if a match is found.", async () => { Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); - const screenMock = new Screen(new VisionAdapter(), new NativeAdapter()); + const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); await expect(SUT.isVisible("foo")).rejects.toThrowError("Element not found"); @@ -27,7 +26,7 @@ describe("Assert", () => { it("isVisible should throw if a match is found.", async () => { Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); - const screenMock = new Screen(new VisionAdapter(), new NativeAdapter()); + const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); const searchRegion = new Region(10, 10, 10, 10); @@ -39,7 +38,7 @@ describe("Assert", () => { it("isNotVisible should throw if a match is found.", async () => { Screen.prototype.findOnScreen = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); - const screenMock = new Screen(new VisionAdapter(), new NativeAdapter()); + const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); await expect(SUT.notVisible("foo")).rejects.toThrowError("Element visible"); @@ -47,7 +46,7 @@ describe("Assert", () => { it("isVisible should throw if a match is found.", async () => { Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); - const screenMock = new Screen(new VisionAdapter(), new NativeAdapter()); + const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); await expect(SUT.notVisible("foo")).resolves.not.toThrowError(); From 327a3d26404ef3a529d17c1fa3c4aa574ff0d196 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 11:55:49 +0100 Subject: [PATCH 15/25] Added further Screen E2E tests --- lib/screen.class.e2e.spec.ts | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/lib/screen.class.e2e.spec.ts b/lib/screen.class.e2e.spec.ts index 4d86ef13..3dace4f9 100644 --- a/lib/screen.class.e2e.spec.ts +++ b/lib/screen.class.e2e.spec.ts @@ -32,4 +32,54 @@ describe("Screen.", () => { await sleep(1000); expect(existsSync(filename)).toBeTruthy(); }); + + it("should capture the screen and save file with prefix", async () => { + // GIVEN + const visionAdapter = new VisionAdapter(); + const SUT = new Screen(visionAdapter); + const prefix = "foo_"; + + // WHEN + const filename = await SUT.capture("asdf.txt", FileType.JPG, "./", prefix); + + // THEN + expect(filename.includes(prefix)).toBeTruthy(); + expect(filename).not.toBeNull(); + await sleep(1000); + expect(existsSync(filename)).toBeTruthy(); + }); + + it("should capture the screen and save file with postfix", async () => { + // GIVEN + const visionAdapter = new VisionAdapter(); + const SUT = new Screen(visionAdapter); + const postfix = "_bar"; + + // WHEN + const filename = await SUT.capture("asdf.txt", FileType.JPG, "./", "", postfix); + + // THEN + expect(filename.includes(postfix)).toBeTruthy(); + expect(filename).not.toBeNull(); + await sleep(1000); + expect(existsSync(filename)).toBeTruthy(); + }); + + it("should capture the screen and save file with pre- and postfix", async () => { + // GIVEN + const visionAdapter = new VisionAdapter(); + const SUT = new Screen(visionAdapter); + const filename = "asdf"; + const prefix = "foo_"; + const postfix = "_bar"; + + // WHEN + const output = await SUT.capture("asdf", FileType.JPG, "./", prefix, postfix); + + // THEN + expect(output.includes(`${prefix}${filename}${postfix}`)).toBeTruthy(); + expect(output).not.toBeNull(); + await sleep(1000); + expect(existsSync(output)).toBeTruthy(); + }); }); From d27d31b7c11d72f24243ddfc7ae65c8dea5fd605 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 11:56:08 +0100 Subject: [PATCH 16/25] Removed notification hook --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd64c3a7..bea209f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,6 @@ node_js: - "lts/dubnium" cache: npm -notifications: - webhooks: https://outlook.office.com/webhook/b6e4942d-6066-4001-8ba1-428598f3ae13@eb86a0ab-5bd0-4070-b04f-b7bf90ca02c5/TravisCI/ad6b89add60a4d4c8d1a06aa4ee424e8/d6c06c79-667d-43b9-92b6-0e9687d93d0f - addons: sonarcloud: organization: "nut-tree" From 7c1faadf6fbe8f4d9826e87972dc00ef305ffe1e Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 16:19:00 +0100 Subject: [PATCH 17/25] Updated interfaces --- demo/mouse.js | 16 ++--- lib/clipboard.class.ts | 7 +- lib/keyboard.class.spec.ts | 24 +++---- lib/keyboard.class.ts | 51 ++++++++------ lib/mouse.class.spec.ts | 32 ++++----- lib/mouse.class.ts | 133 ++++++++++++++++++++--------------- lib/screen.class.e2e.spec.ts | 81 +++++++++++---------- 7 files changed, 191 insertions(+), 153 deletions(-) diff --git a/demo/mouse.js b/demo/mouse.js index db007af2..eb4bf6bb 100755 --- a/demo/mouse.js +++ b/demo/mouse.js @@ -12,19 +12,19 @@ const square = async () => { }; (async () => { - mouse - .leftClick() - // await square(); + await mouse + .leftClick(); + await square(); try { screen.config.resourceDirectory = "./assets"; const whale = await screen.findOnScreen("docker.png"); - mouse.move(await movement.straightTo(Location.centerOf(whale))); + await mouse.move(await movement.straightTo(Location.centerOf(whale))); const gitlens = await screen.findOnScreen("gitlens.png"); - mouse.move(await movement.straightTo(Location.centerOf(gitlens))); - mouse.drag(await movement.right(600)); - mouse.move(await movement.straightTo(Location.centerOf(gitlens))); - mouse.drag(await movement.straightTo(Location.centerOf(whale))); + await mouse.move(await movement.straightTo(Location.centerOf(gitlens))); + await mouse.drag(await movement.right(600)); + await mouse.move(await movement.straightTo(Location.centerOf(gitlens))); + await mouse.drag(await movement.straightTo(Location.centerOf(whale))); } catch (error) { console.log(error); } diff --git a/lib/clipboard.class.ts b/lib/clipboard.class.ts index 8a0fc92e..bf07e325 100644 --- a/lib/clipboard.class.ts +++ b/lib/clipboard.class.ts @@ -3,8 +3,11 @@ import { NativeAdapter } from "./adapter/native.adapter.class"; export class Clipboard { constructor(private nativeAdapter: NativeAdapter) {} - public copy(text: string): void { - this.nativeAdapter.copy(text); + public copy(text: string): Promise { + return new Promise(resolve => { + this.nativeAdapter.copy(text); + resolve(); + }); } public paste(): Promise { diff --git a/lib/keyboard.class.spec.ts b/lib/keyboard.class.spec.ts index 4e4b5c7b..fe9efb17 100644 --- a/lib/keyboard.class.spec.ts +++ b/lib/keyboard.class.spec.ts @@ -20,14 +20,14 @@ describe("Keyboard", () => { expect(SUT.config.autoDelayMs).toEqual(500); }); - it("should pass input strings down to the type call.", () => { + it("should pass input strings down to the type call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); const payload = "Test input!"; // WHEN - SUT.type(payload); + await SUT.type(payload); // THEN expect(adapterMock.type).toHaveBeenCalledTimes(payload.length); @@ -36,14 +36,14 @@ describe("Keyboard", () => { } }); - it("should pass multiple input strings down to the type call.", () => { + it("should pass multiple input strings down to the type call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); const payload = ["Test input!", "Array test2"]; // WHEN - SUT.type(...payload); + await SUT.type(...payload); // THEN expect(adapterMock.type).toHaveBeenCalledTimes(payload.join(" ").length); @@ -52,21 +52,21 @@ describe("Keyboard", () => { } }); - it("should pass input keys down to the click call.", () => { + it("should pass input keys down to the click call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); const payload = [Key.A, Key.S, Key.D, Key.F]; // WHEN - SUT.type(...payload); + await SUT.type(...payload); // THEN expect(adapterMock.click).toHaveBeenCalledTimes(1); expect(adapterMock.click).toHaveBeenCalledWith(...payload); }); - it("should pass a list of input keys down to the click call.", () => { + it("should pass a list of input keys down to the click call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); @@ -74,14 +74,14 @@ describe("Keyboard", () => { // WHEN for (const key of payload) { - SUT.type(key); + await SUT.type(key); } // THEN expect(adapterMock.click).toHaveBeenCalledTimes(payload.length); }); - it("should pass a list of input keys down to the pressKey call.", () => { + it("should pass a list of input keys down to the pressKey call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); @@ -89,14 +89,14 @@ describe("Keyboard", () => { // WHEN for (const key of payload) { - SUT.pressKey(key); + await SUT.pressKey(key); } // THEN expect(adapterMock.pressKey).toHaveBeenCalledTimes(payload.length); }); - it("should pass a list of input keys down to the releaseKey call.", () => { + it("should pass a list of input keys down to the releaseKey call.", async () => { // GIVEN const adapterMock = new NativeAdapter(); const SUT = new Keyboard(adapterMock); @@ -104,7 +104,7 @@ describe("Keyboard", () => { // WHEN for (const key of payload) { - SUT.releaseKey(key); + await SUT.releaseKey(key); } // THEN diff --git a/lib/keyboard.class.ts b/lib/keyboard.class.ts index 5c73278e..caf3f584 100644 --- a/lib/keyboard.class.ts +++ b/lib/keyboard.class.ts @@ -18,37 +18,46 @@ export class Keyboard { this.lastAction = Date.now(); } - public type(...input: string[] | Key[]): Keyboard { - if (Keyboard.inputIsString(input)) { - for (const char of input.join(" ").split("")) { - this.waitForNextTick(); - this.nativeAdapter.type(char); - this.updateTick(); + public type(...input: string[] | Key[]): Promise { + return new Promise(async resolve => { + if (Keyboard.inputIsString(input)) { + for (const char of input.join(" ").split("")) { + await this.waitForNextTick(); + this.nativeAdapter.type(char); + this.updateTick(); + } + } else { + this.nativeAdapter.click(...input as Key[]); } - } else { - this.nativeAdapter.click(...input as Key[]); - } - return this; + resolve(this); + }); } - public pressKey(...keys: Key[]): Keyboard { - this.nativeAdapter.pressKey(...keys); - return this; + public pressKey(...keys: Key[]): Promise { + return new Promise(async resolve => { + this.nativeAdapter.pressKey(...keys); + resolve(this); + }); } - public releaseKey(...keys: Key[]): Keyboard { - this.nativeAdapter.releaseKey(...keys); - return this; + public releaseKey(...keys: Key[]): Promise { + return new Promise(async resolve => { + this.nativeAdapter.releaseKey(...keys); + resolve(this); + }); } private updateTick() { this.lastAction = Date.now(); } - private waitForNextTick() { - let current = Date.now(); - while (current - this.lastAction < this.config.autoDelayMs) { - current = Date.now(); - } + private async waitForNextTick(): Promise { + return new Promise(resolve => { + let current = Date.now(); + while (current - this.lastAction < this.config.autoDelayMs) { + current = Date.now(); + } + resolve(); + }); } } diff --git a/lib/mouse.class.spec.ts b/lib/mouse.class.spec.ts index 7850608a..2e021bc7 100644 --- a/lib/mouse.class.spec.ts +++ b/lib/mouse.class.spec.ts @@ -24,110 +24,110 @@ describe("Mouse class", () => { expect(SUT.config.autoDelayMs).toEqual(100); }); - it("should forward scrollLeft to the native adapter class", () => { + it("should forward scrollLeft to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const scrollAmount = 5; // WHEN - const result = SUT.scrollLeft(scrollAmount); + const result = await SUT.scrollLeft(scrollAmount); // THEN expect(nativeAdapterMock.scrollLeft).toBeCalledWith(scrollAmount); expect(result).toBe(SUT); }); - it("should forward scrollRight to the native adapter class", () => { + it("should forward scrollRight to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const scrollAmount = 5; // WHEN - const result = SUT.scrollRight(scrollAmount); + const result = await SUT.scrollRight(scrollAmount); // THEN expect(nativeAdapterMock.scrollRight).toBeCalledWith(scrollAmount); expect(result).toBe(SUT); }); - it("should forward scrollDown to the native adapter class", () => { + it("should forward scrollDown to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const scrollAmount = 5; // WHEN - const result = SUT.scrollDown(scrollAmount); + const result = await SUT.scrollDown(scrollAmount); // THEN expect(nativeAdapterMock.scrollDown).toBeCalledWith(scrollAmount); expect(result).toBe(SUT); }); - it("should forward scrollUp to the native adapter class", () => { + it("should forward scrollUp to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const scrollAmount = 5; // WHEN - const result = SUT.scrollUp(scrollAmount); + const result = await SUT.scrollUp(scrollAmount); // THEN expect(nativeAdapterMock.scrollUp).toBeCalledWith(scrollAmount); expect(result).toBe(SUT); }); - it("should forward leftClick to the native adapter class", () => { + it("should forward leftClick to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); // WHEN - const result = SUT.leftClick(); + const result = await SUT.leftClick(); // THEN expect(nativeAdapterMock.leftClick).toBeCalled(); expect(result).toBe(SUT); }); - it("should forward rightClick to the native adapter class", () => { + it("should forward rightClick to the native adapter class", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); // WHEN - const result = SUT.rightClick(); + const result = await SUT.rightClick(); // THEN expect(nativeAdapterMock.rightClick).toBeCalled(); expect(result).toBe(SUT); }); - it("update mouse position along path on move", () => { + it("update mouse position along path on move", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const path = linehelper.straightLine(new Point(0, 0), new Point(10, 10)); // WHEN - const result = SUT.move(path); + const result = await SUT.move(path); // THEN expect(nativeAdapterMock.setMousePosition).toBeCalledTimes(path.length); expect(result).toBe(SUT); }); - it("should press and hold left mouse button, move and release left mouse button on drag", () => { + it("should press and hold left mouse button, move and release left mouse button on drag", async () => { // GIVEN const nativeAdapterMock = new NativeAdapter(); const SUT = new Mouse(nativeAdapterMock); const path = linehelper.straightLine(new Point(0, 0), new Point(10, 10)); // WHEN - const result = SUT.drag(path); + const result = await SUT.drag(path); // THEN expect(nativeAdapterMock.pressButton).toBeCalledWith(Button.LEFT); diff --git a/lib/mouse.class.ts b/lib/mouse.class.ts index df7e8ca1..80849a64 100644 --- a/lib/mouse.class.ts +++ b/lib/mouse.class.ts @@ -16,86 +16,107 @@ export class Mouse { this.lastAction = Date.now(); } - public setPosition(target: Point): Mouse { - this.native.setMousePosition(target); - return this; + public setPosition(target: Point): Promise { + return new Promise(resolve => { + this.native.setMousePosition(target); + resolve(this); + }); } public getPosition(): Promise { return this.native.currentMousePosition(); } - public move(path: Point[], movementType = MovementType.linear): Mouse { - const timeSteps = movementType(path.length, this.config.mouseSpeed); - for (let idx = 0; idx < path.length; ++idx) { - const node = path[idx]; - const minTime = timeSteps[idx]; - this.waitForNextTick(minTime); - this.native.setMousePosition(node); - this.updateTick(); - } - return this; + public async move(path: Point[], movementType = MovementType.linear): Promise { + return new Promise(async resolve => { + const timeSteps = movementType(path.length, this.config.mouseSpeed); + for (let idx = 0; idx < path.length; ++idx) { + const node = path[idx]; + const minTime = timeSteps[idx]; + await this.waitForNextTick(minTime); + this.native.setMousePosition(node); + await this.updateTick(); + } + resolve(this); + }); } - public leftClick(): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.leftClick(); - this.updateTick(); - return this; + public async leftClick(): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.leftClick(); + await this.updateTick(); + resolve(this); + }); } - public rightClick(): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.rightClick(); - this.updateTick(); - return this; + public async rightClick(): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.rightClick(); + await this.updateTick(); + resolve(this); + }); } - public scrollDown(amount: number): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.scrollDown(amount); - this.updateTick(); - return this; + public async scrollDown(amount: number): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.scrollDown(amount); + await this.updateTick(); + resolve(this); + }); } - public scrollUp(amount: number): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.scrollUp(amount); - this.updateTick(); - return this; + public async scrollUp(amount: number): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.scrollUp(amount); + await this.updateTick(); + resolve(this); + }); } - public scrollLeft(amount: number): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.scrollLeft(amount); - this.updateTick(); - return this; + public async scrollLeft(amount: number): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.scrollLeft(amount); + await this.updateTick(); + resolve(this); + }); } - public scrollRight(amount: number): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.scrollRight(amount); - this.updateTick(); - return this; + public async scrollRight(amount: number): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.scrollRight(amount); + await this.updateTick(); + resolve(this); + }); } - public drag(path: Point[]): Mouse { - this.waitForNextTick(this.config.autoDelayMs); - this.native.pressButton(Button.LEFT); - this.move(path); - this.native.releaseButton(Button.LEFT); - this.updateTick(); - return this; + public async drag(path: Point[]): Promise { + return new Promise(async resolve => { + await this.waitForNextTick(this.config.autoDelayMs); + this.native.pressButton(Button.LEFT); + await this.move(path); + this.native.releaseButton(Button.LEFT); + await this.updateTick(); + resolve(this); + }); } - private updateTick() { + private async updateTick() { this.lastAction = Date.now(); } - private waitForNextTick(minTime: number) { - let current = Date.now(); - while (current - this.lastAction < minTime) { - current = Date.now(); - } + private async waitForNextTick(minTime: number): Promise { + return new Promise(resolve => { + let current = Date.now(); + while (current - this.lastAction < minTime) { + current = Date.now(); + } + resolve(); + }); } } diff --git a/lib/screen.class.e2e.spec.ts b/lib/screen.class.e2e.spec.ts index 3dace4f9..22bf4468 100644 --- a/lib/screen.class.e2e.spec.ts +++ b/lib/screen.class.e2e.spec.ts @@ -5,67 +5,71 @@ import { Screen } from "./screen.class"; import { sleep } from "./sleep.function"; describe("Screen.", () => { - it("should capture the screen", async () => { + it("should capture the screen", () => { // GIVEN const visionAdapter = new VisionAdapter(); const SUT = new Screen(visionAdapter); // WHEN - const filename = await SUT.capture("asdf.txt", FileType.PNG); - - // THEN - expect(filename).not.toBeNull(); - await sleep(1000); - expect(existsSync(filename)).toBeTruthy(); + SUT.capture("asdf", FileType.PNG).then(filename => { + // THEN + expect(filename).not.toBeNull(); + sleep(1000).then(() => { + expect(existsSync(filename)).toBeTruthy(); + }); + }); }); - it("should capture the screen and save to JPG", async () => { + it("should capture the screen and save to JPG", () => { // GIVEN const visionAdapter = new VisionAdapter(); const SUT = new Screen(visionAdapter); // WHEN - const filename = await SUT.capture("asdf.txt", FileType.JPG); - - // THEN - expect(filename).not.toBeNull(); - await sleep(1000); - expect(existsSync(filename)).toBeTruthy(); + SUT.capture("asdf", FileType.JPG).then(filename => { + // THEN + expect(filename).not.toBeNull(); + sleep(1000).then(() => { + expect(existsSync(filename)).toBeTruthy(); + }); + }); }); - it("should capture the screen and save file with prefix", async () => { + it("should capture the screen and save file with prefix", () => { // GIVEN const visionAdapter = new VisionAdapter(); const SUT = new Screen(visionAdapter); const prefix = "foo_"; // WHEN - const filename = await SUT.capture("asdf.txt", FileType.JPG, "./", prefix); - - // THEN - expect(filename.includes(prefix)).toBeTruthy(); - expect(filename).not.toBeNull(); - await sleep(1000); - expect(existsSync(filename)).toBeTruthy(); + SUT.capture("asdf", FileType.JPG, "./", prefix).then(filename => { + // THEN + expect(filename.includes(prefix)).toBeTruthy(); + expect(filename).not.toBeNull(); + sleep(1000).then(() => { + expect(existsSync(filename)).toBeTruthy(); + }); + }); }); - it("should capture the screen and save file with postfix", async () => { + it("should capture the screen and save file with postfix", () => { // GIVEN const visionAdapter = new VisionAdapter(); const SUT = new Screen(visionAdapter); const postfix = "_bar"; // WHEN - const filename = await SUT.capture("asdf.txt", FileType.JPG, "./", "", postfix); - - // THEN - expect(filename.includes(postfix)).toBeTruthy(); - expect(filename).not.toBeNull(); - await sleep(1000); - expect(existsSync(filename)).toBeTruthy(); + SUT.capture("asdf", FileType.JPG, "./", "", postfix).then(filename => { + // THEN + expect(filename.includes(postfix)).toBeTruthy(); + expect(filename).not.toBeNull(); + sleep(1000).then(() => { + expect(existsSync(filename)).toBeTruthy(); + }); + }); }); - it("should capture the screen and save file with pre- and postfix", async () => { + it("should capture the screen and save file with pre- and postfix", () => { // GIVEN const visionAdapter = new VisionAdapter(); const SUT = new Screen(visionAdapter); @@ -74,12 +78,13 @@ describe("Screen.", () => { const postfix = "_bar"; // WHEN - const output = await SUT.capture("asdf", FileType.JPG, "./", prefix, postfix); - - // THEN - expect(output.includes(`${prefix}${filename}${postfix}`)).toBeTruthy(); - expect(output).not.toBeNull(); - await sleep(1000); - expect(existsSync(output)).toBeTruthy(); + SUT.capture("asdf", FileType.JPG, "./", prefix, postfix).then(output => { + // THEN + expect(output.includes(`${prefix}${filename}${postfix}`)).toBeTruthy(); + expect(output).not.toBeNull(); + sleep(1000).then(() => { + expect(existsSync(output)).toBeTruthy(); + }); + }); }); }); From d89171032074c7a0a0eb74e4a4caa3813e256ad7 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 19:27:42 +0100 Subject: [PATCH 18/25] Updated e2e test assets --- demo/assets/docker.png | Bin 5016 -> 0 bytes demo/assets/gitlens.png | Bin 5849 -> 0 bytes demo/clipboard.js | 9 --------- demo/mouse.js | 31 ------------------------------- e2e/assets/calculator.png | Bin 0 -> 11526 bytes e2e/assets/close.png | Bin 0 -> 270 bytes e2e/assets/desktop.png | Bin 0 -> 16257 bytes e2e/assets/menu.png | Bin 0 -> 2724 bytes e2e/assets/mouse.png | Bin 0 -> 13607 bytes e2e/assets/one.png | Bin 0 -> 491 bytes e2e/assets/plus.png | Bin 0 -> 465 bytes e2e/assets/result.png | Bin 0 -> 1135 bytes e2e/assets/terminal.png | Bin 0 -> 545 bytes e2e/assets/xfce-menu.png | Bin 0 -> 2857 bytes e2e/assets/zero.png | Bin 0 -> 598 bytes 15 files changed, 40 deletions(-) delete mode 100644 demo/assets/docker.png delete mode 100644 demo/assets/gitlens.png delete mode 100755 demo/clipboard.js delete mode 100755 demo/mouse.js create mode 100644 e2e/assets/calculator.png create mode 100644 e2e/assets/close.png create mode 100644 e2e/assets/desktop.png create mode 100644 e2e/assets/menu.png create mode 100644 e2e/assets/mouse.png create mode 100644 e2e/assets/one.png create mode 100644 e2e/assets/plus.png create mode 100644 e2e/assets/result.png create mode 100644 e2e/assets/terminal.png create mode 100644 e2e/assets/xfce-menu.png create mode 100644 e2e/assets/zero.png diff --git a/demo/assets/docker.png b/demo/assets/docker.png deleted file mode 100644 index a984b6c97fff6b1b1581b42c7ab51a3d2d0686a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5016 zcmbVPXE>bQ)*fc`P7r;FUZWd5jG8Ek-g{@18I0(ih~6R$5rl{m5iQyfoe(u@h#rg< zHQJH)yx%$Rb)A3TzOJ>`diJ{Swf0_n?H^CPuC^KpAw3}g03gv&hd#O0mbc=Fk9#{S zU2s+b0K}Ru%F4PL%F19}A5TXYcLxAKJwDS2PhYQ}KHuz#hI2T+Izemv*t-mJQxMkM zh{O~SrRH;j2VF`0@0Mm&Kois!)ZU|$)Z`4dLJ7A10%X3AO-yKsB=o-*hgIdDeh;{T zz&8dJZh}Jl=bJuC{;kw{JcRw0QYU6w z5f>O`T;4U~YF^%z<7!^=K|^y%v4sdAlGvN>0DQH8eO#dwBC$H!Mo{w(3eEz&QjU>| z6Ivz!Cq*FjL#`1VF@9*)UqtykpjUP1dDscM6%z zv@@HDeuRjVaYJs?cv0pHT<>ajQ3+Dp;JC$SIJ|*zkIU65GAruUw9b70)qNqO~9K^uwkzM^TNec^oV6#o-JABAHet zR|G0B5wp*sdhDyD2kpEx93|y;J!R3$8OCvStd0Y4s-j7W7g{xOR5JGW^w_yq8p5Zo zxZ{Zpe%a~O+EWnF2b#16aa+09s1GGhE^T2yev%R6L|ah$Y!QE%rZ5U6+jTEP=Q-Vg z3YeJ4Xd}sjQZr5b+}2_&;w$LOJndKuGEq*OdR>M0*pNJTfQU*Qe((yr5j=T`toR6) z*I?qx&-u(iTb+a_ge@Ef>;w>TTMvT9ACQv!A4!~cT5YA`qk$qRBvELUBD$BU<@Bj& zCpK=}&F;@&lQ5*$SZ5~9{3EaPXMjZZy>9qSQ=Jl1k z4idV_E(sa#4Zcl3Hs|4X0C7Yu?;k(%;PR-pp>fb^uSk)e8v60cCq}L9 zWaRwy81}SUs7Jg&&xuWGjoq}#4*3+Z@$};goaQhl!{r|aN3pKdBmoa~yVHpRx)#q? zT!MJ{c>F!QFy2?MnEA+Qcuv*OIf5t-DyIZOWB0~iL?-40p-0?V&F>iI>oON9jwO!M z-u{*c55Wt3Iq(4ZtE8l)%)cuV-K|pecxbXDjj!z^VM4(4^2bmX8H=7Cjd3 znIU{1ZwigIzCzma0DzD6!9+h;T+^!3|MkSBJzl)YYsWbI1JC=sB zNQyf&f;$D$$5xDO60LtPH}&Z%?JB^B7?OZsYe>0JCp*LrNVerB5m)@8D}x~3O87A9 zEJlEea4Zu2YWwkyMT}vg@222K0=bxcwdz8PO}&pSz!x+C!}1<#Cg%pXlll2u9cu5TzN99XGSYB`<$1c5S;ep(;o%+ zhzOpJoF$zlN>0iT1fm2EQJS3+ogtkXXA-_tmQ?Xj&e8l$;9`%MEvdJJH;*^aTe2o` zS|dn(hbvXRhu!H3m?x?09(Brq`nE>1x|&9|#zJv}y}$>Y85H9KZLWuX9IKj#+J_W} z4u^J!0F`XphXcPOtg!{9wy)kV2(3VYUiV>|DOWt}Y6gf9bj1~uC6fAebz6!BAM*b*1V_l6zzS}vF>m7tg^bY&ku!hnUnN8@q6pHI43?QS0njhW0rPKa(dDG zl?+H`$g2$AxTTIb@*VP>Uqbd1_#XODLMEjw5UQwFRQE7Lo{SoW>UmluO@|;5NSt5|K|GWNYC_h4VGG;p`XG9=B?(x%o{#^_Z#IYSZS`{0u?)24jE9oO92Fe)BMFk7YMlcK;qOjdYs?m>|U7K5*c*5Gk zA6`ryY@T_q7$vt;xiRp?dn5t9=Nl)z{Z}w6PF*Z{ih1M;g^ry?poS<2K`9ko{5YjQ zXPY*mmT5jhW`@-ybw2-fx(K91eof2Oc&mJ(D&CHB7=@Jo!mgD!m8Pw!qp_IvU4bWP zY*u3-y_GXtt4+Q;L~}HwR!{5Ax|W=*mJ_|_Y#XtXs%y{ibFvmGOQvdt^jwqNncj{4 zZwCd0N+36oT&Lm>-XAL!=n4Z9oe#iTBd6222$js&mcnZ00wMWSnYBC{S}^n7llhL8 ziI#=))ywCXK+0f^s?{#Uub(R8G9|-fA}-&EZ|K~dj{09a%&o=+J!>gJ1DL0UxEb#( z^6b*$QcvA!L*J~4W_Zuj`r5SKk)07Ch3W)Pr=>Fbs?%Sgu_&8|qAlXKC7BX%d zRD<;HrA+47&JNAav*Jp2y!HC>Q-O${MuEnR9 zx7DEg9di|P`zIF?H?8xRMsB5*a%MkGnp~KCQMMLF29FE|pXMI(O@)@x7+Ad{sGPBI zGi@$D`GVUKGsvJUApsMa)35n?mAuU22}_!v*LN~9YKm?w@fs|uI7eDkD~?|zT&DVk5u(H3tlmvz#kSpTv=ZjTA&U@Gk51Jg!Z4U z{rD35DzPdr$dcq6uTs_uUw)2> z&1NZN=8+RYemrvy&HY$;YJ5@?iy5EwWGO&iZp9ODNo%VX$ijJ-Cl1DU#??kZ`4Gg^ z%}zMHZR6!gV1ehSC10BxPs?`9-u|xhr%iaxTH0dC)Nl<-O%TsY-j8Ev;O)ElcN^8+ zmfJ1)L09XE{gR(xgfRK0O#kikz36tbc}uTYuhPq^-Gza`H>X?IYiHF97T+ym_hJ{? z_rV7pnApo$otu=KgTm$`imS(Kb_u=5I`ajLTk)GsM;pZo%>|kTq(@m-C8tIh(O9SU zYo^1~=(hOah1<@+v*HhSx%9c<8!^IM9bBDSZnQHa^{%JRFiHMxd)ny1IT!xpKIOqfn;OjWR+B{+-R%0tLUz7ZJK|dND+PT&I zO0xyaISO^yIP3znCUf`mDCZ;4Wu8n|0&M*do)=>qIrK7uk1i#~?)!P|m(T%<4FU24 zxOjLH#H1nfgpsW{igU!rS5J7LNXfHNy?8;<1e&nw)kOqZXffdwmG14&1%a2k2^;{R z;rJt18c*2w0RXH#7ky)dvDPDLJ5LWm8+%V%2SKEV*DV?VkVQ)0njQ`a8!*zt9R`<1 z%CY^0kiND5EDN!L|AHXgtD(LCsBqR)hK!om#2#JUY+#&?v0WgFOQUC_O_wOM87YFJ9xASrF zLb!Osz<=V}*n0XRK|3hrpH*pH z7o>x`G1SGw0S3R#ArBFg{R{p-j{he72hrreMB)1)|78Bd^EXpg=+FNDah`t{>#x<@ zYRMDI3jL?@@`N3qc%ZkJ!RP|j(ZAK$e{SY>h~5hK-}=_ZmgF68o4wUQ4d?@XB-YMs zs|WUjJD??hIyySmloU!zRyL5BqN*zG5f-%~wY?%vhGLJEA}+;=OhAgS8+)WL+|9+X z6Btla`cpC-_+nn#y`XWFH97(bc) zypfIiIZVX4F(=6CtEbX_M5vD9!!Lob(Cc!?T9@m-q%|Lxiz|5YyP4Tz3i*NEW<)^*01j$;n*`?jKsTbGelNT!q5vOvtvdpczbT%@Uu}c`vDtvrpbmSg@=oK-rWg@pAk+ z<_mTE+FIZCuGC1OwAtOS3&SV2?CPiM&wej`xvbtRNrr^LVC~@9MZuXx>L*z3_=J zGCL)@uEA7*&pQp#UZTN=bmksZU3}ftqk%A!(f>x;W?5}!gHqM@M9oIkF<@BI$Z#Q(Y+AZ$<$4+ZF~I(l z)M(4Fv+q_hlWc~6b91;A9)i*A1+OZ)84_6%mh?p&n>oS~^0XT+O+<~T=)a3R`|VoC zDt1|WJF~-itiw(@B?j{n)r}fj4()_aP$hIjr5NkC)D+NtQWQC0O%r~a z&?^}bo%?}8|HIt_iM|kfJMOS%oYzp_Ue0gEEk$owB+z=?cLe7!C!e#{uGf%0P4f=z zi_KQ!WaB9oB%?7RNL(Fgm^#0iY$O+(B72rVeg_o=m~xP2WGNn>Jl-L}X&(xT>-x|w zie$rv+RiM~$x>jk)wmxJ=f?q3jqCr1j(^G0@bQR!4ydb%7 diff --git a/demo/assets/gitlens.png b/demo/assets/gitlens.png deleted file mode 100644 index e7bf7e833af2c6fa73be5795b79e6f3b4ede9da5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5849 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 literal 0 HcmV?d00001 diff --git a/e2e/assets/one.png b/e2e/assets/one.png new file mode 100644 index 0000000000000000000000000000000000000000..666fd83eaa49b0069b59c06c5a389985c9e85c28 GIT binary patch literal 491 zcmV0eyK*v_>B9@>ch$5op1}F!hp@g$=3JNYk$ql$c3Y03n zQz57jM1URQEzE{!5n?wnGH72Df1=UTWHhmiR;v}fH`unoa~%CpN^Q5>-ENmof7Ata@Yq9{p{Znq1C;%2iM3Qgx!6#8!c9>rrIfO$Ql@O;Jlgmx zLI}<|=UfOe91g47-Qhfc<##L=i!clujmCPtHmi7R-Krj=(P%cCjmP8qp)`e2_b2k zzDX7_#%Y=oLiF^i=y_fo$DK}xQfki)003hQ0C609o~Ku?ioWl2&Z8(2LRho=hEm#Y hw|(E&Q}q6~5nshLWy})-B0^2moWO)oOJ* z9YP2midmL%&d1}i>$+C;KnM{+#BrQuS-;=MLvg>~PbL%2d7kG|N~@Bflnw@i)oP^` zsjdnkJkL9y&({3_NGUzf6GG@FtM=V)HycVXcq%HTlu{N|s#HzbZyn8n8qAVX?shwa zftshHs!g8fv)QbEj^-g|axLoDYlc*#G$z-gLB%TU^&_uXuh(gs0w~K;DYaNEbbUA+ zjz**U`35H1_x*Oe4d8OQ5JL1l0M~W@JfemtI*OtwiU6EWr{!`vola{8{@??)i^+5G zO_&@--}mS9d7}@VH}U@&VS>-uE}ZkCC>k<~l+vOoIOn=~R}6w6Ns?Z#=Qxf%HvpiN z0!Wf12m)QXD~4gX-EQMJF3ZxI-8YWobi3U!40V$<|5yJDn*(64u7iX?00000NkvXX Hu0mjfI&{)i literal 0 HcmV?d00001 diff --git a/e2e/assets/result.png b/e2e/assets/result.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec3abfb27238d1d92fab0e6b5db81e31e754e4a GIT binary patch literal 1135 zcmV-#1d#iQP)H2r;Ww3&B1XEm{;s^dWuC zqJO|mBm@$rL==gXAcT;h5p4{DpfoK*!XmPLDD?RF2moNS*>!bwLZOhD@bK{P`T03nxz^U!Un$N41VIc2!{XxN+uIxN z69hp+LqjNcyWL}BV|RCV#0<5ywOXx~$Kxd$ySlpEZg;YxUavP*?;r@8o0}sF0sth= z1cqT!K>z@k%hlW4OPV1ClJ?GMG+M1zlvh_*Ll7ho2mk=r*VlV{dj$mrIRE2#l;p8$YhFlaWL`}+EbB^nwU%F4>{f-*A5HO1rcg@px_^LRY7*_@r7 zjSg8XmRKxKbmnroo12>wi3GD$R#v{gzAi5>qr=nFQ_?Cbm8!F|lV~T`!{MW&qevveWHR}Der9H7Dow}7#~2R= zgG#0H{QMk25Gs`_lgTC~CMqf_NCPqWd_IgzrBYHKjYfm@eB+ML?RIYKwe(n($W&qt+=?j zsi}#}UK@hE0tJmw%p-?C^ z7z`{Hi!}MSAYUiBT#l9ZdcBxEkylk!p(GxULlA@sYHMpV8jZ;WIh{_6#e%!g>~?!7 z6he7^ety#XPNUJRuCAhdXlO{GP@J8e&CbroVleqttHm}MmJS6B!?;w$R{#vd7K?>gR4SFK)#{{oFqKMOTU+bz@2Amdm@z#)y``mP zYio;i^ZpL%>+5@ZdN>>o&R$ehG&MD~zP_H5lauPLf+8M|`~7|xhG{e!pUHkg* z4)^!>H#axoaF{}&a5$XApYeN5|2=-<+xI7G`Wr~D_w6V3SZx3R002ovPDHLkV1mXb B4Q2oU literal 0 HcmV?d00001 diff --git a/e2e/assets/terminal.png b/e2e/assets/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..06795f61794d6787b1b41614e319e3876d8462e0 GIT binary patch literal 545 zcmV++0^a?JP)P000^Y0ssI2%^zTz00003b3#c}2nYz< z;ZNWI00G%aL_t(Ijonl|s=`1J-k*TF#?Hdl19%AW0!Gk6#l|~$0t;IqcmWF`1U-mg z;RQr&6a=jVbvN^h^^Kb~FFxT_Z;CLR$$T^4w=VN6DP? zX0zGtb{|+#6cIv#AZWE(rBX@1rIb=iwS$?+006XqI2?i?Xt&$3zNC}@FdPmM%dAf+ zwWQF;e!qXe-!bG^)ym~EVp)hL3IJ?28}xOEVZ%`rX}?~t7mGzHW%Oc7Df9tA>jU5B zm}e=a@B6OnRw|V+4A<*5V=SdLZ5rXp5ucaKC6~*M$K&mGo6qMHWqQ4e1ddwH<#IV1 zjcT=;u4x(=X3Fy5XlXy0OmufjDWw$W{FS3g(CjOQMF<%T2Axi4Hk+N#XV-NTx8f(_ zG3^;+*Xz~y{cJWXgt*;qi^T$SJkQHyGVis=3Y>Exgq|#=RJB^gXrWNBmMod0IV^e( zv?GMTOvad17`1+iEaCU`@36iAF`fWCu|s=A00000NkvXXu0mjfYNh;1 literal 0 HcmV?d00001 diff --git a/e2e/assets/xfce-menu.png b/e2e/assets/xfce-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..ae098f123b0ab62a4a3913a9f1b03ef7d64bd24f GIT binary patch literal 2857 zcmZWr3p`Zo7T=^yQqd99<1i*kVP;GcbBs3`$4E?Gh308yWQLi+q;N=`aMbn4V@QX| zDe=593f>!<-1@Fn_WM1#WJpV9LjU00C4U5ylTV z&EjJCSoj()27F&-BjK<$6`ns9?tyoPS+hA**dfFr1PX4Z05j!KXc!k8yYGv^85U0G z@d7bOWN2t8BJ?1F&GADTn3$L#QD`I@tq*GGbI-7NM7}RZwwnMm&{=V@)&Fu zY!#D8Vh8iEa5yN3eFx_;X#b$IxZm9e1A$zXAPo>G@oWn9^moTV&@~=7MXm-D`8}FoT97~T0#1HpmdXOt$pQ0Ll336M05VYwYinn& z%MmLW&eqztfV=5wZ+NCAB%BD?>ZEkdDlJF11S6T_jA_98r zG7bxAP0|M$hHnp?u#HXd-LxWG{mg4WeDAJZ{-pEST)%uf^hn63`R<7aBfN=weG2<# zQoP5`6ENfpvJn&AOVKq8I}RV`kKVvb0=T>|jJ@aLU7=NDruy;XrF)Sjh@F+eg@wxM zZFt>1rkcA?zDSR&xsW*%qq^N}`={!`=qEJ}S5)R~gX$jn#+3xp6;CES>77GfULs+M zc`-vnycor-GSMaD?VcUEFPTIaCF0&4`wgGz!Tl1b zTfeDT9`w|UYmJP9j9ErAHHq{S)}q(LwGy_t;A8gU;=odE@9@L0%&EnpS#Fv6V0Puy z=iU+SOYo{oZ>AhLa6r~z<^AJt0WtTz_tKfLhmXkFUS3{~+CRkvHklb; zPD@GIZNi}-E;L?3Cug(#{auSY&>4!rZ$#)+T2wwmkS_z6U2mZqHkmHhH{K}NAGZ@c zBXl}MN&^7SLEz7dilp4aNJr8ig^$Q;I&rxS3>F*SS?Z1SeK^fGHC{OZFJQc5R$WZ^ zTvAfvsvEQ$sjr`q`kFiPa%hcg%O~R1kXcUq?$e%L++0*tlvtb-Kt@>+a}%eeMwzcF`M(Nbw!Y(sxwmgyPJ%!dx(x7ym;>FMd&iT7ekMMVW#*p{A{ z*w)jdpJ;#DsB278aKE;8VPV0}&dvtjc2(ECbz2*=>cSe)W2oX(Pd(Kl0<-e%&6_u? z+3&Xitz*2No*sw1_8|@~uf3_MsiC0(GVbE;F0yTJ6CUwrGC@CO04#-kv*AU_!69TBn8`{1k$!0xSU8{>t3>b5jmSel=D zk$E_A*B^Gm9#(zOz(orfYG*VrxX&pIA}9O%mY+Y2kL&5^q+=r3?1>p^=LM_& zV)ru8nrc>0+`!z*@?zV{c_kwwBf$$=g5ALfPN01#XgcZm@$D|qs2jIquHI;)gFB0C z*pU7qaoW_EF9&pWWdN`gK*!NgMIF=I0ox7g*B^#x;w4p8RbZ$(IyzdivFmOXZqc;a zZ2XB))72x9Bxh#&S9z7V6=+%@!6gB}y_2kR4|Vg1?$@t3XpT#zna2w3wUR1Nk=Sxc zPoCH&Nyc_Vp>HbvwjNMbQ;VGc(kPwDC0#0k?=d_|h8mffu~5($s~mf+of;aEbDuRO zwAoKR&r8DW>U@xw2f!2K$E*OW>3B5alOm~nu0EPyclWNbwsKQr<8qI3?EIHP17^tA z@wbm3Kd$ocbkN!sWzjb^PkWVd_3CjSAG0bmSsbw+-aIm;EcbZul*&5$Bu5-h#`W~} z9mFq&S46+s+do1nK1Idlewmue*sv{D?skM#Ms`Yy3Z#E>K=f2Sy+Hj0?TUCPZ1HQ! z+tYSu!}$Yk>989IIRidH%DP;+y$if#C}6>mh^I^bdW;)aO%T{g{b zIh|Cw%LCAhmXM&`M=4PaLERFt_vpHp)&)ydE7s#B8s-s$5rTLi8U~AD)$9WLc$i-> zn7h*oaBNP$JeCzGbr#t4GC#9sMP-?moEmIt*G#bs{U)SL>7%_2kv!%}! z)ts|}YZna^2PXN?gRbB64Kh!;h6x7ySz2nU_P%|K=gjh4iaMpjv&}T2vrb%md~tE{ zc7^q}$E2NQ6Jui;>TGL! z{O~t?%bPcE`uhHK)Fz|fXQ53^$7dHM?d`)XTzQVpvyUNS3R>m5-~L!FoZ{2mq;%`_ zZVB|_{PM~=`7O8o-{3P!OifLfj$~NFl=Qsr&_giafFi=q$(BvZ7D^4#>o?`IpL)B1 zWN34N*e(H^zMU{pT#tZ6I~R9wwRDY0Bv-UOgnq>U=N-0fEpX)adum1XQTcH|z P^$!ts`Ebt?KlvBNHW literal 0 HcmV?d00001 diff --git a/e2e/assets/zero.png b/e2e/assets/zero.png new file mode 100644 index 0000000000000000000000000000000000000000..1f468065716627e85a0b7272d5f07e1b4ab1ae29 GIT binary patch literal 598 zcmV-c0;&CpP)v!16@YT_N`jD zY0)}dNvlF5h@yprAWk}GVaMa*91i6C_#e)*k(q&)2fxpmk=gI}@V(*U2O;Eszq_vc zdcE=$0sxNV%H^`6C=A0uqUbmd&+~)9KorGX^?+d*jIn8&j^i|&O-K}Px7%nm;(7l0 zd`3}}t0b^2+v#)+!-y5xcot(UNs{mTx%&Y?6h)FGVT|J;mtG6QFb}1_@Jo>pLI}xG zB~99d`_sY)oX_XoZWjbWx7*cqJxf#?mR8W|bXqJH0H7$!a=A1NgH|%NLa*2Be!oAN zOaMTZ<<)9691eM&|12$S!lq|GCJe*F;n3^#;-RkVzV9E8$1ItN7@b~>k0n`_;{=3| zAPA4gBV%*N(CNi^w@Q~4Aw=serPGUoAOL{pc}arjd7>zO97w;=g+ifHso1vNYPA61 zdc9(d8;u6#LT71hLdak+*lxF;=Y?Uo*=*YFwxTFm0uwRrcix{c9*-}V%X~gZ2o;OP z*=$BDncBX{aolt|bzL_If@-zOFie&-`n{M?DwSwOCH!aCh%bWLHR9`dzeS$s(;IKT zuq^9&UUF8w6;)NWEUR9xBZTsE0{~!I762^EQdKpcc`Is~X4|%Dnn4icX7>|>P_0(e kG%X%7-~U(tANX8;09~Q?>OhsX_W%F@07*qoM6N<$g5p6Gp#T5? literal 0 HcmV?d00001 From 83fb108db06ae566ed298764c56784ea0be05d98 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 19:28:18 +0100 Subject: [PATCH 19/25] Updated Screen.find signature --- lib/assert.class.spec.ts | 47 ++++++++++++++++++++------ lib/assert.class.ts | 10 +++--- lib/expect/matchers/toShow.function.ts | 2 +- lib/screen.class.spec.ts | 10 +++--- lib/screen.class.ts | 2 +- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/assert.class.spec.ts b/lib/assert.class.spec.ts index 17c38ad5..3a022346 100644 --- a/lib/assert.class.spec.ts +++ b/lib/assert.class.spec.ts @@ -9,46 +9,71 @@ jest.mock("./screen.class"); describe("Assert", () => { it("isVisible should not throw if a match is found.", async () => { - Screen.prototype.findOnScreen = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); + // GIVEN + Screen.prototype.find = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); + const needle = "foo"; - await expect(SUT.isVisible("foo")).resolves.not.toThrowError(); + // WHEN + + // THEN + await expect(SUT.isVisible(needle)).resolves.not.toThrowError(); }); it("isVisible should throw if a match is found.", async () => { - Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); + // GIVEN + Screen.prototype.find = jest.fn(() => Promise.reject("foo")); const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); + const needle = "foo"; + + // WHEN - await expect(SUT.isVisible("foo")).rejects.toThrowError("Element not found"); + // THEN + await expect(SUT.isVisible(needle)).rejects.toThrowError(`Element '${needle}' not found`); }); it("isVisible should throw if a match is found.", async () => { - Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); + // GIVEN + Screen.prototype.find = jest.fn(() => Promise.reject("foo")); const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); const searchRegion = new Region(10, 10, 10, 10); + const needle = "foo"; + + // WHEN + // THEN await expect(SUT - .isVisible("foo", searchRegion)) - .rejects.toThrowError(`Element not found in region ${searchRegion.toString()}` + .isVisible(needle, searchRegion)) + .rejects.toThrowError(`Element '${needle}' not found in region ${searchRegion.toString()}` ); }); it("isNotVisible should throw if a match is found.", async () => { - Screen.prototype.findOnScreen = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); + // GIVEN + Screen.prototype.find = jest.fn(() => Promise.resolve(new Region(0, 0, 100, 100))); const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); + const needle = "foo"; - await expect(SUT.notVisible("foo")).rejects.toThrowError("Element visible"); + // WHEN + + // THEN + await expect(SUT.notVisible(needle)).rejects.toThrowError(`'${needle}' is visible`); }); it("isVisible should throw if a match is found.", async () => { - Screen.prototype.findOnScreen = jest.fn(() => Promise.reject("foo")); + // GIVEN + Screen.prototype.find = jest.fn(() => Promise.reject("foo")); const screenMock = new Screen(new VisionAdapter()); const SUT = new Assert(screenMock); + const needle = "foo"; + + // WHEN - await expect(SUT.notVisible("foo")).resolves.not.toThrowError(); + // THEN + await expect(SUT.notVisible(needle)).resolves.not.toThrowError(); }); }); diff --git a/lib/assert.class.ts b/lib/assert.class.ts index 242f1663..14cb0cd2 100644 --- a/lib/assert.class.ts +++ b/lib/assert.class.ts @@ -7,30 +7,30 @@ export class Assert { public async isVisible(pathToNeedle: string, searchRegion?: Region, confidence?: number) { try { - await this.screen.findOnScreen( + await this.screen.find( pathToNeedle, {searchRegion, confidence} as LocationParameters, ); } catch (err) { if (searchRegion !== undefined) { throw new Error( - `Element not found in region ${searchRegion.toString()}`, + `Element '${pathToNeedle}' not found in region ${searchRegion.toString()}`, ); } else { - throw new Error("Element not found"); + throw new Error(`Element '${pathToNeedle}' not found`); } } } public async notVisible(pathToNeedle: string, searchRegion?: Region, confidence?: number) { try { - await this.screen.findOnScreen( + await this.screen.find( pathToNeedle, {searchRegion, confidence} as LocationParameters, ); } catch (err) { return; } - throw new Error("Element visible"); + throw new Error(`'${pathToNeedle}' is visible`); } } diff --git a/lib/expect/matchers/toShow.function.ts b/lib/expect/matchers/toShow.function.ts index e459b331..d50da7f4 100644 --- a/lib/expect/matchers/toShow.function.ts +++ b/lib/expect/matchers/toShow.function.ts @@ -12,7 +12,7 @@ export const toShow = async ( locationParams.confidence = confidence; } try { - await received.findOnScreen(needle, locationParams); + await received.find(needle, locationParams); return { message: () => `Expected screen to not show ${needle}`, pass: true, diff --git a/lib/screen.class.spec.ts b/lib/screen.class.spec.ts index ef8a8777..99382af9 100644 --- a/lib/screen.class.spec.ts +++ b/lib/screen.class.spec.ts @@ -33,7 +33,7 @@ describe("Screen.", () => { const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; - await expect(SUT.findOnScreen(imagePath)).resolves.toEqual(matchResult.location); + await expect(SUT.find(imagePath)).resolves.toEqual(matchResult.location); const matchRequest = new MatchRequest( expect.any(Image), imagePath, @@ -54,7 +54,7 @@ describe("Screen.", () => { const SUT = new Screen(visionAdapterMock); const imagePath = "test/path/to/image.png"; - await expect(SUT.findOnScreen(imagePath)) + await expect(SUT.find(imagePath)) .rejects .toEqual(`No match for ${imagePath}. Required: ${SUT.config.confidence}, given: ${matchResult.confidence}`); }); @@ -73,7 +73,7 @@ describe("Screen.", () => { const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(undefined, minMatch); - await expect(SUT.findOnScreen(imagePath, parameters)).resolves.toEqual(matchResult.location); + await expect(SUT.find(imagePath, parameters)).resolves.toEqual(matchResult.location); const matchRequest = new MatchRequest( expect.any(Image), imagePath, @@ -97,7 +97,7 @@ describe("Screen.", () => { const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(customSearchRegion); - await expect(SUT.findOnScreen(imagePath, parameters)).resolves.toEqual(matchResult.location); + await expect(SUT.find(imagePath, parameters)).resolves.toEqual(matchResult.location); const matchRequest = new MatchRequest( expect.any(Image), imagePath, @@ -122,7 +122,7 @@ describe("Screen.", () => { const imagePath = "test/path/to/image.png"; const parameters = new LocationParameters(customSearchRegion, minMatch); - await expect(SUT.findOnScreen(imagePath, parameters)).resolves.toEqual(matchResult.location); + await expect(SUT.find(imagePath, parameters)).resolves.toEqual(matchResult.location); const matchRequest = new MatchRequest( expect.any(Image), imagePath, diff --git a/lib/screen.class.ts b/lib/screen.class.ts index c1769e95..32ffb7e8 100644 --- a/lib/screen.class.ts +++ b/lib/screen.class.ts @@ -24,7 +24,7 @@ export class Screen { return this.vision.screenHeight(); } - public async findOnScreen( + public async find( pathToNeedle: string, params?: LocationParameters, ): Promise { From dd3e05a691e0df88be2c3fe414e32d783f3b3afa Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 19:28:42 +0100 Subject: [PATCH 20/25] Updated Jest config to include index e2e test --- jest.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 5d8459f7..0bf0786d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,6 @@ module.exports = { preset: "ts-jest", testEnvironment: "node", - roots: ["lib"], collectCoverageFrom: [ "index.ts", "lib/**/*.ts", @@ -9,6 +8,10 @@ module.exports = { "!/node_modules/", "!/path/to/dir/" ], + testPathIgnorePatterns: [ + "/node_modules/", + "/dist/" + ], testMatch: process.env.E2E_TEST ? [ "**/__tests__/?(e2e)/**/*.[jt]s?(x)", "**/?(*.)?(e2e.)+(spec|test).[jt]s?(x)" ] : [ "**/__tests__/!(e2e)/**/*.[jt]s?(x)", "**/!(*.e2e.*)+(spec|test).[jt]s?(x)" ] From 2f45497b8e06b3dca03e351cbc9b5eeb8f87225b Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 19:29:01 +0100 Subject: [PATCH 21/25] Added e2e test suits --- index.e2e.spec.ts | 50 ++++++++++++++++++++++++++++++++++ lib/keyboard.class.e2e.spec.ts | 33 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 index.e2e.spec.ts create mode 100644 lib/keyboard.class.e2e.spec.ts diff --git a/index.e2e.spec.ts b/index.e2e.spec.ts new file mode 100644 index 00000000..2bf0937a --- /dev/null +++ b/index.e2e.spec.ts @@ -0,0 +1,50 @@ +import { assert, Key, keyboard, Location, mouse, movement, screen } from "./index"; + +const openXfceMenu = async () => { + const menu = await screen.find("menu.png"); + await mouse.move(await movement.straightTo(Location.centerOf(menu))); + await mouse.leftClick(); + await mouse.leftClick(); +}; + +const run = async (cmd: string) => { + await keyboard.type(Key.LeftAlt, Key.F2); + await keyboard.type(cmd); + await keyboard.type(Key.Enter); +}; + +const calculate = async () => { + const plus = await screen.find("plus.png"); + await mouse.move(await movement.straightTo(Location.centerOf(plus))); + await mouse.leftClick(); + const one = await screen.find("one.png"); + await mouse.move(await movement.straightTo(Location.centerOf(one))); + await mouse.leftClick(); + const zero = await screen.find("zero.png"); + await mouse.move(await movement.straightTo(Location.centerOf(zero))); + await mouse.leftClick(); + await mouse.leftClick(); + await keyboard.type(Key.Enter); +}; + +const close = async () => { + const x = await screen.find("close.png"); + await mouse.move(await movement.straightTo(Location.centerOf(x))); + await mouse.leftClick(); +}; + +describe("E2E demo", () => { + it("should run without throwing", async () => { + jest.setTimeout(30000); + screen.config.resourceDirectory = "./e2e/assets"; + await assert.isVisible("mouse.png"); + await assert.isVisible("desktop.png"); + await openXfceMenu(); + await run("gnome-calculator"); + await assert.isVisible("calculator.png"); + await keyboard.type("525"); + await calculate(); + await assert.isVisible("result.png"); + await close(); + }); +}); diff --git a/lib/keyboard.class.e2e.spec.ts b/lib/keyboard.class.e2e.spec.ts new file mode 100644 index 00000000..3cb82a99 --- /dev/null +++ b/lib/keyboard.class.e2e.spec.ts @@ -0,0 +1,33 @@ +import { jestMatchers, Key, keyboard, screen } from "../index"; + +expect.extend(jestMatchers); + +const run = async (cmd: string) => { + await keyboard.type(Key.LeftAlt, Key.F2); + await keyboard.type(cmd); + await keyboard.type(Key.Enter); +}; + +const confirm = async () => { + await keyboard.type(Key.Enter); +}; + +const close = async () => { + await keyboard.type(Key.LeftAlt, Key.F4); +}; + +describe("Keyboard e2e class", () => { + it("should paste copied input from system clipboard.", async () => { + // GIVEN + jest.setTimeout(30000); + screen.config.resourceDirectory = "./e2e/assets"; + await run("gnome-calculator"); + await confirm(); + + // WHEN + + // THEN + await expect(screen).toShow("calculator.png"); + await close(); + }); +}); From 1dfd8967a2bd3ffbfffdfb054f5c083e8b6aaeef Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Tue, 5 Mar 2019 20:04:36 +0100 Subject: [PATCH 22/25] Updated e2e test image --- e2e/assets/calculator.png | Bin 11526 -> 463 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/e2e/assets/calculator.png b/e2e/assets/calculator.png index ade6f55868712a549ef673236ff6c19b45db371f..8f6cf3cb186e256953d148ed76ee928e0c82ffc8 100644 GIT binary patch literal 463 zcmV;=0WkiFP);@^AVf%~g_-QmD;9!8-)_Jt58j*VPiFYP%w*Vw)9J+CA74cD0Sx~DgMF-xTS(f!QE2Z4;_m1NLz)KiJv@B~d7{qa0NjZ*lJRb8rmr`=B zTUs-wC zybgwwDG>2?y9GfI1VNT%zVDY}I2`7Aj)+E+THQz~)we$tjSY>6Hk*y|tq6rtZ(hX+ zA;K^OfYoX>8jVW97~Ac3LI|UY`GnRC?YmT-RN%*FTj3K)>Gy0KE?! z4hKD^)9JKYElt7Yayg&RdXrlBO`4|q8e{yLOZp%45Z`D)(z0U_cqjk>002ovPDHLk FV1iu{&Efz6 literal 11526 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 Date: Thu, 7 Mar 2019 12:10:37 +0100 Subject: [PATCH 23/25] Updated versions, added version-bump-prompt --- package-lock.json | 3737 +++++++++++++++++++-------------------------- package.json | 14 +- 2 files changed, 1611 insertions(+), 2140 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2f2b74c0..a7e28464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,87 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/core": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", + "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.3.4", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.3.4", + "@babel/types": "^7.3.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helpers": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", + "dev": true, + "requires": { + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.3.0" + } + }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -24,6 +105,60 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, "@types/clipboardy": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@types/clipboardy/-/clipboardy-1.1.0.tgz", @@ -31,9 +166,18 @@ "dev": true }, "@types/jest": { - "version": "23.3.9", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.9.tgz", - "integrity": "sha512-wNMwXSUcwyYajtbayfPp55tSayuDVU6PfY5gzvRSj80UvxdXEJOVPnUVajaOp7NgXLm+1e2ZDLULmpsU9vDvQw==", + "version": "24.0.9", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.9.tgz", + "integrity": "sha512-k3OOeevcBYLR5pdsOv5g3OP94h3mrJmLPHFEPWgbbVy2tGv0TZ/TlygiC848ogXhK8NL0I5up7YYtwpCp8xCJA==", + "dev": true, + "requires": { + "@types/jest-diff": "*" + } + }, + "@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", "dev": true }, "@types/node": { @@ -49,9 +193,9 @@ "dev": true }, "acorn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.2.tgz", - "integrity": "sha512-GXmKIvbrN3TV7aVqAzVFaMW8F8wzVX7voEBRO3bDA64+EX37YSayggRJP5Xig6HYHBkWKpFg9W5gg6orklubhg==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, "acorn-globals": { @@ -62,18 +206,38 @@ "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + } } }, "acorn-walk": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.0.tgz", - "integrity": "sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "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" + } + }, "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-regex": { @@ -98,306 +262,15 @@ "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } } }, "append-transform": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { - "default-require-extensions": "^1.0.0" + "default-require-extensions": "^2.0.0" } }, "aproba": { @@ -429,13 +302,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -456,9 +326,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { @@ -476,6 +346,12 @@ "safer-buffer": "~2.1.0" } }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -489,12 +365,12 @@ "dev": true }, "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.10" + "lodash": "^4.17.11" } }, "async-limiter": { @@ -515,6 +391,12 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", @@ -574,225 +456,45 @@ } } }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "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.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "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-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.1.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" } }, "babel-plugin-istanbul": { - "version": "4.1.6", - "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", - "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz", + "integrity": "sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==", "dev": true, "requires": { - "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" + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.0.0", + "test-exclude": "^5.0.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-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "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-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" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "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" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "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-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "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.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.1.0" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -851,18 +553,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -871,7 +561,6 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -896,14 +585,32 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.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": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "browser-process-hrtime": { @@ -919,6 +626,14 @@ "dev": true, "requires": { "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } } }, "bs-logger": { @@ -985,20 +700,24 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", "dev": true }, "capture-exit": { @@ -1017,9 +736,9 @@ "dev": true }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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", @@ -1027,15 +746,21 @@ "supports-color": "^5.3.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" }, "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, "class-utils": { @@ -1058,15 +783,24 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "clipboardy": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", @@ -1140,9 +874,9 @@ "dev": true }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -1154,6 +888,12 @@ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", "dev": true }, + "compare-versions": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.4.0.tgz", + "integrity": "sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg==", + "dev": true + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -1186,12 +926,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1208,15 +942,15 @@ } }, "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": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", - "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.1.tgz", + "integrity": "sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==", "dev": true, "requires": { "cssom": "0.3.x" @@ -1229,14 +963,6 @@ "dev": true, "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "data-urls": { @@ -1263,6 +989,15 @@ } } }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -1295,12 +1030,12 @@ "dev": true }, "default-require-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { - "strip-bom": "^2.0.0" + "strip-bom": "^3.0.0" } }, "define-properties": { @@ -1350,18 +1085,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -1377,13 +1100,10 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true }, "detect-libc": { "version": "1.0.3", @@ -1402,6 +1122,12 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "diff-sequences": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.0.0.tgz", + "integrity": "sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw==", + "dev": true + }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -1416,7 +1142,6 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "optional": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -1440,16 +1165,17 @@ } }, "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, "requires": { - "es-to-primitive": "^1.1.1", + "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" } }, "es-to-primitive": { @@ -1470,9 +1196,9 @@ "dev": true }, "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", "dev": true, "requires": { "esprima": "^3.1.3", @@ -1525,13 +1251,13 @@ } }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.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", @@ -1540,15 +1266,36 @@ }, "dependencies": { "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "lru-cache": "^4.0.1", + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } } } }, @@ -1559,21 +1306,53 @@ "dev": true }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "expand-template": { @@ -1582,17 +1361,16 @@ "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" }, "expect": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-23.6.0.tgz", - "integrity": "sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.1.0.tgz", + "integrity": "sha512-lVcAPhaYkQcIyMS+F8RVwzbm1jro20IG8OkvxQ6f1JfqhVZyyudCwYogQ7wnktlf14iF3ii7ArIUO/mqvrW9Gw==", "dev": true, "requires": { "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" + "jest-get-type": "^24.0.0", + "jest-matcher-utils": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-regex-util": "^24.0.0" } }, "extend": { @@ -1622,13 +1400,80 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, "extsprintf": { @@ -1637,6 +1482,39 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "ez-spawn": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ez-spawn/-/ez-spawn-2.1.1.tgz", + "integrity": "sha512-fAi+/2QwSAQsUDqkSX+3P6NRsnOZUnCpHlH9zNf6CPFnXpGIiyQO+3w31nykHosMSldwrTubX9ijeSOXA+l5vA==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^6.0.5", + "string-argv": "^0.1.1", + "type-detect": "^4.0.8" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -1658,11 +1536,14 @@ "bser": "^2.0.0" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } }, "fileset": { "version": "2.0.3", @@ -1675,25 +1556,35 @@ } }, "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "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": "^2.0.0" + "locate-path": "^3.0.0" } }, "for-in": { @@ -1702,21 +1593,23 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -1738,9 +1631,9 @@ "dev": true }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { @@ -1757,8 +1650,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -1767,7 +1659,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, @@ -1779,21 +1671,19 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -1801,20 +1691,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1832,7 +1719,7 @@ } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -1881,7 +1768,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, @@ -1901,12 +1788,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -1931,8 +1818,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1944,7 +1830,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1959,7 +1844,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1967,21 +1851,19 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, @@ -1993,7 +1875,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2005,7 +1886,7 @@ "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.2.4", "bundled": true, "dev": true, "optional": true, @@ -2016,18 +1897,18 @@ } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.10.3", "bundled": true, "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -2044,13 +1925,13 @@ } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.5", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true, @@ -2074,8 +1955,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2087,7 +1967,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2127,12 +2006,12 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -2162,19 +2041,18 @@ } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -2189,7 +2067,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "dev": true, "optional": true @@ -2210,7 +2088,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2230,7 +2107,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2242,17 +2118,17 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, @@ -2263,25 +2139,23 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -2358,14 +2232,6 @@ "dev": true, "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "github-from-package": { @@ -2374,9 +2240,9 @@ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2387,29 +2253,16 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, "growly": { @@ -2419,9 +2272,9 @@ "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.5.0", @@ -2438,6 +2291,22 @@ } } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2482,14 +2351,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -2502,26 +2363,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -2533,16 +2374,6 @@ } } }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -2558,6 +2389,17 @@ "whatwg-encoding": "^1.0.1" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2568,12 +2410,12 @@ } }, "import-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { - "pkg-dir": "^2.0.0", + "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" } }, @@ -2603,6 +2445,44 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "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 + }, + "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" + } + } + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -2613,9 +2493,9 @@ } }, "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "is-accessor-descriptor": { @@ -2625,6 +2505,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-arrayish": { @@ -2639,15 +2530,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", @@ -2655,12 +2537,12 @@ "dev": true }, "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { - "ci-info": "^1.5.0" + "ci-info": "^2.0.0" } }, "is-data-descriptor": { @@ -2670,6 +2552,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-date-object": { @@ -2697,69 +2590,41 @@ } } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-generator-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", - "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.0.0.tgz", + "integrity": "sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g==", "dev": true }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-plain-object": { @@ -2769,26 +2634,12 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-regex": { @@ -2820,18 +2671,18 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2843,13 +2694,10 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -2858,346 +2706,360 @@ "dev": true }, "istanbul-api": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", - "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", - "dev": true, - "requires": { - "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", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz", + "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==", + "dev": true, + "requires": { + "async": "^2.6.1", + "compare-versions": "^3.2.1", + "fileset": "^2.0.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.1.0", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.1", + "js-yaml": "^3.12.0", + "make-dir": "^1.3.0", + "minimatch": "^3.0.4", "once": "^1.4.0" } }, "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "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-hook": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", - "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", + "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", "dev": true, "requires": { - "append-transform": "^0.4.0" + "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "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": "^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" + "@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" } }, "istanbul-lib-report": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", - "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", + "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", "dev": true, "requires": { - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" }, "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", - "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", + "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", "dev": true, "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, "istanbul-reports": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", - "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", + "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", "dev": true, "requires": { - "handlebars": "^4.0.3" + "handlebars": "^4.1.0" } }, "jest": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-23.6.0.tgz", - "integrity": "sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.1.0.tgz", + "integrity": "sha512-+q91L65kypqklvlRFfXfdzUKyngQLOcwGhXQaLmVHv+d09LkNXuBuGxlofTFW42XMzu3giIcChchTsCNUjQ78A==", "dev": true, "requires": { - "import-local": "^1.0.0", - "jest-cli": "^23.6.0" + "import-local": "^2.0.0", + "jest-cli": "^24.1.0" }, "dependencies": { + "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 + }, "jest-cli": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-23.6.0.tgz", - "integrity": "sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.1.0.tgz", + "integrity": "sha512-U/iyWPwOI0T1CIxVLtk/2uviOTJ/OiSWJSe8qt6X1VkbbgP+nrtLJlmT9lPBe4lK78VNFJtrJ7pttcNv/s7yCw==", "dev": true, "requires": { "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", + "graceful-fs": "^4.1.15", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "istanbul-api": "^2.0.8", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-source-maps": "^3.0.1", + "jest-changed-files": "^24.0.0", + "jest-config": "^24.1.0", + "jest-environment-jsdom": "^24.0.0", + "jest-get-type": "^24.0.0", + "jest-haste-map": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-regex-util": "^24.0.0", + "jest-resolve-dependencies": "^24.1.0", + "jest-runner": "^24.1.0", + "jest-runtime": "^24.1.0", + "jest-snapshot": "^24.1.0", + "jest-util": "^24.0.0", + "jest-validate": "^24.0.0", + "jest-watcher": "^24.0.0", + "jest-worker": "^24.0.0", + "micromatch": "^3.1.10", "node-notifier": "^5.2.1", - "prompts": "^0.1.9", + "p-each-series": "^1.0.0", + "pirates": "^4.0.0", + "prompts": "^2.0.1", "realpath-native": "^1.0.0", "rimraf": "^2.5.4", - "slash": "^1.0.0", + "slash": "^2.0.0", "string-length": "^2.0.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.0.0", "which": "^1.2.12", - "yargs": "^11.0.0" + "yargs": "^12.0.2" + } + }, + "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" } } } }, "jest-changed-files": { - "version": "23.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-23.4.2.tgz", - "integrity": "sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.0.0.tgz", + "integrity": "sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ==", "dev": true, "requires": { + "execa": "^1.0.0", "throat": "^4.0.0" } }, "jest-config": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-23.6.0.tgz", - "integrity": "sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.1.0.tgz", + "integrity": "sha512-FbbRzRqtFC6eGjG5VwsbW4E5dW3zqJKLWYiZWhB0/4E5fgsMw8GODLbGSrY5t17kKOtCWb/Z7nsIThRoDpuVyg==", "dev": true, "requires": { - "babel-core": "^6.0.0", - "babel-jest": "^23.6.0", + "@babel/core": "^7.1.0", + "babel-jest": "^24.1.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" + "jest-environment-jsdom": "^24.0.0", + "jest-environment-node": "^24.0.0", + "jest-get-type": "^24.0.0", + "jest-jasmine2": "^24.1.0", + "jest-regex-util": "^24.0.0", + "jest-resolve": "^24.1.0", + "jest-util": "^24.0.0", + "jest-validate": "^24.0.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.0.0", + "realpath-native": "^1.0.2" } }, "jest-diff": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-23.6.0.tgz", - "integrity": "sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.0.0.tgz", + "integrity": "sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA==", "dev": true, "requires": { "chalk": "^2.0.1", - "diff": "^3.2.0", - "jest-get-type": "^22.1.0", - "pretty-format": "^23.6.0" + "diff-sequences": "^24.0.0", + "jest-get-type": "^24.0.0", + "pretty-format": "^24.0.0" } }, "jest-docblock": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-23.2.0.tgz", - "integrity": "sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.0.0.tgz", + "integrity": "sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA==", "dev": true, "requires": { "detect-newline": "^2.1.0" } }, "jest-each": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-23.6.0.tgz", - "integrity": "sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.0.0.tgz", + "integrity": "sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA==", "dev": true, "requires": { "chalk": "^2.0.1", - "pretty-format": "^23.6.0" + "jest-get-type": "^24.0.0", + "jest-util": "^24.0.0", + "pretty-format": "^24.0.0" } }, "jest-environment-jsdom": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz", - "integrity": "sha1-BWp5UrP+pROsYqFAosNox52eYCM=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz", + "integrity": "sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw==", "dev": true, "requires": { - "jest-mock": "^23.2.0", - "jest-util": "^23.4.0", + "jest-mock": "^24.0.0", + "jest-util": "^24.0.0", "jsdom": "^11.5.1" } }, "jest-environment-node": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-23.4.0.tgz", - "integrity": "sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.0.0.tgz", + "integrity": "sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg==", "dev": true, "requires": { - "jest-mock": "^23.2.0", - "jest-util": "^23.4.0" + "jest-mock": "^24.0.0", + "jest-util": "^24.0.0" } }, "jest-get-type": { - "version": "22.4.3", - "resolved": "http://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", - "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.0.0.tgz", + "integrity": "sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w==", "dev": true }, "jest-haste-map": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-23.6.0.tgz", - "integrity": "sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.0.0.tgz", + "integrity": "sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ==", "dev": true, "requires": { "fb-watchman": "^2.0.0", - "graceful-fs": "^4.1.11", + "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.0.0" + "jest-serializer": "^24.0.0", + "jest-util": "^24.0.0", + "jest-worker": "^24.0.0", + "micromatch": "^3.1.10", + "sane": "^3.0.0" } }, "jest-jasmine2": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz", - "integrity": "sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz", + "integrity": "sha512-H+o76SdSNyCh9fM5K8upK45YTo/DiFx5w2YAzblQebSQmukDcoVBVeXynyr7DDnxh+0NTHYRCLwJVf3tC518wg==", "dev": true, "requires": { - "babel-traverse": "^6.0.0", + "@babel/traverse": "^7.1.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" + "expect": "^24.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.0.0", + "jest-matcher-utils": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-snapshot": "^24.1.0", + "jest-util": "^24.0.0", + "pretty-format": "^24.0.0", + "throat": "^4.0.0" } }, "jest-leak-detector": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz", - "integrity": "sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz", + "integrity": "sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg==", "dev": true, "requires": { - "pretty-format": "^23.6.0" + "pretty-format": "^24.0.0" } }, "jest-matcher-utils": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz", - "integrity": "sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz", + "integrity": "sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA==", "dev": true, "requires": { "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "pretty-format": "^23.6.0" + "jest-diff": "^24.0.0", + "jest-get-type": "^24.0.0", + "pretty-format": "^24.0.0" } }, "jest-message-util": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.4.0.tgz", - "integrity": "sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.0.0.tgz", + "integrity": "sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0-beta.35", + "@babel/code-frame": "^7.0.0", "chalk": "^2.0.1", - "micromatch": "^2.3.11", - "slash": "^1.0.0", + "micromatch": "^3.1.10", + "slash": "^2.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-23.2.0.tgz", - "integrity": "sha1-rRxg8p6HGdR8JuETgJi20YsmETQ=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.0.0.tgz", + "integrity": "sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A==", "dev": true }, "jest-regex-util": { - "version": "23.3.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-23.3.0.tgz", - "integrity": "sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.0.0.tgz", + "integrity": "sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q==", "dev": true }, "jest-resolve": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.6.0.tgz", - "integrity": "sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.1.0.tgz", + "integrity": "sha512-TPiAIVp3TG6zAxH28u/6eogbwrvZjBMWroSLBDkwkHKrqxB/RIdwkWDye4uqPlZIXWIaHtifY3L0/eO5Z0f2wg==", "dev": true, "requires": { "browser-resolve": "^1.11.3", @@ -3206,137 +3068,107 @@ } }, "jest-resolve-dependencies": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz", - "integrity": "sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz", + "integrity": "sha512-2VwPsjd3kRPu7qe2cpytAgowCObk5AKeizfXuuiwgm1a9sijJDZe8Kh1sFj6FKvSaNEfCPlBVkZEJa2482m/Uw==", "dev": true, "requires": { - "jest-regex-util": "^23.3.0", - "jest-snapshot": "^23.6.0" + "jest-regex-util": "^24.0.0", + "jest-snapshot": "^24.1.0" } }, "jest-runner": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-23.6.0.tgz", - "integrity": "sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.1.0.tgz", + "integrity": "sha512-CDGOkT3AIFl16BLL/OdbtYgYvbAprwJ+ExKuLZmGSCSldwsuU2dEGauqkpvd9nphVdAnJUcP12e/EIlnTX0QXg==", "dev": true, "requires": { + "chalk": "^2.4.2", "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", + "graceful-fs": "^4.1.15", + "jest-config": "^24.1.0", + "jest-docblock": "^24.0.0", + "jest-haste-map": "^24.0.0", + "jest-jasmine2": "^24.1.0", + "jest-leak-detector": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-runtime": "^24.1.0", + "jest-util": "^24.0.0", + "jest-worker": "^24.0.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } } }, "jest-runtime": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-23.6.0.tgz", - "integrity": "sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.1.0.tgz", + "integrity": "sha512-59/BY6OCuTXxGeDhEMU7+N33dpMQyXq7MLK07cNSIY/QYt2QZgJ7Tjx+rykBI0skAoigFl0A5tmT8UdwX92YuQ==", "dev": true, "requires": { - "babel-core": "^6.0.0", - "babel-plugin-istanbul": "^4.1.6", + "@babel/core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", "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", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.1.0", + "jest-haste-map": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-regex-util": "^24.0.0", + "jest-resolve": "^24.1.0", + "jest-snapshot": "^24.1.0", + "jest-util": "^24.0.0", + "jest-validate": "^24.0.0", + "micromatch": "^3.1.10", "realpath-native": "^1.0.0", - "slash": "^1.0.0", - "strip-bom": "3.0.0", - "write-file-atomic": "^2.1.0", - "yargs": "^11.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "write-file-atomic": "2.4.1", + "yargs": "^12.0.2" } }, "jest-serializer": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-23.0.1.tgz", - "integrity": "sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.0.0.tgz", + "integrity": "sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw==", "dev": true }, "jest-snapshot": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-23.6.0.tgz", - "integrity": "sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.1.0.tgz", + "integrity": "sha512-th6TDfFqEmXvuViacU1ikD7xFb7lQsPn2rJl7OEmnfIVpnrx3QNY2t3PE88meeg0u/mQ0nkyvmC05PBqO4USFA==", "dev": true, "requires": { - "babel-types": "^6.0.0", + "@babel/types": "^7.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", + "jest-diff": "^24.0.0", + "jest-matcher-utils": "^24.0.0", + "jest-message-util": "^24.0.0", + "jest-resolve": "^24.1.0", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^23.6.0", + "pretty-format": "^24.0.0", "semver": "^5.5.0" } }, "jest-util": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-23.4.0.tgz", - "integrity": "sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.0.0.tgz", + "integrity": "sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ==", "dev": true, "requires": { - "callsites": "^2.0.0", + "callsites": "^3.0.0", "chalk": "^2.0.1", - "graceful-fs": "^4.1.11", - "is-ci": "^1.0.10", - "jest-message-util": "^23.4.0", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "jest-message-util": "^24.0.0", "mkdirp": "^0.5.1", - "slash": "^1.0.0", + "slash": "^2.0.0", "source-map": "^0.6.0" }, "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3346,35 +3178,49 @@ } }, "jest-validate": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", - "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.0.0.tgz", + "integrity": "sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g==", "dev": true, "requires": { + "camelcase": "^5.0.0", "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", + "jest-get-type": "^24.0.0", "leven": "^2.1.0", - "pretty-format": "^23.6.0" + "pretty-format": "^24.0.0" } }, "jest-watcher": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-23.4.0.tgz", - "integrity": "sha1-0uKM50+NrWxq/JIrksq+9u0FyRw=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.0.0.tgz", + "integrity": "sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", + "jest-util": "^24.0.0", "string-length": "^2.0.0" } }, "jest-worker": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", - "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.0.0.tgz", + "integrity": "sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg==", "dev": true, "requires": { - "merge-stream": "^1.0.1" + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "js-tokens": { @@ -3384,9 +3230,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3397,8 +3243,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "dev": true }, "jsdom": { "version": "11.12.0", @@ -3432,158 +3277,18 @@ "whatwg-url": "^6.4.1", "ws": "^5.2.0", "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", - "dev": true - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - } - } - } } }, "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema": { @@ -3592,6 +3297,12 @@ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -3599,10 +3310,21 @@ "dev": true }, "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } }, "jsprim": { "version": "1.4.1", @@ -3614,38 +3336,27 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "kleur": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-2.0.2.tgz", - "integrity": "sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.2.tgz", + "integrity": "sha512-3h7B2WRT5LNXOtQiAaWonilegHcPSf9nLVXlSTci8lu1dZUuui61+EsPEZqSVxY7rXYmB2DVKMQILxaO5WL61Q==", "dev": true }, "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "invert-kv": "^1.0.0" + "invert-kv": "^2.0.0" } }, "left-pad": { @@ -3671,32 +3382,31 @@ } }, "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "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": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "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": "^2.0.0", + "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lodash.sortby": { @@ -3705,6 +3415,15 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3738,6 +3457,15 @@ } } }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, "make-error": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", @@ -3753,6 +3481,15 @@ "tmpl": "1.0.x" } }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3768,19 +3505,15 @@ "object-visit": "^1.0.0" } }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" } }, "merge": { @@ -3799,39 +3532,39 @@ } }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "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" + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime-db": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", "dev": true }, "mime-types": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", - "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", "dev": true, "requires": { - "mime-db": "~1.35.0" + "mime-db": "~1.38.0" } }, "mimic-fn": { @@ -3894,6 +3627,12 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", @@ -3916,26 +3655,6 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "native-node-utils": { @@ -3959,6 +3678,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node-abi": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.7.1.tgz", @@ -3973,13 +3698,20 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, "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", + "is-wsl": "^1.1.0", "semver": "^5.5.0", "shellwords": "^0.1.1", "which": "^1.3.0" @@ -3991,13 +3723,13 @@ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } @@ -4036,9 +3768,15 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "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.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.1.tgz", + "integrity": "sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { @@ -4065,13 +3803,22 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", "dev": true }, "object-visit": { @@ -4081,14 +3828,6 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "object.getownpropertydescriptors": { @@ -4101,16 +3840,6 @@ "es-abstract": "^1.5.1" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -4118,14 +3847,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "once": { @@ -4136,6 +3857,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "opencv-build": { "version": "0.0.17", "resolved": "https://registry.npmjs.org/opencv-build/-/opencv-build-0.0.17.tgz", @@ -4171,14 +3901,6 @@ "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } } }, "optionator": { @@ -4193,6 +3915,14 @@ "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } } }, "os-homedir": { @@ -4201,14 +3931,14 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, "os-tmpdir": { @@ -4217,54 +3947,70 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "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": "^1.1.0" + "p-limit": "^2.0.0" } }, - "p-try": { + "p-reduce": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^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 }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse5": { @@ -4303,44 +4049,42 @@ "dev": true }, "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "pify": "^3.0.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, "requires": { - "pinkie": "^2.0.0" + "node-modules-regexp": "^1.0.0" } }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "^2.1.0" + "find-up": "^3.0.0" } }, "pn": { @@ -4390,49 +4134,37 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, "pretty-format": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.0.0.tgz", + "integrity": "sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g==", "dev": true, "requires": { - "ansi-regex": "^3.0.0", + "ansi-regex": "^4.0.0", "ansi-styles": "^3.2.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", "dev": true } } }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "prompts": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-0.1.14.tgz", - "integrity": "sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.3.tgz", + "integrity": "sha512-H8oWEoRZpybm6NV4to9/1limhttEo13xK62pNvn2JzY0MA03p7s0OjtmhXyon3uJmxiJJVSuUwEJFFssI3eBiQ==", "dev": true, "requires": { - "kleur": "^2.0.1", - "sisteransi": "^0.1.1" + "kleur": "^3.0.2", + "sisteransi": "^1.0.0" } }, "pseudomap": { @@ -4441,9 +4173,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, "pump": { @@ -4461,30 +4193,11 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "rc": { "version": "1.2.8", @@ -4505,45 +4218,24 @@ } }, "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "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": "^1.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "path-type": "^3.0.0" } }, "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "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": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" } }, "readable-stream": { @@ -4561,29 +4253,14 @@ } }, "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" } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -4612,33 +4289,70 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } } }, "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", "dev": true, "requires": { - "lodash": "^4.13.1" + "lodash": "^4.17.11" } }, "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", "dev": true, "requires": { - "request-promise-core": "1.1.1", - "stealthy-require": "^1.1.0", - "tough-cookie": ">=2.3.3" + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" } }, "require-directory": { @@ -4654,10 +4368,13 @@ "dev": true }, "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } }, "resolve-cwd": { "version": "2.0.0", @@ -4666,22 +4383,30 @@ "dev": true, "requires": { "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } } }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -4689,12 +4414,12 @@ "dev": true }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "robotjs": { @@ -4712,6 +4437,24 @@ "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", "dev": true }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4733,14 +4476,15 @@ "dev": true }, "sane": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", - "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-3.1.0.tgz", + "integrity": "sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q==", "dev": true, "requires": { "anymatch": "^2.0.0", "capture-exit": "^1.2.0", "exec-sh": "^0.2.0", + "execa": "^1.0.0", "fb-watchman": "^2.0.0", "fsevents": "^1.2.3", "micromatch": "^3.1.4", @@ -4749,300 +4493,11 @@ "watch": "~0.18.0" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "minimist": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -5125,15 +4580,15 @@ } }, "sisteransi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-0.1.1.tgz", - "integrity": "sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", + "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", "dev": true }, "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, "snapdragon": { @@ -5235,18 +4690,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -5257,6 +4700,17 @@ "dev": true, "requires": { "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "source-map": { @@ -5279,12 +4733,21 @@ } }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", "dev": true, "requires": { - "source-map": "^0.5.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -5294,9 +4757,9 @@ "dev": true }, "spdx-correct": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", - "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -5320,9 +4783,9 @@ } }, "spdx-license-ids": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", - "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", "dev": true }, "split-string": { @@ -5341,9 +4804,9 @@ "dev": true }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -5355,20 +4818,12 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, "static-extend": { @@ -5398,6 +4853,12 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, + "string-argv": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.1.tgz", + "integrity": "sha512-El1Va5ehZ0XTj3Ekw4WFidXvTmt9SrC0+eigdojgtJMVtPkF0qbBe9fyNSl9eQf+kUHnTSQxdQYzuHfZy8V+DQ==", + "dev": true + }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", @@ -5441,13 +4902,10 @@ } }, "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true }, "strip-eof": { "version": "1.0.0", @@ -5511,15 +4969,14 @@ } }, "test-exclude": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.3.tgz", - "integrity": "sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA==", + "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", - "micromatch": "^2.3.11", - "object-assign": "^4.1.0", - "read-pkg-up": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", "require-main-filename": "^1.0.1" } }, @@ -5529,6 +4986,21 @@ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -5541,9 +5013,9 @@ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" }, "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-object-path": { @@ -5553,6 +5025,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "to-regex": { @@ -5575,34 +5058,16 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } } }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "tr46": { @@ -5621,9 +5086,9 @@ "dev": true }, "ts-jest": { - "version": "23.10.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-23.10.5.tgz", - "integrity": "sha512-MRCs9qnGoyKgFc8adDEntAOP64fWK1vZKnOYU1o2HxaqjdJvGqmkLCPCnVq1/If4zkUmEjKPnCiUisTrlX2p2A==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.0.0.tgz", + "integrity": "sha512-o8BO3TkMREpAATaFTrXkovMsCpBl2z4NDBoLJuWZcJJj1ijI49UnvDMfVpj+iogn/Jl8Pbhuei5nc/Ti+frEHw==", "dev": true, "requires": { "bs-logger": "0.x", @@ -5637,19 +5102,10 @@ "yargs-parser": "10.x" }, "dependencies": { - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "yargs-parser": { @@ -5670,9 +5126,9 @@ "dev": true }, "tslint": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.11.0.tgz", - "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.1.tgz", + "integrity": "sha512-fplQqb2miLbcPhyHoMV4FU9PtNRbgmm/zI5d3SZwwmJQM6V0eodju+hplpyfhLWpmwrDNfNYU57uYRb8s0zZoQ==", "dev": true, "requires": { "babel-code-frame": "^6.22.0", @@ -5683,21 +5139,11 @@ "glob": "^7.1.1", "js-yaml": "^3.7.0", "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", "resolve": "^1.3.2", "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.27.2" - }, - "dependencies": { - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - } } }, "tsutils": { @@ -5721,8 +5167,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "dev": true }, "type-check": { "version": "0.3.2", @@ -5733,10 +5178,16 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "typescript": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz", - "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==", + "version": "3.3.3333", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3333.tgz", + "integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==", "dev": true }, "uglify-js": { @@ -5831,15 +5282,18 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -5892,12 +5346,28 @@ "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" + } + }, + "version-bump-prompt": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/version-bump-prompt/-/version-bump-prompt-4.3.0.tgz", + "integrity": "sha512-6k03/PlGdhV0TcgSE/3717oJ60HIWJRP70mdngWaoYqnehL/tUQyKUxPvzK7VxrjUrGhwc0wG9z7ceLUlnybJQ==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "commander": "^2.19.0", + "detect-indent": "^5.0.0", + "ez-spawn": "^2.1.1", + "glob": "^7.1.3", + "inquirer": "^6.2.1", + "log-symbols": "^2.2.0", + "semver": "^5.6.0" }, "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true } } @@ -5954,9 +5424,9 @@ } }, "whatwg-mimetype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz", - "integrity": "sha512-5YSO1nMd5D1hY3WzAQV3PzZL83W3YeyR1yW9PcH26Weh1t+Vzh9B6XkDh7aXm83HBZ4nSMvkjvN2H2ySWIvBgw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, "whatwg-url": { @@ -5998,9 +5468,9 @@ } }, "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrap-ansi": { @@ -6050,9 +5520,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "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.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -6081,9 +5551,9 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yallist": { @@ -6092,32 +5562,33 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { - "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", - "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "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", - "yargs-parser": "^9.0.2" + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" } }, "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } diff --git a/package.json b/package.json index c5b79ecd..988a4ed1 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,7 @@ "lint": "tslint -p tsconfig.json", "watch": "tsc -w -p .", "prepublishOnly": "npm run compile && npm test", - "version": "git add -A lib", - "postversion": "git push && git push --tags" + "versionUpdate": "bump --prompt --tag --push --all" }, "dependencies": { "clipboardy": "^1.2.3", @@ -62,10 +61,11 @@ }, "devDependencies": { "@types/clipboardy": "^1.1.0", - "@types/jest": "^23.3.9", - "jest": "^23.6.0", - "ts-jest": "^23.10.5", - "tslint": "^5.11.0", - "typescript": "^3.3.3" + "@types/jest": "^24.0.9", + "jest": "^24.1.0", + "ts-jest": "^24.0.0", + "tslint": "^5.13.1", + "typescript": "^3.3.3333", + "version-bump-prompt": "^4.3.0" } } From 6dd0da41c00f521a66553ed77b872b37431532f2 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 7 Mar 2019 12:11:34 +0100 Subject: [PATCH 24/25] Updated mocks to match method signatures --- .../native/robotjs-screen-action.class.spec.ts | 8 ++++++++ lib/screen.class.spec.ts | 14 +++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/provider/native/robotjs-screen-action.class.spec.ts b/lib/provider/native/robotjs-screen-action.class.spec.ts index 48fd725e..4571365c 100644 --- a/lib/provider/native/robotjs-screen-action.class.spec.ts +++ b/lib/provider/native/robotjs-screen-action.class.spec.ts @@ -28,6 +28,10 @@ describe("robotjs screen action", () => { // GIVEN const SUT = new ScreenAction(); robot.screen.capture = jest.fn(() => ({ + bitsPerPixel: 0, + byteWidth: 0, + bytesPerPixel: 0, + colorAt: jest.fn(), height: screenShotSize.height, image: new ArrayBuffer(0), width: screenShotSize.width, @@ -55,6 +59,10 @@ describe("robotjs screen action", () => { const screenRegion = new Region(0, 0, 10, 10); const SUT = new ScreenAction(); robot.screen.capture = jest.fn(() => ({ + bitsPerPixel: 0, + byteWidth: 0, + bytesPerPixel: 0, + colorAt: jest.fn(), height: screenShotSize.height, image: new ArrayBuffer(0), width: screenShotSize.width, diff --git a/lib/screen.class.spec.ts b/lib/screen.class.spec.ts index 99382af9..4f455e1b 100644 --- a/lib/screen.class.spec.ts +++ b/lib/screen.class.spec.ts @@ -13,11 +13,11 @@ const searchRegion = new Region(0, 0, 100, 100); beforeAll(() => { VisionAdapter.prototype.grabScreen = jest.fn(() => { - return new Image(searchRegion.width, searchRegion.height, new ArrayBuffer(0), 3); + return Promise.resolve(new Image(searchRegion.width, searchRegion.height, new ArrayBuffer(0), 3)); }); VisionAdapter.prototype.screenSize = jest.fn(() => { - return searchRegion; + return Promise.resolve(searchRegion); }); }); @@ -26,7 +26,7 @@ describe("Screen.", () => { const matchResult = new MatchResult(0.99, searchRegion); VisionAdapter.prototype.findOnScreenRegion = jest.fn(() => { - return matchResult; + return Promise.resolve(matchResult); }); const visionAdapterMock = new VisionAdapter(); @@ -47,7 +47,7 @@ describe("Screen.", () => { const matchResult = new MatchResult(0.8, searchRegion); VisionAdapter.prototype.findOnScreenRegion = jest.fn(() => { - return matchResult; + return Promise.resolve(matchResult); }); const visionAdapterMock = new VisionAdapter(); @@ -64,7 +64,7 @@ describe("Screen.", () => { const matchResult = new MatchResult(minMatch, searchRegion); VisionAdapter.prototype.findOnScreenRegion = jest.fn(() => { - return matchResult; + return Promise.resolve(matchResult); }); const visionAdapterMock = new VisionAdapter(); @@ -88,7 +88,7 @@ describe("Screen.", () => { const matchResult = new MatchResult(0.99, searchRegion); VisionAdapter.prototype.findOnScreenRegion = jest.fn(() => { - return matchResult; + return Promise.resolve(matchResult); }); const visionAdapterMock = new VisionAdapter(); @@ -113,7 +113,7 @@ describe("Screen.", () => { const matchResult = new MatchResult(minMatch, searchRegion); VisionAdapter.prototype.findOnScreenRegion = jest.fn(() => { - return matchResult; + return Promise.resolve(matchResult); }); const visionAdapterMock = new VisionAdapter(); From 65215d42536b540863cd4fedecfd466cca4612d0 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Thu, 7 Mar 2019 12:29:11 +0100 Subject: [PATCH 25/25] release v0.1.0-beta.0 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 988a4ed1..c78d526e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nut-tree/nut-js", - "version": "0.0.4", + "version": "0.1.0-beta.0", "license": "Apache-2.0", "main": "dist/index", "typings": "dist/index", @@ -52,7 +52,7 @@ "lint": "tslint -p tsconfig.json", "watch": "tsc -w -p .", "prepublishOnly": "npm run compile && npm test", - "versionUpdate": "bump --prompt --tag --push --all" + "versionBump": "bump --prompt --tag --push --all" }, "dependencies": { "clipboardy": "^1.2.3", @@ -68,4 +68,4 @@ "typescript": "^3.3.3333", "version-bump-prompt": "^4.3.0" } -} +} \ No newline at end of file

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 Y`!&Bj1sLmF{QD^a2B|5O%Ugv056G$M`2YX_ diff --git a/demo/clipboard.js b/demo/clipboard.js deleted file mode 100755 index 37ee643d..00000000 --- a/demo/clipboard.js +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node - -"use strict"; -const { clipboard } = require("../dist"); - -(async () => { - await clipboard.copy("clipboard test!"); - console.log(await clipboard.paste()); -})(); \ No newline at end of file diff --git a/demo/mouse.js b/demo/mouse.js deleted file mode 100755 index eb4bf6bb..00000000 --- a/demo/mouse.js +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env node - -"use strict"; - -const { mouse, movement, screen, Location } = require("../dist"); - -const square = async () => { - await mouse.move(await movement.right(500)); - await mouse.move(await movement.down(500)); - await mouse.move(await movement.left(500)); - await mouse.move(await movement.up(500)); -}; - -(async () => { - await mouse - .leftClick(); - await square(); - try { - screen.config.resourceDirectory = "./assets"; - const whale = await screen.findOnScreen("docker.png"); - await mouse.move(await movement.straightTo(Location.centerOf(whale))); - - const gitlens = await screen.findOnScreen("gitlens.png"); - await mouse.move(await movement.straightTo(Location.centerOf(gitlens))); - await mouse.drag(await movement.right(600)); - await mouse.move(await movement.straightTo(Location.centerOf(gitlens))); - await mouse.drag(await movement.straightTo(Location.centerOf(whale))); - } catch (error) { - console.log(error); - } -})(); diff --git a/e2e/assets/calculator.png b/e2e/assets/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..ade6f55868712a549ef673236ff6c19b45db371f GIT binary patch literal 11526 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 *#;yiZvHBdtFoD8x2Q$YYnfBkExpUj*=LY_z9Gt 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