diff --git a/.gitignore b/.gitignore index 51a3df207..7bc1e7ff6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ out/ !locales/**/out/ package.nls.*.json +# virtual environment +venv/ + # testing .vscode-test diff --git a/.vscode/settings.json b/.vscode/settings.json index 30bf8c2d3..fa0a10487 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,4 +8,4 @@ }, // Turn off tsc task auto detection since we have the necessary tasks as npm scripts "typescript.tsc.autoDetect": "off" -} \ No newline at end of file +} diff --git a/README.md b/README.md index 9ecc0c8b2..f52084c69 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,39 @@ # Device Simulator Express, a Microsoft Garage project -Make without limit! Device Simulator Express, a Microsoft Garage project, allows you to code in CircuitPython for your awesome -Circuit Playground Express (CPX) projects! Test and debug your code on the device simulator and see the same +Python versions: 3.7+ Project Status: Active – The project has reached a stable, usable state and is being actively developed. License: We are using the MIT License We are welcoming PRS! Platforms Supported: Windows, MacOSX + +Azure DevOps Board Badge + +Make without limit! Device Simulator Express, a Microsoft Garage project, allows you to code microcontrollers without the hardware on hand! You can program your Circuit Playground Express (CPX) or your BBC micro:bit! Test and debug your code on the device simulator and see the same result when you plug in your actual microcontroller. Curious about the output of the device, the serial monitor allows you to observe the device output. CircuitPlayground Express -## Features +## Build Status + +| Branch | Build Status | +| :------ | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| dev | [![Build Status](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_apis/build/status/Adafruit/Pacifica-CI?branchName=dev)](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_build/latest?definitionId=304&branchName=dev) | +| staging | [![Build Status](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_apis/build/status/Adafruit/Pacifica-CI?branchName=staging)](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_build/latest?definitionId=304&branchName=staging) | +| master | [![Build Status](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_apis/build/status/Adafruit/Pacifica-CI?branchName=master)](https://microsoftgarage.visualstudio.com/Intern%20GitHub/_build/latest?definitionId=304&branchName=master) | + + +## Prerequisites -- IntelliSense and syntax highlighting for CircuitPython code (only supports CPX Express library) +The following dependencies are required to install before launching Device Simulator Express. +You will be prompted to install the Python dependencies during the first use. + +- _**[Visual Studio Code](https://code.visualstudio.com/)**_ +- _**[Node](https://nodejs.org/en/download/)**_ +- _**[Python 3.7+](https://www.python.org/downloads/)**_: Make sure you've added python and pip to your PATH in your environment variables. (1) +- _**[Python VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python)**_: This will be installed automatically from the marketplace when you install Device Simulator Express. + +## Circuit Playground Express (CPX) Simulator + +### Features + +- IntelliSense and syntax highlighting for CircuitPython code - Template file generation - Integrated Python Debugging for the Simulator - Serial monitor (available on Windows and Mac only) @@ -33,27 +57,10 @@ The simulator supports most of the sensors on CPX except **IR transmitter & Rece The code related to these sensors can still run on the actual CPX board and be deployed using Device Simulator Express. As we only support CPX library now, other libraries (i.e. simpleio) can’t run on the simulator. But they will work on the actual device! -## Prerequisites - -The following dependencies are required to install before launching Device Simulator Express. -You will be prompted to install the Python dependencies during the first use. - -- _**[Visual Studio Code](https://code.visualstudio.com/)**_ -- _**[Node](https://nodejs.org/en/download/)**_ -- _**[Python 3.7.4](https://www.python.org/downloads/)**_: Make sure you've added python and pip to your PATH in your environment variables. (1) -- _**[Python VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python)**_: This will be installed automatically from the marketplace when you install Device Simulator Express. -- Python Modules for Simulation - - **Note:** On extension activation, you will be prompted with a popup message asking if you want the modules to be automatically installed for you. The following Python modules should be downloaded when you select "yes" on the prompt message. **If modules are not installed correctly, please use the "pip install" commands listed below.** - - Playsound : `pip install playsound` - - Pywin32 : `pip install pywin32` - - On Windows, you need to use the above command in the console to manually install pywin32. - - Python-Socketio : `pip install python-socketio` - - Requests : `pip install requests` - - Application Insights: `pip install applicationinsights` -## Useful Links +### Useful Links - Tutorials and Example Code for Adafruit CPX: - [Adafruit CPX library tutorial](https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library) - [Adafruit CPX Examples on GitHub](https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples) @@ -62,35 +69,33 @@ You will be prompted to install the Python dependencies during the first use. - [Tutorial for formatting Adafruit CPX for CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython) - [Download Firmware .uf2 file](https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart) - [Download the latest version of the Adafruit CPX library](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries) -- For developers: - - [Steps to run the extension locally](/docs/developers-setup.md) -## How to use +### How to use To use Device Simulator Express, install the extension from the marketplace and reload VS Code. -### 1. Start with the "New File" Command. +#### 1. Start with the "Device Simulator Express [Circuit Playground Express]: New File" Command. -1. Type in `"Device Simulator Express: New File"` in the command palette (`CTRL+SHIFT+P` to open the command palette). +1. Type in `"Device Simulator Express: [Circuit Playground Express] New File"` in the command palette (`CTRL+SHIFT+P` to open the command palette). "New File" animation 2. Name and save your file somewhere, and we’re good to go! (3) -3. Start with some examples: you can find examples files and tutorials inside the comments, as well as in the notification pop up when you run the `"Device Simulator Express: New File"` Command. +3. Start with some examples: you can find examples files and tutorials inside the comments, as well as in the notification pop up when you run the `"Device Simulator Express: [Circuit Playground Express] New File"` Command. How to find example code screenshot -### 2. Start from an existing python file. +#### 2. Start from an existing python file. 1. Open the folder or your .py file in Visual Studio Code. -2. Run `open Simulator` from the command palette or icon in the editor toolbar. +2. Run `Device Simulator Express: [Circuit Playground Express] Open Simulator` from the command palette or icon in the editor toolbar. -### 3. Run your code on the simulator. +#### 3. Run your code on the simulator. How to run the simulator animation - Run `Run Simulator` from the command palette or icon in the editor toolbar. - You can use the `Play` or `Refresh` button on the simulator webview. -### 4. Deploy your code to the physical device +#### 4. Deploy your code to the physical device Before deploying the python code to your CPX device, you need to format your device following these tutorials: @@ -102,14 +107,14 @@ Then, if you are on Windows, you will also need to install the Python Pywin32 pa Deploy to Device -### 5. Use the Serial Monitor for your Adafruit CPX device (available on Windows and Mac only) +#### 5. Use the Serial Monitor for your Adafruit CPX device (available on Windows and Mac only) 1. Plug in your CPX device (make sure it’s formatted properly already) -2. Run the command `"Device Simulator Express: Open Serial Monitor"` +2. Run the command `"Device Simulator Express: [Circuit Playground Express] Open Serial Monitor"` 3. Select your baud rate for the serial port 4. The print() statements in your code will show in the output console -### 6. Use the sensors in the Device Simulator Express +#### 6. Use the sensors in the Device Simulator Express Generating input for the sensors can be done by interacting directly with device on the webview or by using the toolbar. @@ -118,33 +123,64 @@ or by using the toolbar. - **Temperature sensor, Light sensor, acceleration:** click on the corresponding button in the toolbar and change the value using the slider or the input box attached to it. - **Shake detection:** go to the motion sensor section in the toolbar and click on the shake button. -### 7. Debug your project on the simulator +#### 7. Debug your project on the simulator 1. Add breakpoints in your code 2. Press F5 to enter the debugging mode, and you can start debugging line by line! -## Commands +### Commands Device Simulator Express provides several commands in the Command Palette (F1 or Ctrl + Shift + P/ Cmd + Shift + P for Mac OS) for working with \*.py files: -- `Device Simulator Express: New File`: Opens an unsaved .py file with template code, also opens the simulator. -- `Device Simulator Express: Open Simulator`: Opens the simulator in the webView -- `Device Simulator Express: Run on Simulator`: Runs python code on the simulator -- `Device Simulator Express: Deploy to Device`: Copies & Pastes the code.py or main.py file to CIRCUITPY drive if detected a CPX is plugged in -- `Device Simulator Express: Open Serial Monitor`: Opens the serial monitor in the integrated output window. -- `Device Simulator Express: Close Serial Monitor`: Stops the serial monitor and releases the serial port. -- `Device Simulator Express: Change Baud Rate`: Changes the baud rate of the selected serial port. For Adafruit CPX, the default baud rate is 115200. -- `Device Simulator Express: Select Serial Port`: Changes the current serial port. +- `Device Simulator Express: [Circuit Playground Express] New File`: Opens an unsaved .py file with template code, also opens the simulator. +- `Device Simulator Express: [Circuit Playground Express] Open Simulator`: Opens the simulator in the webView +- `Device Simulator Express: [Circuit Playground Express] Run on Simulator`: Runs python code on the simulator +- `Device Simulator Express: [Circuit Playground Express] Deploy to Device`: Copies & Pastes the code.py or main.py file to CIRCUITPY drive if detected a CPX is plugged in +- `Device Simulator Express: [Circuit Playground Express] Open Serial Monitor`: Opens the serial monitor in the integrated output window. +- `Device Simulator Express: [Circuit Playground Express] Close Serial Monitor`: Stops the serial monitor and releases the serial port. +- `Device Simulator Express: [Circuit Playground Express] Change Baud Rate`: Changes the baud rate of the selected serial port. For Adafruit CPX, the default baud rate is 115200. +- `Device Simulator Express: [Circuit Playground Express] Select Serial Port`: Changes the current serial port. -## Keybindings +### Keybindings In Device Simulator Express, you can use keyboard to interact with the device: -- Push Button `A & B: A B` +- Push Button `A for A, B for B, C for A & B` - Capacitive Touch Sensor `A1 – A7: SHIFT + 1~7` - Slider Switch: `SHIFT + S` - Refresh the simulator: `SHIFT + R` + +## BBC micro:bit Simulator +>**NOTE 1**: this feature is hidden by default. To use it, enable the feature flag in the "deviceSimulatorExpress.previewMode" user setting. + +>**NOTE 2**: micro:bit simulation is still in development. Features may not work as intended. + +### Features +- IntelliSense and syntax highlighting for micro:bit code +- Template file generation +- Integrated Python Debugging for the Simulator +- Simulation of the micro:bit device, including: + - 25 LEDs + - Light sensor + - Motion sensors + - Acceleration detection + - Temperature sensor + +### How to use +Using the simulator for the micro:bit is similar to using the one for the CPX. The only difference is that the commands in the command palette display `Device Simulator Express: [micro:bit] ` instead of `Device Simulator Express: [Circuit Playground Express] `. Currently, we support the following commands for micro:bit: +- `Device Simulator Express: [micro:bit] Open Simulator`: Opens an unsaved .py file with template code, also opens the simulator. +- `Device Simulator Express: [micro:bit] New File`: Opens the simulator in the webView + +Please review the CPX's ["How to use" guide](#How-to-use) for more info. + +### Keybindings +- Push Button `A for A, B for B, C for A & B` +- Refresh the simulator: `SHIFT + R` + +## Contribute +[See here for steps to run the extension locally.](/docs/developers-setup.md) + ## Provide feedback To report issues, provide feedback or requests, please use this link: [Provide Feedback](https://aka.ms/AA5xpxx). @@ -183,7 +219,7 @@ A `ThirdPartyNotices.txt` file is provided in the extension's source code listin - While running a code file, if you get an error saying it can't find the file, make sure you've clicked on a valid Python code file before running it. - To open the output panel again after closing it go to VS Code menu: `View->Output`. - If you try to deploy to the device while it's plugged in but you still get an error saying it cannot find the board, make sure your Circuit Playground Express is formatted correctly and that its name matches `CIRCUITPY`. -- If you can't get the Simulator communication working while debugging, try to open your `Settings` and check the port used under `"Device Simulator Express: Debugger Server Port"`. You can either change it (usually ports above 5000 should work) or try to free it, then start debugging again. +- If you can't get the Simulator communication working while debugging, try to open your `Settings` and check the port used under `"Device Simulator Express: [] Debugger Server Port"`. You can either change it (usually ports above 5000 should work) or try to free it, then start debugging again. - When you are using the serial monitor, if you get some unusual error messages, unplug the device and reload the VS Code windows. ## License diff --git a/gulpfile.js b/gulpfile.js index 3c106798d..e2b15d39b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,135 +1,140 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -const gulp = require("gulp"); - -const ts = require("gulp-typescript"); -const sourcemaps = require("gulp-sourcemaps"); -const typescript = require("typescript"); -const del = require("del"); -const es = require("event-stream"); -const vsce = require("vsce"); -const nls = require("vscode-nls-dev"); - -const tsProject = ts.createProject("./tsconfig.json", { typescript }); - -const inlineMap = true; -const inlineSource = false; -const outDest = "out"; - -// A list of all locales supported by VSCode can be found here: https://code.visualstudio.com/docs/getstarted/locales -const languages = [{ folderName: "en", id: "en" }]; - -gulp.task("clean", () => { - return del( - [ - "out/*", - "package.nls.*.json", - "../../dist/*0.0.0-UNTRACKEDVERSION.vsix" - ], - { force: true } - ); -}); - -const pythonToMove = [ - "./src/adafruit_circuitplayground/*.*", - "./src/*.py", - "./src/requirements.txt", -]; - -gulp.task("python-compile", () => { - // the base option sets the relative root for the set of files, - // preserving the folder structure - return gulp.src(pythonToMove, { base: "./src/" }).pipe(gulp.dest("out")); -}); - -gulp.task("internal-compile", () => { - return compile(false); -}); - -gulp.task("internal-nls-compile", () => { - return compile(true); -}); - -gulp.task("add-locales", () => { - return gulp - .src(["package.nls.json"]) - .pipe(nls.createAdditionalLanguageFiles(languages, "locales")) - .pipe(gulp.dest(".")); -}); - -gulp.task("vsce:publish", () => { - return vsce.publish(); -}); - -gulp.task("vsce:package", () => { - return vsce.createVSIX({ - packagePath: "../../dist/deviceSimulatorExpress-0.0.0-UNTRACKEDVERSION.vsix" - }); -}); - -gulp.task( - "compile", - gulp.series("clean", "internal-compile", "python-compile", callback => { - callback(); - }) -); - -gulp.task( - "build", - gulp.series( - "clean", - "internal-nls-compile", - "python-compile", - "add-locales", - callback => { - callback(); - } - ) -); - -gulp.task( - "publish", - gulp.series("compile", "vsce:publish", callback => { - callback(); - }) -); - -gulp.task( - "package", - gulp.series("compile", "vsce:package", callback => { - callback(); - }) -); - -//---- internal - -function compile(buildNls) { - var r = tsProject - .src() - .pipe(sourcemaps.init()) - .pipe(tsProject()) - .js.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through()) - .pipe( - buildNls - ? nls.createAdditionalLanguageFiles(languages, "locales", "out") - : es.through() - ); - - if (inlineMap && inlineSource) { - r = r.pipe(sourcemaps.write()); - } else { - r = r.pipe( - sourcemaps.write("../out", { - // no inlined source - includeContent: inlineSource, - // Return relative source map root directories per file. - sourceRoot: "../src" - }) - ); - } - - return r.pipe(gulp.dest(outDest)); -} +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const gulp = require("gulp"); + +const ts = require("gulp-typescript"); +const sourcemaps = require("gulp-sourcemaps"); +const typescript = require("typescript"); +const del = require("del"); +const es = require("event-stream"); +const vsce = require("vsce"); +const nls = require("vscode-nls-dev"); + +const tsProject = ts.createProject("./tsconfig.json", { typescript }); + +const inlineMap = true; +const inlineSource = false; +const outDest = "out"; + +// A list of all locales supported by VSCode can be found here: https://code.visualstudio.com/docs/getstarted/locales +const languages = [{ folderName: "en", id: "en" }]; + +gulp.task("clean", () => { + return del( + [ + "out/*", + "package.nls.*.json", + "../../dist/*0.0.0-UNTRACKEDVERSION.vsix", + ], + { force: true } + ); +}); + +const pythonToMove = [ + "./src/adafruit_circuitplayground/*.*", + "./src/microbit/*.*", + "./src/microbit/!(test)/**/*", + "./src/*.py", + "./src/common/*.py", + "./src/requirements.txt", + "./src/templates/*.*" +]; + +gulp.task("python-compile", () => { + // the base option sets the relative root for the set of files, + // preserving the folder structure + return gulp.src(pythonToMove, { base: "./src/" }).pipe(gulp.dest("out")); +}); + +gulp.task("internal-compile", () => { + return compile(false); +}); + +gulp.task("internal-nls-compile", () => { + return compile(true); +}); + +gulp.task("add-locales", () => { + return gulp + .src(["package.nls.json"]) + .pipe(nls.createAdditionalLanguageFiles(languages, "locales")) + .pipe(gulp.dest(".")); +}); + +gulp.task("vsce:publish", () => { + return vsce.publish(); +}); + +gulp.task("vsce:package", () => { + return vsce.createVSIX({ + packagePath: + "../../dist/deviceSimulatorExpress-0.0.0-UNTRACKEDVERSION.vsix", + }); +}); + +gulp.task( + "compile", + gulp.series("clean", "internal-compile", "python-compile", callback => { + callback(); + }) +); + +gulp.task( + "build", + gulp.series( + "clean", + "internal-nls-compile", + "python-compile", + "add-locales", + callback => { + callback(); + } + ) +); + +gulp.task( + "publish", + gulp.series("compile", "vsce:publish", callback => { + callback(); + }) +); + +gulp.task( + "package", + gulp.series("compile", "vsce:package", callback => { + callback(); + }) +); + +//---- internal + +function compile(buildNls) { + var r = tsProject + .src() + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .js.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through()) + .pipe( + buildNls + ? nls.createAdditionalLanguageFiles(languages, "locales", "out") + : es.through() + ); + + if (inlineMap && inlineSource) { + r = r.pipe(sourcemaps.write()); + } else { + r = r.pipe( + sourcemaps.write("../out", { + // no inlined source + includeContent: inlineSource, + // Return relative source map root directories per file. + sourceRoot: "../src", + }) + ); + } + + return r.pipe(gulp.dest(outDest)); +} diff --git a/locales/en/out/constants.i18n.json b/locales/en/out/constants.i18n.json index d805009c8..333d9bf47 100644 --- a/locales/en/out/constants.i18n.json +++ b/locales/en/out/constants.i18n.json @@ -27,7 +27,7 @@ "info.deploySimulator": "\n[INFO] Deploying code to the simulator...\n", "info.deploySuccess": "\n[INFO] Code successfully deployed\n", "info.extensionActivated": "Congratulations, your extension Adafruit_Simulator is now active!", - "info.firstTimeWebview": "To reopen the simulator click on the \"Open Simulator\" button on the upper right corner of the text editor, or select the command \"Open Simulator\" from command palette.", + "info.firstTimeWebview": "To reopen the simulator select the command \"Open Simulator\" from command palette.", "info.installPythonDependencies": "Do you want us to try and install this extensions dependencies for you?", "error.invalidFileExtensionDebug": "The file you tried to run isn\\'t a Python file.", "info.newFile": "New to Python or the Circuit Playground Express? We are here to help!", @@ -36,7 +36,7 @@ "info.privacyStatement": "Privacy Statement", "info.successfulInstall": "Successfully installed Python dependencies.", "info.thirdPartyWebsite": "By clicking \"Agree and Proceed\" you will be redirected to adafruit.com, a third party website not managed by Microsoft. Please note that your activity on adafruit.com is subject to Adafruit's privacy policy", - "info.welcomeOutputTab": "Welcome to the Adafruit Simulator output tab!\n\n", + "info.welcomeOutputTab": "Welcome to the Device Simulator Express output tab!\n\n", "label.webviewPanel": "Device Simulator Express", "name": "Device Simulator Express", diff --git a/locales/en/package.i18n.json b/locales/en/package.i18n.json index 49d2906a0..9afd1a72c 100644 --- a/locales/en/package.i18n.json +++ b/locales/en/package.i18n.json @@ -1,16 +1,19 @@ { - "deviceSimulatorExpressExtension.commands.changeBaudRate": "Change Baud Rate", - "deviceSimulatorExpressExtension.commands.closeSerialMonitor": "Close Serial Monitor", - "deviceSimulatorExpressExtension.commands.label": "Device Simulator Express", - "deviceSimulatorExpressExtension.commands.openSerialMonitor": "Open Serial Monitor", - "deviceSimulatorExpressExtension.commands.openSimulator": "Open Simulator", - "deviceSimulatorExpressExtension.commands.runSimulator": "Run Simulator", - "deviceSimulatorExpressExtension.commands.newFile": "New File", - "deviceSimulatorExpressExtension.commands.runDevice": "Deploy to Device", - "deviceSimulatorExpressExtension.commands.selectSerialPort": "Select Serial Port", + "deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies", + "deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express", + "deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator", + "deviceSimulatorExpressExtension.commands.cpx.changeBaudRate": "[Circuit Playground Express] Change Baud Rate", + "deviceSimulatorExpressExtension.commands.cpx.closeSerialMonitor": "[Circuit Playground Express] Close Serial Monitor", + "deviceSimulatorExpressExtension.commands.cpx.openSerialMonitor": "[Circuit Playground Express] Open Serial Monitor", + "deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator", + "deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File", + "deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device", + "deviceSimulatorExpressExtension.commands.cpx.selectSerialPort": "[Circuit Playground Express] Select Serial Port", + "deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator", + "deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File", "deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration", - "deviceSimulatorExpressExtension.configuration.properties.open": "Whether to show 'Open Simulator' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.device": "Whether to show 'Run Device' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.simulator": "Whether to show 'Run Simulator' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger." + "deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.", + "deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.", + "deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask if we can download dependencies. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files." + "deviceSimulatorExpressExtension.configuration.properties.previewMode": "Enable this to test out and play with the new micro:bit simulator!" } diff --git a/package-lock.json b/package-lock.json index 87a51978c..7b8613ef0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,17 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/compat-data": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.5.tgz", + "integrity": "sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, "@babel/core": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz", @@ -73,351 +84,392 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-react-jsx": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", - "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz", + "integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==", "dev": true, "requires": { - "@babel/types": "^7.3.0", + "@babel/types": "^7.8.3", "esutils": "^2.0.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-call-delegate": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", - "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", - "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", - "@babel/helper-split-export-declaration": "^7.4.4" - } - }, - "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@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==", - "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==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", - "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "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==" - }, - "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, - "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz", + "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } - }, - "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, "requires": { - "color-convert": "^1.9.0" + "@babel/highlight": "^7.8.3" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, "requires": { - "has-flag": "^3.0.0" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } - } - } - }, - "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz", - "integrity": "sha512-t2ECPNOXsIeK1JxJNKmgbzQtoG27KIlVE61vTqX0DKR9E9sZlVVxWUtEW9D5FlZ8b8j7SBNCHY47GgPKCKlpPg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.0.tgz", - "integrity": "sha512-d08TLmXeK/XbgCo7ZeZ+JaeZDtDai/2ctapTRsWWkkmy7G/cqz8DQN/HlWG7RR4YmfXxmExsbU3SuCjlM7AtUg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-decorators": "^7.2.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.2.0" + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", - "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "@babel/helper-compilation-targets": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz", + "integrity": "sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + "@babel/compat-data": "^7.8.4", + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "@babel/helper-create-class-features-plugin": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz", + "integrity": "sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz", + "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.6.0" }, "dependencies": { "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", "dev": true, "requires": { "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", + "regenerate-unicode-properties": "^8.1.0", "regjsgen": "^0.5.0", "regjsparser": "^0.6.0", "unicode-match-property-ecmascript": "^1.0.4", @@ -425,15 +477,15 @@ } }, "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", "dev": true }, "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", + "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -441,526 +493,140 @@ } } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-bigint": { + "@babel/helper-define-map": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" - } - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz", - "integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", - "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", - "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@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==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz", - "integrity": "sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" }, "dependencies": { - "@babel/helper-plugin-utils": { + "@babel/code-frame": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" - } - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", - "@babel/helper-split-export-declaration": "^7.4.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - }, - "dependencies": { - "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" + "@babel/highlight": "^7.8.3" } }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", "dev": true }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", "dev": true, "requires": { - "jsesc": "~0.5.0" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.0.tgz", - "integrity": "sha512-C4ZVNejHnfB22vI2TYN4RUp2oCmq6cSEAg4RygSvYZUECRqUu9O4PMEMNJ4wsemaRGg27BbgYctG4BZh+AgIHw==", + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.2.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", - "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", - "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", - "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", - "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.6" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", - "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.2.0.tgz", - "integrity": "sha512-YYQFg6giRFMsZPKUM9v+VcHOdfSQdz9jHCx3akAi3UYgyjndmdYGSXylQ/V+HswQt4fL8IklchD9HTsaOCrWQQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", - "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", - "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.3.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", - "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", - "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", - "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", - "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.3.tgz", - "integrity": "sha512-7Q61bU+uEI7bCUFReT1NKn7/X6sDQsZ7wL1sJ9IYMAO7cI+eg6x9re1cEw2fCRMbbTVyoeUKWSV1M6azEfKCfg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.3.tgz", - "integrity": "sha512-Ebj230AxcrKGZPKIp4g4TdQLrqX95TobLUWKd/CwG7X1XHUH1ZpkpFvXuXqWbtGRWb7uuEWNlrl681wsOArAdQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-typescript": "^7.8.3" + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" }, "dependencies": { "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, "requires": { "@babel/highlight": "^7.8.3" } }, "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, "requires": { "@babel/types": "^7.8.3", "jsesc": "^2.5.1", @@ -968,23 +634,11 @@ "source-map": "^0.5.0" } }, - "@babel/helper-create-class-features-plugin": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz", - "integrity": "sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==", - "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3" - } - }, "@babel/helper-function-name": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", @@ -995,46 +649,16 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" - }, - "@babel/helper-replace-supers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", - "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -1043,6 +667,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -1050,14 +675,16 @@ } }, "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==" + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true }, "@babel/template": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.3", @@ -1065,15 +692,16 @@ } }, "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", + "@babel/generator": "^7.8.4", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", + "@babel/parser": "^7.8.4", "@babel/types": "^7.8.3", "debug": "^4.1.0", "globals": "^11.1.0", @@ -1084,6 +712,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -1094,6 +723,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1102,6 +732,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1111,208 +742,2583 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "@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==", + "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==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "@babel/types": "^7.8.3" }, "dependencies": { - "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", "dev": true, "requires": { - "jsesc": "~0.5.0" + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } } } }, - "@babel/preset-env": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz", - "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==", + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.4.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.4.4", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.4.4", - "@babel/plugin-transform-classes": "^7.4.4", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.4", - "@babel/plugin-transform-function-name": "^7.4.4", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@babel/plugin-transform-modules-systemjs": "^7.4.4", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", - "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.4.4", - "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.5", - "@babel/plugin-transform-reserved-words": "^7.2.0", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "browserslist": "^4.6.0", - "core-js-compat": "^3.1.1", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-react-display-name": "^7.0.0", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/plugin-transform-react-jsx-self": "^7.0.0", - "@babel/plugin-transform-react-jsx-source": "^7.0.0" + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/preset-typescript": { + "@babel/helper-module-transforms": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.8.3.tgz", - "integrity": "sha512-qee5LgPGui9zQ0jR1TeU5/fP9L+ovoArklEqY12ek8P/wV5ZeM/VYSQYwICeoT6FfpJTekG9Ilay5PhwsOpMHA==", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz", + "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==", + "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-transform-typescript": "^7.8.3" + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" }, "dependencies": { - "@babel/helper-plugin-utils": { + "@babel/code-frame": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "@babel/runtime": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz", - "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==", + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } + "@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==" }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" + "lodash": "^4.17.13" } }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", + "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz", + "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-decorators": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + } + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", + "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz", + "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + } + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz", + "integrity": "sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz", + "integrity": "sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", + "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/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==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz", + "integrity": "sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + } + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-classes": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz", + "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz", + "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.8.3.tgz", + "integrity": "sha512-g/6WTWG/xbdd2exBBzMfygjX/zw4eyNC4X8pRaq7aRHRoDUCzAIu3kGYIXviOv8BjCuWm8vDBwjHcjiRNgXrPA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-flow": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz", + "integrity": "sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", + "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", + "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", + "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", + "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", + "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.8.3", + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.8.3.tgz", + "integrity": "sha512-glrzN2U+egwRfkNFtL34xIBYTxbbUF2qJTP8HD3qETBBqzAWSeNB821X0GjU06+dNpq/UyCIjI72FmGE5NNkQQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", + "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz", + "integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.8.3.tgz", + "integrity": "sha512-01OT7s5oa0XTLf2I8XGsL8+KqV9lx3EZV+jxn/L2LQ97CGKila2YMroTkCEIE0HV/FF7CMSRsIAybopdN9NTdg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz", + "integrity": "sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz", + "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz", + "integrity": "sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "resolve": "^1.8.1", + "semver": "^5.5.1" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.3.tgz", + "integrity": "sha512-Ebj230AxcrKGZPKIp4g4TdQLrqX95TobLUWKd/CwG7X1XHUH1ZpkpFvXuXqWbtGRWb7uuEWNlrl681wsOArAdQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-typescript": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", + "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz", + "integrity": "sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + }, + "@babel/helper-replace-supers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", + "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", + "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==" + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", + "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/preset-env": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.4.tgz", + "integrity": "sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.4", + "@babel/helper-compilation-targets": "^7.8.4", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.3", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.4", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.8.3", + "@babel/plugin-transform-modules-systemjs": "^7.8.3", + "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.4", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.3", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/types": "^7.8.3", + "browserslist": "^4.8.5", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/preset-react": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.8.3.tgz", + "integrity": "sha512-9hx0CwZg92jGb7iHYQVgi0tOEHP/kM60CtWJQnmbATSPIQQ2xYzfoCI3EdqAhFBeeJwYMdWQuDUHMsuDbH9hyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.8.3", + "@babel/plugin-transform-react-jsx-self": "^7.8.3", + "@babel/plugin-transform-react-jsx-source": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/preset-typescript": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.8.3.tgz", + "integrity": "sha512-qee5LgPGui9zQ0jR1TeU5/fP9L+ovoArklEqY12ek8P/wV5ZeM/VYSQYwICeoT6FfpJTekG9Ilay5PhwsOpMHA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-typescript": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" + } + } + }, + "@babel/runtime": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", + "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@cnakazawa/watch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", + "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } }, "@csstools/convert-colors": { "version": "1.4.0", @@ -1321,209 +3327,884 @@ "dev": true }, "@csstools/normalize.css": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-9.0.1.tgz", - "integrity": "sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", + "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==", + "dev": true + }, + "@formatjs/intl-relativetimeformat": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-2.8.0.tgz", + "integrity": "sha512-5T3m5hJSxXrbwtnFHyYBSbTjOXPXu+4NJ0MUu1LAf4fPEdd+pJZfWKuMJSWgFQPVMbLYq9NLvDWQda3hVe99sg==" + }, + "@gulp-sourcemaps/identity-map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", + "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "dev": true, + "requires": { + "acorn": "^5.0.3", + "css": "^2.2.1", + "normalize-path": "^2.1.1", + "source-map": "^0.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + } + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + } + }, + "@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "dev": true + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "dev": true + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", "dev": true }, - "@formatjs/intl-relativetimeformat": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-2.8.0.tgz", - "integrity": "sha512-5T3m5hJSxXrbwtnFHyYBSbTjOXPXu+4NJ0MUu1LAf4fPEdd+pJZfWKuMJSWgFQPVMbLYq9NLvDWQda3hVe99sg==" + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "dev": true, + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "dev": true, + "requires": { + "@hapi/hoek": "^8.3.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", + "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, + "@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@jest/core": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz", + "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==", + "requires": { + "@jest/console": "^25.1.0", + "@jest/reporters": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.3", + "jest-changed-files": "^25.1.0", + "jest-config": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-resolve-dependencies": "^25.1.0", + "jest-runner": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "jest-watcher": "^25.1.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^1.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "@jest/console": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", + "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", + "requires": { + "@jest/source-map": "^25.1.0", + "chalk": "^3.0.0", + "jest-util": "^25.1.0", + "slash": "^3.0.0" + } + }, + "@jest/source-map": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", + "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.3", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", + "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", + "requires": { + "@jest/console": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "ansi-escapes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "requires": { + "type-fest": "^0.8.1" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-message-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", + "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-resolve": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", + "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", + "requires": { + "@jest/types": "^25.1.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", + "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "requires": { + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1" + } + }, + "jest-watcher": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", + "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==", + "requires": { + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.1.0", + "string-length": "^3.1.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + } + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/environment": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz", + "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==", + "requires": { + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0" + }, + "dependencies": { + "@jest/console": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", + "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", + "requires": { + "@jest/source-map": "^25.1.0", + "chalk": "^3.0.0", + "jest-util": "^25.1.0", + "slash": "^3.0.0" + } + }, + "@jest/fake-timers": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz", + "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==", + "requires": { + "@jest/types": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^25.1.0", + "lolex": "^5.0.0" + } + }, + "@jest/source-map": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", + "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.3", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", + "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", + "requires": { + "@jest/console": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-message-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", + "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz", + "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==", + "requires": { + "@jest/types": "^25.1.0" + } + }, + "jest-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", + "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "requires": { + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } }, - "@gulp-sourcemaps/identity-map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", - "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", "dev": true, "requires": { - "acorn": "^5.0.3", - "css": "^2.2.1", - "normalize-path": "^2.1.1", - "source-map": "^0.6.0", - "through2": "^2.0.3" + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.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 + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } } } }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - } - }, - "@hapi/address": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", - "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==", - "dev": true - }, - "@hapi/hoek": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-6.2.4.tgz", - "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==", - "dev": true - }, - "@hapi/joi": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.0.3.tgz", - "integrity": "sha512-z6CesJ2YBwgVCi+ci8SI8zixoj8bGFn/vZb9MBPbSyoxsS2PnWYjHcyTM17VLK6tx64YVK38SDIh10hJypB+ig==", - "dev": true, - "requires": { - "@hapi/address": "2.x.x", - "@hapi/hoek": "6.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.0.tgz", - "integrity": "sha512-gZDI/eXOIk8kP2PkUKjWu9RW8GGVd2Hkgjxyr/S7Z+JF+0mr7bAlbw+DkTRxnD580o8Kqxlnba9wvqp5aOHBww==", - "dev": true, - "requires": { - "@hapi/hoek": "6.x.x" - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "@jest/reporters": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", + "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.0", + "jest-haste-map": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.0.1" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", + "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helpers": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", + "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "requires": { - "p-locate": "^4.1.0" + "@babel/types": "^7.8.3" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "requires": { - "p-limit": "^2.2.0" + "@babel/types": "^7.8.3" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "@babel/helpers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", + "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" - }, - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "requires": { - "color-convert": "^1.9.0" + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "@babel/parser": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", + "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==" + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "@babel/traverse": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", + "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", "requires": { - "has-flag": "^3.0.0" + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" } - } - } - }, - "@jest/core": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz", - "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==", - "requires": { - "@jest/console": "^25.1.0", - "@jest/reporters": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-changed-files": "^25.1.0", - "jest-config": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-resolve-dependencies": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "jest-watcher": "^25.1.0", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "realpath-native": "^1.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "@jest/console": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", @@ -1557,14 +4238,6 @@ "collect-v8-coverage": "^1.0.0" } }, - "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", - "requires": { - "type-fest": "^0.8.1" - } - }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -1579,14 +4252,6 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1614,12 +4279,12 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "requires": { - "to-regex-range": "^5.0.1" + "safe-buffer": "~5.1.1" } }, "graceful-fs": { @@ -1632,24 +4297,23 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "jest-message-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", - "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz", + "integrity": "sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==", "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" + "@babel/core": "^7.7.5", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" } }, "jest-resolve": { @@ -1675,28 +4339,24 @@ "mkdirp": "^0.5.1" } }, - "jest-watcher": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", - "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==", - "requires": { - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "string-length": "^3.1.0" - } + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "minimist": "^1.2.0" } }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -1709,31 +4369,14 @@ "requires": { "astral-regex": "^1.0.0", "strip-ansi": "^5.2.0" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - } + "ansi-regex": "^4.1.0" } }, "supports-color": { @@ -1743,25 +4386,61 @@ "requires": { "has-flag": "^4.0.0" } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + } + } + }, + "@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, "requires": { - "is-number": "^7.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" } } } }, - "@jest/environment": { + "@jest/test-sequencer": { "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz", - "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", + "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", "requires": { - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0" + "@jest/test-result": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-runner": "^25.1.0", + "jest-runtime": "^25.1.0" }, "dependencies": { "@jest/console": { @@ -1775,18 +4454,6 @@ "slash": "^3.0.0" } }, - "@jest/fake-timers": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz", - "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==", - "requires": { - "@jest/types": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0", - "lolex": "^5.0.0" - } - }, "@jest/source-map": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", @@ -1818,14 +4485,6 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1853,14 +4512,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -1871,34 +4522,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "jest-message-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", - "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz", - "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==", - "requires": { - "@jest/types": "^25.1.0" - } - }, "jest-util": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", @@ -1910,15 +4533,6 @@ "mkdirp": "^0.5.1" } }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -1931,81 +4545,30 @@ "requires": { "has-flag": "^4.0.0" } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } } } }, - "@jest/reporters": { + "@jest/transform": { "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", - "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", + "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", + "@babel/core": "^7.1.0", + "@jest/types": "^25.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.3", "jest-haste-map": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-runtime": "^25.1.0", + "jest-regex-util": "^25.1.0", "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", - "node-notifier": "^6.0.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^3.1.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.0.1" + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "dependencies": { "@babel/code-frame": { @@ -2016,40 +4579,6 @@ "@babel/highlight": "^7.8.3" } }, - "@babel/core": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, "@babel/generator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", @@ -2114,14 +4643,6 @@ "js-tokens": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2131,32 +4652,6 @@ "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -2201,58 +4696,34 @@ "to-fast-properties": "^2.0.0" } }, - "@jest/console": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", - "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", - "requires": { - "@jest/source-map": "^25.1.0", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "slash": "^3.0.0" - } - }, - "@jest/source-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", - "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" + "color-convert": "^1.9.0" } }, - "@jest/test-result": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", - "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "requires": { - "@jest/console": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" } }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "fill-range": "^7.0.1" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -2260,14 +4731,38 @@ "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "color-name": { @@ -2275,12 +4770,12 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "safe-buffer": "~5.1.1" + "to-regex-range": "^5.0.1" } }, "graceful-fs": { @@ -2288,10 +4783,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "istanbul-lib-coverage": { "version": "3.0.0", @@ -2310,18 +4805,50 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" - } - }, - "jest-resolve": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", - "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", - "requires": { - "@jest/types": "^25.1.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + }, + "dependencies": { + "@babel/core": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", + "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helpers": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "jest-util": { @@ -2348,6 +4875,15 @@ "minimist": "^1.2.0" } }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2358,127 +4894,62 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, - "string-length": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", - "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" + "has-flag": "^3.0.0" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "requires": { - "ansi-regex": "^4.1.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/source-map": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", - "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" + "is-number": "^7.0.0" } }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, + "write-file-atomic": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", + "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", "requires": { - "@types/yargs-parser": "*" + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } } } }, - "@jest/test-sequencer": { + "@jest/types": { "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", - "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", + "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", "requires": { - "@jest/test-result": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "dependencies": { - "@jest/console": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", - "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", - "requires": { - "@jest/source-map": "^25.1.0", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "slash": "^3.0.0" - } - }, - "@jest/source-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", - "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", - "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", + "@types/yargs": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.1.tgz", + "integrity": "sha512-sYlwNU7zYi6eZbMzFvG6eHD7VsEvFdoDtlD7eI1JTg7YNnuguzmiGsc6MPSq5l8n+h21AsNof0je+9sgOe4+dg==", "requires": { - "@jest/console": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/yargs-parser": "*" } }, "ansi-styles": { @@ -2490,11 +4961,6 @@ "color-convert": "^2.0.1" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -2517,32 +4983,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "jest-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", - "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", - "requires": { - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -2553,59 +4998,185 @@ } } }, - "@jest/transform": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", - "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", + "@microsoft/load-themed-styles": { + "version": "1.10.36", + "resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.36.tgz", + "integrity": "sha512-xsBSgHhUbivT6cHqw5UP567fa+yJ1gM/L9CDnYftTmeruxpDUsLiK1sPrWeyMc+5VSaxcd+lsY10vqDVEptxoA==" + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@sheerun/mutationobserver-shim": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz", + "integrity": "sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==" + }, + "@sinonjs/commons": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", + "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", + "integrity": "sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz", + "integrity": "sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz", + "integrity": "sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w==", + "dev": true + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz", + "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==", + "dev": true + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz", + "integrity": "sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w==", + "dev": true + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz", + "integrity": "sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w==", + "dev": true + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz", + "integrity": "sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw==", + "dev": true + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz", + "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==", + "dev": true + }, + "@svgr/babel-preset": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.3.tgz", + "integrity": "sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A==", + "dev": true, + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0", + "@svgr/babel-plugin-svg-dynamic-title": "^4.3.3", + "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0", + "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0", + "@svgr/babel-plugin-transform-svg-component": "^4.2.0" + } + }, + "@svgr/core": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.3.tgz", + "integrity": "sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==", + "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.1.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-util": "^25.1.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "@svgr/plugin-jsx": "^4.3.3", + "camelcase": "^5.3.1", + "cosmiconfig": "^5.2.1" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz", + "integrity": "sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@svgr/plugin-jsx": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz", + "integrity": "sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==", + "dev": true, + "requires": { + "@babel/core": "^7.4.5", + "@svgr/babel-preset": "^4.3.3", + "@svgr/hast-util-to-babel-ast": "^4.3.2", + "svg-parser": "^2.0.0" }, "dependencies": { "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, "requires": { "@babel/highlight": "^7.8.3" } }, + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, "requires": { "@babel/types": "^7.8.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } } }, "@babel/helper-function-name": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", @@ -2616,6 +5187,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -2624,17 +5196,19 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helpers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", - "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", + "@babel/traverse": "^7.8.4", "@babel/types": "^7.8.3" } }, @@ -2642,33 +5216,24 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } } }, "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==" + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true }, "@babel/template": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.3", @@ -2676,15 +5241,16 @@ } }, "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", + "@babel/generator": "^7.8.4", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", + "@babel/parser": "^7.8.4", "@babel/types": "^7.8.3", "debug": "^4.1.0", "globals": "^11.1.0", @@ -2695,6 +5261,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -2705,458 +5272,291 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-instrument": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz", - "integrity": "sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==", + "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": { - "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "@babel/core": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "jest-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", - "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, "requires": { - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1" + "safe-buffer": "~5.1.1" } }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json5": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, "requires": { "minimist": "^1.2.0" } }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } + } + } + }, + "@svgr/plugin-svgo": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz", + "integrity": "sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==", + "dev": true, + "requires": { + "cosmiconfig": "^5.2.1", + "merge-deep": "^3.0.2", + "svgo": "^1.2.2" + } + }, + "@svgr/webpack": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-4.3.3.tgz", + "integrity": "sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg==", + "dev": true, + "requires": { + "@babel/core": "^7.4.5", + "@babel/plugin-transform-react-constant-elements": "^7.0.0", + "@babel/preset-env": "^7.4.5", + "@babel/preset-react": "^7.0.0", + "@svgr/core": "^4.3.3", + "@svgr/plugin-jsx": "^4.3.3", + "@svgr/plugin-svgo": "^4.3.1", + "loader-utils": "^1.2.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, "requires": { - "is-number": "^7.0.0" + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" } }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } - } - } - }, - "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "dependencies": { - "@types/yargs": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.1.tgz", - "integrity": "sha512-sYlwNU7zYi6eZbMzFvG6eHD7VsEvFdoDtlD7eI1JTg7YNnuguzmiGsc6MPSq5l8n+h21AsNof0je+9sgOe4+dg==", + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, "requires": { - "@types/yargs-parser": "*" + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "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": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, "requires": { - "color-name": "~1.1.4" + "safe-buffer": "~5.1.1" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } } } }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "@sheerun/mutationobserver-shim": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz", - "integrity": "sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==" - }, - "@sinonjs/commons": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", - "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", - "requires": { - "type-detect": "4.0.8" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", - "integrity": "sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig==", - "dev": true - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz", - "integrity": "sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ==", - "dev": true - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz", - "integrity": "sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w==", - "dev": true - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz", - "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==", - "dev": true - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.0.tgz", - "integrity": "sha512-3eI17Pb3jlg3oqV4Tie069n1SelYKBUpI90txDcnBWk4EGFW+YQGyQjy6iuJAReH0RnpUJ9jUExrt/xniGvhqw==", - "dev": true - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz", - "integrity": "sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w==", - "dev": true - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz", - "integrity": "sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw==", - "dev": true - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz", - "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==", - "dev": true - }, - "@svgr/babel-preset": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.0.tgz", - "integrity": "sha512-Lgy1RJiZumGtv6yJroOxzFuL64kG/eIcivJQ7y9ljVWL+0QXvFz4ix1xMrmjMD+rpJWwj50ayCIcFelevG/XXg==", - "dev": true, - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0", - "@svgr/babel-plugin-svg-dynamic-title": "^4.3.0", - "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0", - "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0", - "@svgr/babel-plugin-transform-svg-component": "^4.2.0" - } - }, - "@svgr/core": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.0.tgz", - "integrity": "sha512-Ycu1qrF5opBgKXI0eQg3ROzupalCZnSDETKCK/3MKN4/9IEmt3jPX/bbBjftklnRW+qqsCEpO0y/X9BTRw2WBg==", - "dev": true, - "requires": { - "@svgr/plugin-jsx": "^4.3.0", - "camelcase": "^5.3.1", - "cosmiconfig": "^5.2.0" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.2.0.tgz", - "integrity": "sha512-IvAeb7gqrGB5TH9EGyBsPrMRH/QCzIuAkLySKvH2TLfLb2uqk98qtJamordRQTpHH3e6TORfBXoTo7L7Opo/Ow==", - "dev": true, - "requires": { - "@babel/types": "^7.4.0" - } - }, - "@svgr/plugin-jsx": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.0.tgz", - "integrity": "sha512-0ab8zJdSOTqPfjZtl89cjq2IOmXXUYV3Fs7grLT9ur1Al3+x3DSp2+/obrYKUGbQUnLq96RMjSZ7Icd+13vwlQ==", - "dev": true, - "requires": { - "@babel/core": "^7.4.3", - "@svgr/babel-preset": "^4.3.0", - "@svgr/hast-util-to-babel-ast": "^4.2.0", - "rehype-parse": "^6.0.0", - "unified": "^7.1.0", - "vfile": "^4.0.0" - } - }, - "@svgr/plugin-svgo": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.2.0.tgz", - "integrity": "sha512-zUEKgkT172YzHh3mb2B2q92xCnOAMVjRx+o0waZ1U50XqKLrVQ/8dDqTAtnmapdLsGurv8PSwenjLCUpj6hcvw==", - "dev": true, - "requires": { - "cosmiconfig": "^5.2.0", - "merge-deep": "^3.0.2", - "svgo": "^1.2.1" - } - }, - "@svgr/webpack": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-4.1.0.tgz", - "integrity": "sha512-d09ehQWqLMywP/PT/5JvXwPskPK9QCXUjiSkAHehreB381qExXf5JFCBWhfEyNonRbkIneCeYM99w+Ud48YIQQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.6", - "@babel/plugin-transform-react-constant-elements": "^7.0.0", - "@babel/preset-env": "^7.1.6", - "@babel/preset-react": "^7.0.0", - "@svgr/core": "^4.1.0", - "@svgr/plugin-jsx": "^4.1.0", - "@svgr/plugin-svgo": "^4.0.3", - "loader-utils": "^1.1.0" - } - }, "@testing-library/dom": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-6.11.0.tgz", @@ -3295,6 +5695,12 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -3356,6 +5762,12 @@ "jest-diff": "^24.3.0" } }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -3375,10 +5787,16 @@ "@types/node": "*" } }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, "@types/prop-types": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", - "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==" + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/q": { "version": "1.5.2", @@ -3387,9 +5805,9 @@ "dev": true }, "@types/react": { - "version": "16.8.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.18.tgz", - "integrity": "sha512-lUXdKzRqWR4FebR5tGHkLCqnvQJS4fdXKCBrNGGbglqZg2gpU+J82pMONevQODUotATs9fc9k66bx3/St8vReg==", + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.6.tgz", + "integrity": "sha512-bN9qDjEMltmHrl0PZRI4IF2AbB7V5UlRfG+OOduckVnRQ4VzXVSzy/1eLAh778IEqhTnW0mmgL9yShfinNverA==", "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" @@ -3403,6 +5821,14 @@ "@types/react": "*" } }, + "@types/react-test-renderer": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-16.9.2.tgz", + "integrity": "sha512-4eJr1JFLIAlWhzDkBCkhrOIWOvOxcCAfQh+jiKg7l/nNZcCIL2MHl2dZhogIFKyHzedVWHaVP1Yydq/Ruu4agw==", + "requires": { + "@types/react": "*" + } + }, "@types/socket.io": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.2.tgz", @@ -3441,33 +5867,6 @@ "@types/testing-library__dom": "*" } }, - "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", - "dev": true - }, - "@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "@types/vfile-message": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz", - "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/unist": "*" - } - }, "@types/vscode": { "version": "1.36.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.36.0.tgz", @@ -3475,10 +5874,13 @@ "dev": true }, "@types/yargs": { - "version": "12.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.12.tgz", - "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==", - "dev": true + "version": "13.0.8", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", + "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } }, "@types/yargs-parser": { "version": "15.0.0", @@ -3486,43 +5888,208 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" }, "@typescript-eslint/eslint-plugin": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz", - "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.20.0.tgz", + "integrity": "sha512-cimIdVDV3MakiGJqMXw51Xci6oEDEoPkvh8ggJe2IIzcc0fYqAxOXN6Vbeanahz6dLZq64W+40iUEc9g32FLDQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.20.0", + "eslint-utils": "^1.4.3", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.20.0.tgz", + "integrity": "sha512-fEBy9xYrwG9hfBLFEwGW2lKwDRTmYzH3DwTmYbT+SMycmxAoPl0eGretnBFj/s+NfYBG63w/5c3lsvqqz5mYag==", "dev": true, "requires": { - "@typescript-eslint/parser": "1.6.0", - "@typescript-eslint/typescript-estree": "1.6.0", - "requireindex": "^1.2.0", - "tsutils": "^3.7.0" + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.20.0", + "eslint-scope": "^5.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } } }, "@typescript-eslint/parser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz", - "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.20.0.tgz", + "integrity": "sha512-o8qsKaosLh2qhMZiHNtaHKTHyCHc3Triq6aMnwnWj7budm3xAY9owSZzV1uon5T9cWmJRJGzTFa90aex4m77Lw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "1.6.0", - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0" + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.20.0", + "@typescript-eslint/typescript-estree": "2.20.0", + "eslint-visitor-keys": "^1.1.0" } }, "@typescript-eslint/typescript-estree": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz", - "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.20.0.tgz", + "integrity": "sha512-WlFk8QtI8pPaE7JGQGxU7nGcnk1ccKAJkhbVookv94ZcAef3m6oCE/jEDL6dGte3JcD7reKrA0o55XhBRiVT3A==", "dev": true, "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@uifabric/foundation": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@uifabric/foundation/-/foundation-7.5.3.tgz", + "integrity": "sha512-LCUETWPkTOjJ0LeP7/fyfpVt8MTzdb41LgV+n3rmKo809R1NjDyG62xX/f7DOLaEvJIO10f8h8I8vilYmUoCRg==", + "requires": { + "@uifabric/merge-styles": "^7.8.3", + "@uifabric/set-version": "^7.0.3", + "@uifabric/styling": "^7.10.2", + "@uifabric/utilities": "^7.11.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/icons": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@uifabric/icons/-/icons-7.3.2.tgz", + "integrity": "sha512-ZqlRBkFporJWHusvAzXI3ye99B/pKN/mGmHbMZtAPoGSFSge3ahv3GzQA8IvamrrHdf5j2OwCZR7db9BJvOOzA==", + "requires": { + "@uifabric/set-version": "^7.0.3", + "@uifabric/styling": "^7.10.2", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/merge-styles": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@uifabric/merge-styles/-/merge-styles-7.8.3.tgz", + "integrity": "sha512-mMLXIKmB7NH2ss6k7I4o7kE7Dy9+vcgubkxNVsgzBdV9vlDtnMDMc6/nZjOxgmBAr1UCRxCxERaKSB1oNFxtAg==", + "requires": { + "@uifabric/set-version": "^7.0.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/react-hooks": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@uifabric/react-hooks/-/react-hooks-7.0.3.tgz", + "integrity": "sha512-ANkdK7ckRfljl4CKHDoW4H2DfTqRJ4QqTM7VD3IddcbZwBlvyhbRJO3sxnBigdBW5An7qdsJeZuOEoRjhm9e+Q==", + "requires": { + "@uifabric/set-version": "^7.0.3", + "@uifabric/utilities": "^7.11.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/set-version": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@uifabric/set-version/-/set-version-7.0.3.tgz", + "integrity": "sha512-03A68Fyfx3y75dUW9rjQ2fZv/9zmGgMeovVLAQa0wc/oVjQ++eVDlAEK0AjfgnOaujYmhk79lXbYAuW3n+YUXw==", + "requires": { + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/styling": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@uifabric/styling/-/styling-7.10.2.tgz", + "integrity": "sha512-a4BCtbm273s2997wZwBkOeWNm2lzUr6eVzE+CmShUVxXWAMPXI5ZZS6SZ4LpZkDkhdItLnNq+VODSJ7M/VM0aw==", + "requires": { + "@microsoft/load-themed-styles": "^1.10.26", + "@uifabric/merge-styles": "^7.8.3", + "@uifabric/set-version": "^7.0.3", + "@uifabric/utilities": "^7.11.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@uifabric/utilities": { + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/@uifabric/utilities/-/utilities-7.11.3.tgz", + "integrity": "sha512-y/2H65F41Q3DU4GQJFWj6x09qfjMYcwutHkU7sm2r0h82K01u5qeCPkPV9RqGGsJOrqllvsR5BoaRP77a1ot8A==", + "requires": { + "@uifabric/merge-styles": "^7.8.3", + "@uifabric/set-version": "^7.0.3", + "prop-types": "^15.5.10", + "tslib": "^1.10.0" }, "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" } } }, @@ -3749,9 +6316,9 @@ } }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "acorn-walk": { @@ -3760,11 +6327,56 @@ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" }, "address": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", - "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, + "adjust-sourcemap-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", + "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", + "dev": true, + "requires": { + "assert": "1.4.1", + "camelcase": "5.0.0", + "loader-utils": "1.2.3", + "object-path": "0.11.4", + "regex-parser": "2.2.10" + }, + "dependencies": { + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", @@ -3779,6 +6391,16 @@ "es6-promisify": "^5.0.0" } }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -3824,10 +6446,13 @@ } }, "ansi-escapes": { - "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 + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } }, "ansi-gray": { "version": "0.1.1", @@ -3926,6 +6551,12 @@ "commander": "^2.11.0" } }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=", + "dev": true + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -3989,13 +6620,67 @@ "dev": true }, "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + } } }, "array-initial": { @@ -4090,6 +6775,69 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + } + } + }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -4174,10 +6922,13 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } }, "async-done": { "version": "1.3.2", @@ -4222,17 +6973,18 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.1.tgz", - "integrity": "sha512-KJSzkStUl3wP0D5sdMlP82Q52JLy5+atf2MHAre48+ckWkXgixmfHyWmA77wFDy6jTHU6mIgXv6hAQ2mf1PjJQ==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", + "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", "dev": true, "requires": { - "browserslist": "^4.5.4", - "caniuse-lite": "^1.0.30000957", + "browserslist": "^4.8.3", + "caniuse-lite": "^1.0.30001020", + "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.14", - "postcss-value-parser": "^3.3.1" + "postcss": "^7.0.26", + "postcss-value-parser": "^4.0.2" }, "dependencies": { "ansi-styles": { @@ -4253,12 +7005,23 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + } + }, + "postcss": { + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" }, "dependencies": { "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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" @@ -4266,21 +7029,16 @@ } } }, - "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } + "postcss-value-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", + "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", + "dev": true }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -4299,13 +7057,10 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", + "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==", + "dev": true }, "azure-devops-node-api": { "version": "7.2.0", @@ -4339,27 +7094,26 @@ } }, "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.0.0", "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" }, "dependencies": { - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "path-parse": "^1.0.6" } } } @@ -4850,32 +7604,41 @@ } }, "babel-loader": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz", - "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", "dev": true, "requires": { "find-cache-dir": "^2.0.0", "loader-utils": "^1.0.2", "mkdirp": "^0.5.1", - "util.promisify": "^1.0.0" + "pify": "^4.0.1" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } } }, "babel-plugin-dynamic-import-node": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz", - "integrity": "sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", "dev": true, "requires": { "object.assign": "^4.1.0" } }, "babel-plugin-istanbul": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz", - "integrity": "sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", "dev": true, "requires": { + "@babel/helper-plugin-utils": "^7.0.0", "find-up": "^3.0.0", "istanbul-lib-instrument": "^3.3.0", "test-exclude": "^5.2.3" @@ -4890,20 +7653,78 @@ } }, "babel-plugin-macros": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz", - "integrity": "sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", "dev": true, "requires": { - "@babel/runtime": "^7.4.2", - "cosmiconfig": "^5.2.0", - "resolve": "^1.10.0" + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } } }, "babel-plugin-named-asset-import": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.2.tgz", - "integrity": "sha512-CxwvxrZ9OirpXQ201Ec57OmGhmI8/ui/GwTDy0hSp6CmRvgRC0pSair6Z04Ck+JStA0sMPZzSJ3uE4n17EXpPQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz", + "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==", "dev": true }, "babel-plugin-syntax-object-rest-spread": { @@ -4939,130 +7760,223 @@ } }, "babel-preset-react-app": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-9.0.0.tgz", - "integrity": "sha512-YVsDA8HpAKklhFLJtl9+AgaxrDaor8gGvDFlsg1ByOS0IPGUovumdv4/gJiAnLcDmZmKlH6+9sVOz4NVW7emAg==", - "dev": true, - "requires": { - "@babel/core": "7.4.3", - "@babel/plugin-proposal-class-properties": "7.4.0", - "@babel/plugin-proposal-decorators": "7.4.0", - "@babel/plugin-proposal-object-rest-spread": "7.4.3", - "@babel/plugin-syntax-dynamic-import": "7.2.0", - "@babel/plugin-transform-classes": "7.4.3", - "@babel/plugin-transform-destructuring": "7.4.3", - "@babel/plugin-transform-flow-strip-types": "7.4.0", - "@babel/plugin-transform-react-constant-elements": "7.2.0", - "@babel/plugin-transform-react-display-name": "7.2.0", - "@babel/plugin-transform-runtime": "7.4.3", - "@babel/preset-env": "7.4.3", - "@babel/preset-react": "7.0.0", - "@babel/preset-typescript": "7.3.3", - "@babel/runtime": "7.4.3", - "babel-plugin-dynamic-import-node": "2.2.0", - "babel-plugin-macros": "2.5.1", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-9.1.1.tgz", + "integrity": "sha512-YkWP2UwY//TLltNlEBRngDOrYhvSLb+CA330G7T9M5UhGEMWe+JK/8IXJc5p2fDTSfSiETf+PY0+PYXFMix81Q==", + "dev": true, + "requires": { + "@babel/core": "7.8.4", + "@babel/plugin-proposal-class-properties": "7.8.3", + "@babel/plugin-proposal-decorators": "7.8.3", + "@babel/plugin-proposal-numeric-separator": "7.8.3", + "@babel/plugin-transform-flow-strip-types": "7.8.3", + "@babel/plugin-transform-react-display-name": "7.8.3", + "@babel/plugin-transform-runtime": "7.8.3", + "@babel/preset-env": "7.8.4", + "@babel/preset-react": "7.8.3", + "@babel/preset-typescript": "7.8.3", + "@babel/runtime": "7.8.4", + "babel-plugin-macros": "2.8.0", "babel-plugin-transform-react-remove-prop-types": "0.4.24" }, "dependencies": { - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz", - "integrity": "sha512-xC//6DNSSHVjq8O2ge0dyYlhshsH4T7XdCVoxbi5HzLYWfsC5ooFlJjrXk8RcAT+hjHAK9UjBXdylzSoDK3t4g==", + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + "@babel/types": "^7.8.3" } }, - "@babel/plugin-transform-classes": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz", - "integrity": "sha512-PUaIKyFUDtG6jF5DUJOfkBdwAS/kFFV3XFk7Nn0a6vR7ZT8jYw5cGtIlat77wcnd0C6ViGqo/wyNf4ZHytF/nQ==", + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.0", - "@babel/helper-split-export-declaration": "^7.4.0", - "globals": "^11.1.0" + "@babel/types": "^7.8.3" } }, - "@babel/plugin-transform-destructuring": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz", - "integrity": "sha512-rVTLLZpydDFDyN4qnXdzwoVpk1oaXHIvPEOkOLyr88o7oHxVc/LyrnDx+amuBWGOwUb7D1s/uLsKBNTx08htZg==", + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" } }, - "@babel/preset-env": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.3.tgz", - "integrity": "sha512-FYbZdV12yHdJU5Z70cEg0f6lvtpZ8jFSDakTm7WXeJbLXh4R0ztGEu/SW7G1nJ2ZvKwDhz8YrbA84eYyprmGqw==", + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.4.3", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.0", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.4.0", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.4.0", - "@babel/plugin-transform-classes": "^7.4.3", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.4.3", - "@babel/plugin-transform-dotall-regex": "^7.4.3", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.3", - "@babel/plugin-transform-function-name": "^7.4.3", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.4.3", - "@babel/plugin-transform-modules-systemjs": "^7.4.0", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.2", - "@babel/plugin-transform-new-target": "^7.4.0", - "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.4.3", - "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.3", - "@babel/plugin-transform-reserved-words": "^7.2.0", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.2.0", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.3", - "@babel/types": "^7.4.0", - "browserslist": "^4.5.2", - "core-js-compat": "^3.0.0", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" - } - }, - "@babel/preset-typescript": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz", - "integrity": "sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==", + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-typescript": "^7.3.2" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } @@ -5078,9 +7992,9 @@ }, "dependencies": { "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", "dev": true }, "regenerator-runtime": { @@ -5119,12 +8033,6 @@ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, - "bail": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", - "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==", - "dev": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -5469,14 +8377,14 @@ } }, "browserslist": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.1.tgz", - "integrity": "sha512-1MC18ooMPRG2UuVFJTHFIAkk6mpByJfxCrnUyvSlu/hyQSFHMrlhM02SzNuCV+quTP4CKmqtOMAIjrifrpBJXQ==", + "version": "4.8.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.7.tgz", + "integrity": "sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000971", - "electron-to-chromium": "^1.3.137", - "node-releases": "^1.1.21" + "caniuse-lite": "^1.0.30001027", + "electron-to-chromium": "^1.3.349", + "node-releases": "^1.1.49" } }, "bs-logger": { @@ -5554,27 +8462,52 @@ "dev": true }, "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", + "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", "dev": true, "requires": { - "bluebird": "^3.5.3", - "chownr": "^1.1.1", + "chownr": "^1.1.2", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "rimraf": "^2.7.1", + "ssri": "^7.0.0", + "unique-filename": "^1.1.1" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -5583,6 +8516,16 @@ "requires": { "glob": "^7.1.3" } + }, + "ssri": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", + "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" + } } } }, @@ -5638,13 +8581,21 @@ "dev": true }, "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", + "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "pascal-case": "^3.1.1", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } } }, "camelcase": { @@ -5665,9 +8616,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000971", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz", - "integrity": "sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==", + "version": "1.0.30001028", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001028.tgz", + "integrity": "sha512-Vnrq+XMSHpT7E+LWoIYhs3Sne8h9lx9YJV3acH3THNCwU/9zV93/ta4xVfzTtnqd3rvnuVpVjE3DFqf56tr3aQ==", "dev": true }, "capture-exit": { @@ -5679,9 +8630,9 @@ } }, "case-sensitive-paths-webpack-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz", - "integrity": "sha512-u5ElzokS8A1pm9vM3/iDgTcI3xqHxuCao94Oz8etI3cf0Tio0p8izkDYbTIn09uP3yUUr6+veaE6IkjnTYS46g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", + "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", "dev": true }, "caseless": { @@ -5689,12 +8640,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "ccount": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", - "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==", - "dev": true - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -5840,21 +8785,27 @@ } }, "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", "dev": true, "requires": { "source-map": "~0.6.0" } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "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=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "^3.1.0" } }, "cli-width": { @@ -6023,9 +8974,9 @@ } }, "color": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.1.tgz", - "integrity": "sha512-PvUltIXRjehRKPSy89VnDWFKY58xyhTLyxIg21vwQBI6qLwZNPmC8k3C1uytIgFKEpOIzN4y32iPm8231zFHIg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", "dev": true, "requires": { "color-convert": "^1.9.1", @@ -6069,12 +9020,6 @@ "delayed-stream": "~1.0.0" } }, - "comma-separated-tokens": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz", - "integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==", - "dev": true - }, "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", @@ -6111,13 +9056,30 @@ "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", + "dev": true, + "requires": { + "arity-n": "^1.0.4" + } + }, "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { - "mime-db": ">= 1.40.0 < 2" + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "dev": true + } } }, "compression": { @@ -6170,9 +9132,9 @@ } }, "confusing-browser-globals": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz", - "integrity": "sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", "dev": true }, "connect-history-api-fallback": { @@ -6278,36 +9240,29 @@ } }, "core-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", - "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", "dev": true }, "core-js-compat": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.3.tgz", - "integrity": "sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", + "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", "dev": true, "requires": { - "browserslist": "^4.6.0", - "core-js-pure": "3.1.3", - "semver": "^6.1.0" + "browserslist": "^4.8.3", + "semver": "7.0.0" }, "dependencies": { "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true } } }, - "core-js-pure": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.3.tgz", - "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -6445,9 +9400,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6514,9 +9469,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6583,9 +9538,9 @@ "dev": true }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6727,9 +9682,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6749,15 +9704,23 @@ } }, "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^2.1.2", + "css-what": "^3.2.1", "domutils": "^1.7.0", "nth-check": "^1.0.2" + }, + "dependencies": { + "css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "dev": true + } } }, "css-select-base-adapter": { @@ -6777,35 +9740,15 @@ } }, "css-tree": { - "version": "1.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", - "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "dev": true, "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "mdn-data": "2.0.4", + "source-map": "^0.6.1" } }, - "css-unit-converter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", - "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", - "dev": true - }, - "css-url-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", - "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", - "dev": true - }, "css-what": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", @@ -6872,9 +9815,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6963,9 +9906,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -7037,9 +9980,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -7065,51 +10008,33 @@ "dev": true }, "csso": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", - "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", + "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.29" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", - "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", - "dev": true, - "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "css-tree": "1.0.0-alpha.37" } }, "cssom": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, "cssstyle": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", - "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { "cssom": "0.3.x" } }, "csstype": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.5.tgz", - "integrity": "sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA==" + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.8.tgz", + "integrity": "sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA==" }, "cyclist": { "version": "0.2.2", @@ -7128,9 +10053,9 @@ } }, "damerau-levenshtein": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", - "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", "dev": true }, "dashdash": { @@ -7210,10 +10135,18 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } }, "deep-is": { "version": "0.1.3", @@ -7571,25 +10504,43 @@ "domelementtype": "1" } }, + "dot-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", + "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } + } + }, "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "^2.0.0" } }, "dotenv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", "dev": true }, "dotenv-expand": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", - "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "dev": true }, "duplexer": { @@ -7636,9 +10587,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.137", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.137.tgz", - "integrity": "sha512-kGi32g42a8vS/WnYE7ELJyejRT7hbr3UeOOu0WeuYuQ29gCpg9Lrf6RdcTQVXSt/v0bjCfnlb/EWOOsiKpTmkw==", + "version": "1.3.355", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.355.tgz", + "integrity": "sha512-zKO/wS+2ChI/jz9WAo647xSW8t2RmgRLFdbUb/77cORkUTargO+SCj4ctTHjBn2VeNFrsLgDT7IuDVrd3F8mLQ==", "dev": true }, "elliptic": { @@ -7927,53 +10878,54 @@ } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", + "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.8.3", "progress": "^2.0.0", "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -7996,31 +10948,91 @@ "supports-color": "^5.3.0" } }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", + "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8033,22 +11045,22 @@ } }, "eslint-config-react-app": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-4.0.1.tgz", - "integrity": "sha512-ZsaoXUIGsK8FCi/x4lT2bZR5mMkL/Kgj+Lnw690rbvvUr/uiwgFiD8FcfAhkCycm7Xte6O5lYz4EqMx2vX7jgw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.0.tgz", + "integrity": "sha512-WrHjoGpKr1kLLiWDD81tme9jMM0hk5cMxasLSdyno6DdPt+IfLOrDJBVo6jN7tn4y1nzhs43TmUaZWO6Sf0blw==", "dev": true, "requires": { - "confusing-browser-globals": "^1.0.7" + "confusing-browser-globals": "^1.0.9" } }, "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", "dev": true, "requires": { "debug": "^2.6.9", - "resolve": "^1.5.0" + "resolve": "^1.13.1" }, "dependencies": { "debug": { @@ -8065,40 +11077,74 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, "eslint-loader": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.1.2.tgz", - "integrity": "sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.3.tgz", + "integrity": "sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw==", "dev": true, "requires": { - "loader-fs-cache": "^1.0.0", - "loader-utils": "^1.0.2", - "object-assign": "^4.0.1", - "object-hash": "^1.1.4", - "rimraf": "^2.6.1" + "fs-extra": "^8.1.0", + "loader-fs-cache": "^1.0.2", + "loader-utils": "^1.2.3", + "object-hash": "^2.0.1", + "schema-utils": "^2.6.1" }, "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", "dev": true, "requires": { - "glob": "^7.1.3" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" } } } }, "eslint-module-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", - "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", "dev": true, "requires": { - "debug": "^2.6.8", + "debug": "^2.6.9", "pkg-dir": "^2.0.0" }, "dependencies": { @@ -8172,30 +11218,32 @@ } }, "eslint-plugin-flowtype": { - "version": "2.50.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.1.tgz", - "integrity": "sha512-9kRxF9hfM/O6WGZcZPszOVPd2W0TLHBtceulLTsGfwMPtiCCLnCW0ssRiOOiXyqrCA20pm1iXdXm7gQeN306zQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz", + "integrity": "sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.15" } }, "eslint-plugin-import": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", - "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz", + "integrity": "sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==", "dev": true, "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", "contains-path": "^0.1.0", "debug": "^2.6.9", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.3.0", + "eslint-module-utils": "^2.4.1", "has": "^1.0.3", - "lodash": "^4.17.11", "minimatch": "^3.0.4", + "object.values": "^1.1.0", "read-pkg-up": "^2.0.0", - "resolve": "^1.9.0" + "resolve": "^1.12.0" }, "dependencies": { "debug": { @@ -8322,15 +11370,25 @@ "find-up": "^2.0.0", "read-pkg": "^2.0.0" } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, "eslint-plugin-jsx-a11y": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz", - "integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", "dev": true, "requires": { + "@babel/runtime": "^7.4.5", "aria-query": "^3.0.0", "array-includes": "^3.0.3", "ast-types-flow": "^0.0.7", @@ -8338,22 +11396,24 @@ "damerau-levenshtein": "^1.0.4", "emoji-regex": "^7.0.2", "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1" + "jsx-ast-utils": "^2.2.1" } }, "eslint-plugin-react": { - "version": "7.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", - "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz", + "integrity": "sha512-p+PGoGeV4SaZRDsXqdj9OWcOrOpZn8gXoGPcIQTzo2IDMbAKhNDnME9myZWqO3Ic4R3YmwAZ1lDjWl2R2hMUVQ==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1", - "object.fromentries": "^2.0.0", - "prop-types": "^15.6.2", - "resolve": "^1.9.0" + "jsx-ast-utils": "^2.2.3", + "object.entries": "^1.1.1", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.14.2" }, "dependencies": { "doctrine": { @@ -8364,13 +11424,85 @@ "requires": { "esutils": "^2.0.2" } + }, + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object.entries": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, "eslint-plugin-react-hooks": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.0.tgz", - "integrity": "sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", "dev": true }, "eslint-scope": { @@ -8390,31 +11522,31 @@ "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - } } }, "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "dev": true + } } }, "esprima": { @@ -8423,9 +11555,9 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -8487,9 +11619,9 @@ "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" }, "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", "dev": true }, "events": { @@ -8911,9 +12043,9 @@ } }, "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==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -9037,9 +12169,9 @@ "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" }, "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -9069,9 +12201,9 @@ "dev": true }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -9087,13 +12219,49 @@ } }, "file-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", - "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", + "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", "dev": true, "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^1.0.0" + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + }, + "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" + } + } } }, "file-uri-to-path": { @@ -9104,9 +12272,9 @@ "optional": true }, "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", - "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", + "integrity": "sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg==", "dev": true }, "fill-range": { @@ -9256,15 +12424,15 @@ } }, "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", "dev": true }, "flush-write-stream": { @@ -9278,12 +12446,12 @@ } }, "follow-redirects": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", - "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", + "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", "dev": true, "requires": { - "debug": "^3.2.6" + "debug": "^3.0.0" }, "dependencies": { "debug": { @@ -9317,14 +12485,14 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "fork-ts-checker-webpack-plugin": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.1.1.tgz", - "integrity": "sha512-gqWAEMLlae/oeVnN6RWCAhesOJMswAN1MaKNqhhjXHV5O0/rTUjWI4UbgQHdlrVbCnb+xLotXmJbBlC66QmpFw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", "dev": true, "requires": { "babel-code-frame": "^6.22.0", "chalk": "^2.4.1", - "chokidar": "^2.0.4", + "chokidar": "^3.3.0", "micromatch": "^3.1.10", "minimatch": "^3.0.4", "semver": "^5.6.0", @@ -9341,6 +12509,31 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -9352,13 +12545,93 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.7" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" } } } @@ -9410,14 +12683,31 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" } }, "fs-mkdirp-stream": { @@ -10049,9 +13339,9 @@ "dev": true }, "get-own-enumerable-property-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", - "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true }, "get-stream": { @@ -10187,9 +13477,9 @@ }, "dependencies": { "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true } } @@ -10602,13 +13892,21 @@ } }, "gzip-size": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz", - "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", "dev": true, "requires": { "duplexer": "^0.1.1", - "pify": "^3.0.0" + "pify": "^4.0.1" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } } }, "handle-thing": { @@ -10737,37 +14035,6 @@ "minimalistic-assert": "^1.0.1" } }, - "hast-util-from-parse5": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-5.0.1.tgz", - "integrity": "sha512-UfPzdl6fbxGAxqGYNThRUhRlDYY7sXu6XU9nQeX4fFZtV+IHbyEJtd+DUuwOqNV4z3K05E/1rIkoVr/JHmeWWA==", - "dev": true, - "requires": { - "ccount": "^1.0.3", - "hastscript": "^5.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.1.2", - "xtend": "^4.0.1" - } - }, - "hast-util-parse-selector": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz", - "integrity": "sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw==", - "dev": true - }, - "hastscript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.0.1.tgz", - "integrity": "sha512-i9nc9NRtVIKlvVfVJ/Tnonk5PXO3BOqaqwfxHw53CWZEETpLCFIjvu0jej/DzT/xlXFOVDpB7KRUFpUrgU8Tow==", - "dev": true, - "requires": { - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.2.0", - "property-information": "^5.0.1", - "space-separated-tokens": "^1.0.0" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -10863,40 +14130,40 @@ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==" }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "html-minifier-terser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.0.4.tgz", + "integrity": "sha512-fHwmKQ+GzhlqdxEtwrqLT7MSuheiA+rif5/dZgbz3GjoMXJzcRzy1L9NXoiiyxrnap+q5guSiv8Tz5lrh9g42g==", "dev": true, "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" }, "dependencies": { "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true } } }, "html-webpack-plugin": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz", - "integrity": "sha512-y5l4lGxOW3pz3xBTFdfB9rnnrWRPVxlAhX6nrBYIcW+2k2zC3mSp/3DxlWVCMBfnO6UAnoF8OcFn0IMy6kaKAQ==", + "version": "4.0.0-beta.11", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", + "integrity": "sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg==", "dev": true, "requires": { - "html-minifier": "^3.5.20", - "loader-utils": "^1.1.0", - "lodash": "^4.17.11", + "html-minifier-terser": "^5.0.1", + "loader-utils": "^1.2.3", + "lodash": "^4.17.15", "pretty-error": "^2.1.1", - "tapable": "^1.1.0", + "tapable": "^1.1.3", "util.promisify": "1.0.0" } }, @@ -10947,18 +14214,18 @@ } }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", "dev": true }, "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", + "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } @@ -11019,9 +14286,9 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -11163,6 +14430,12 @@ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -11184,30 +14457,30 @@ "dev": true }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", + "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", "dev": true, "requires": { - "ansi-escapes": "^3.2.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", + "cli-cursor": "^3.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", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { @@ -11230,6 +14503,46 @@ "supports-color": "^5.3.0" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -11237,6 +14550,14 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "supports-color": { @@ -11438,6 +14759,12 @@ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -11489,9 +14816,9 @@ } }, "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-path-cwd": { @@ -11568,9 +14895,9 @@ "dev": true }, "is-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.0.0.tgz", - "integrity": "sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", "dev": true }, "is-stream": { @@ -11578,6 +14905,12 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -11673,9 +15006,9 @@ }, "dependencies": { "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -12631,16 +15964,139 @@ } }, "jest-environment-jsdom-fourteen": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-0.1.0.tgz", - "integrity": "sha512-4vtoRMg7jAstitRzL4nbw83VmGH8Rs13wrND3Ud2o1fczDhMUF32iIrNKwYGgeOPUdfvZU4oy8Bbv+ni1fgVCA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz", + "integrity": "sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q==", "dev": true, "requires": { - "jest-mock": "^24.5.0", - "jest-util": "^24.5.0", - "jsdom": "^14.0.0" + "@jest/environment": "^24.3.0", + "@jest/fake-timers": "^24.3.0", + "@jest/types": "^24.3.0", + "jest-mock": "^24.0.0", + "jest-util": "^24.0.0", + "jsdom": "^14.1.0" }, "dependencies": { + "@jest/environment": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true + }, + "jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "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" + } + } + } + }, "jsdom": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", @@ -12675,6 +16131,15 @@ "xml-name-validator": "^3.0.0" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -12682,18 +16147,7 @@ "dev": true, "requires": { "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "punycode": "^2.1.1" } }, "ws": { @@ -13374,14 +16828,14 @@ } }, "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "@types/stack-utils": "^1.0.1", "chalk": "^2.0.1", "micromatch": "^3.1.10", @@ -13400,15 +16854,6 @@ "@types/yargs": "^13.0.0" } }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -13441,12 +16886,12 @@ } }, "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", "dev": true, "requires": { - "@jest/types": "^24.8.0" + "@jest/types": "^24.9.0" }, "dependencies": { "@jest/types": { @@ -13459,15 +16904,6 @@ "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^13.0.0" } - }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } } } }, @@ -13482,12 +16918,12 @@ "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==" }, "jest-resolve": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.7.1.tgz", - "integrity": "sha512-Bgrc+/UUZpGJ4323sQyj85hV9d+ANyPNu6XfRDUcyFNX1QrZpSoM0kE4Mb2vZMAYTJZsBFzYe8X1UaOkOELSbw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", "dev": true, "requires": { - "@jest/types": "^24.7.0", + "@jest/types": "^24.9.0", "browser-resolve": "^1.11.3", "chalk": "^2.0.1", "jest-pnp-resolver": "^1.2.1", @@ -13505,15 +16941,6 @@ "@types/yargs": "^13.0.0" } }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -14368,16 +17795,16 @@ } }, "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "callsites": "^3.0.0", "chalk": "^2.0.1", "graceful-fs": "^4.1.15", @@ -14398,15 +17825,6 @@ "@types/yargs": "^13.0.0" } }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -14530,16 +17948,17 @@ } }, "jest-watch-typeahead": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.3.0.tgz", - "integrity": "sha512-+uOtlppt9ysST6k6ZTqsPI0WNz2HLa8bowiZylZoQCQaAVn7XsVmHhZREkz73FhKelrFrpne4hQQjdq42nFEmA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz", + "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.1", + "jest-regex-util": "^24.9.0", "jest-watcher": "^24.3.0", - "slash": "^2.0.0", - "string-length": "^2.0.0", + "slash": "^3.0.0", + "string-length": "^3.1.0", "strip-ansi": "^5.0.0" }, "dependencies": { @@ -14569,6 +17988,28 @@ "supports-color": "^5.3.0" } }, + "jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -14590,17 +18031,17 @@ } }, "jest-watcher": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.8.0.tgz", - "integrity": "sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", "dev": true, "requires": { - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/yargs": "^12.0.9", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", - "jest-util": "^24.8.0", + "jest-util": "^24.9.0", "string-length": "^2.0.0" }, "dependencies": { @@ -14613,19 +18054,14 @@ "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^13.0.0" - }, - "dependencies": { - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - } } }, + "ansi-escapes": { + "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-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -14681,12 +18117,6 @@ } } }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14863,12 +18293,13 @@ } }, "jsx-ast-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", - "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", + "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", "dev": true, "requires": { - "array-includes": "^3.0.3" + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" } }, "just-debounce": { @@ -14995,6 +18426,15 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -15034,6 +18474,12 @@ } } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "linkify-it": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz", @@ -15159,12 +18605,6 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, - "lodash.tail": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", - "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", - "dev": true - }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -15176,20 +18616,14 @@ } }, "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0" + "lodash._reinterpolate": "^3.0.0" } }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -15237,9 +18671,9 @@ } }, "loglevel": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", - "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", + "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", "dev": true }, "lolex": { @@ -15259,10 +18693,21 @@ } }, "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", + "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } + } }, "lru-cache": { "version": "5.1.1", @@ -15401,9 +18846,9 @@ } }, "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "dev": true }, "mdurl": { @@ -15492,9 +18937,9 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", "dev": true }, "methods": { @@ -15566,9 +19011,9 @@ } }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "min-indent": { @@ -15577,12 +19022,13 @@ "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=" }, "mini-css-extract-plugin": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", - "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", "dev": true, "requires": { "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", "schema-utils": "^1.0.0", "webpack-sources": "^1.1.0" } @@ -15612,6 +19058,50 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", + "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -15944,12 +19434,21 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", + "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "^2.0.1", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } } }, "node-environment-flags": { @@ -15963,9 +19462,9 @@ } }, "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", "dev": true }, "node-int64": { @@ -16054,12 +19553,20 @@ } }, "node-releases": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.21.tgz", - "integrity": "sha512-TwnURTCjc8a+ElJUjmDqU6+12jhli1Q61xOQmdZ7ECZVBZuQpN/1UnembiIHDM1wCcfLvh5wrWXUF5H6ufX64Q==", + "version": "1.1.49", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.49.tgz", + "integrity": "sha512-xH8t0LS0disN0mtRCh+eByxFPie+msJUBL/lJDBuap53QGiYPa9joh83K4pCZgWJ+2L4b9h88vCVdXQ60NO2bg==", "dev": true, "requires": { - "semver": "^5.3.0" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "normalize-package-data": { @@ -16089,10 +19596,16 @@ "dev": true }, "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } }, "now-and-later": { "version": "2.0.1", @@ -16181,9 +19694,9 @@ "dev": true }, "nwsapi": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, "oauth-sign": { @@ -16222,9 +19735,21 @@ } }, "object-hash": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", - "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", + "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", + "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", "dev": true }, "object-keys": { @@ -16232,6 +19757,12 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -16287,15 +19818,68 @@ } }, "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", - "has": "^1.0.1" + "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + } } }, "object.getownpropertydescriptors": { @@ -16358,15 +19942,68 @@ } }, "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + } } }, "obuf": { @@ -16375,6 +20012,30 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, + "office-ui-fabric-react": { + "version": "7.85.0", + "resolved": "https://registry.npmjs.org/office-ui-fabric-react/-/office-ui-fabric-react-7.85.0.tgz", + "integrity": "sha512-lWE300YX1GM8r3CHDVL+tT9tfr6XeOL6lMaO8uhoTWyepR+ot2pKlMrPYLyhhuytqEB5qRgmG/RCvvB/09jn0Q==", + "requires": { + "@microsoft/load-themed-styles": "^1.10.26", + "@uifabric/foundation": "^7.5.3", + "@uifabric/icons": "^7.3.2", + "@uifabric/merge-styles": "^7.8.3", + "@uifabric/react-hooks": "^7.0.3", + "@uifabric/set-version": "^7.0.3", + "@uifabric/styling": "^7.10.2", + "@uifabric/utilities": "^7.11.3", + "prop-types": "^15.5.10", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, "on-error-resume-next": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/on-error-resume-next/-/on-error-resume-next-1.1.0.tgz", @@ -16405,12 +20066,12 @@ } }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "^2.1.0" } }, "open": { @@ -16421,13 +20082,22 @@ "is-wsl": "^1.1.0" } }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "optimize-css-assets-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-Rqm6sSjWtx9FchdP0uzTQDc7GXDKnwVEGoSxjezPkzMewx7gEWE9IMUYKmigTRC4U3RaNSwYVnUDLuIdtTpm0A==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", "dev": true, "requires": { - "cssnano": "^4.1.0", + "cssnano": "^4.1.10", "last-call-webpack-plugin": "^3.0.0" } }, @@ -16557,6 +20227,15 @@ "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -16580,12 +20259,21 @@ } }, "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", + "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", "dev": true, "requires": { - "no-case": "^2.2.0" + "dot-case": "^3.0.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } } }, "parent-module": { @@ -16687,6 +20375,24 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "pascal-case": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", + "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + } + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -16844,57 +20550,12 @@ } }, "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } + "find-up": "^3.0.0" } }, "plugin-error": { @@ -16955,39 +20616,33 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, "pnp-webpack-plugin": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.2.1.tgz", - "integrity": "sha512-W6GctK7K2qQiVR+gYSv/Gyt6jwwIH4vwdviFqx+Y2jAtVf5eZyYIDf5Ac2NCDMBiX5yWscBLZElPTsyA1UtVVA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.0.tgz", + "integrity": "sha512-ZcMGn/xF/fCOq+9kWMP9vVVxjIkMCja72oy3lziR7UHy0hHFZ57iVpQ71OtveVbmzeCmphBg8pxNdk/hlK99aQ==", "dev": true, "requires": { - "ts-pnp": "^1.0.0" + "ts-pnp": "^1.1.2" } }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", "dev": true, "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -17035,13 +20690,13 @@ } }, "postcss-attribute-case-insensitive": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.1.tgz", - "integrity": "sha512-L2YKB3vF4PetdTIthQVeT+7YiSzMoNMLLYxPXXppOOP7NoazEAy45sh2LvJ8leCQjfBcfkYQs8TtCcQjeZTp8A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", + "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", "dev": true, "requires": { "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0" + "postcss-selector-parser": "^6.0.2" }, "dependencies": { "ansi-styles": { @@ -17075,16 +20730,10 @@ } } }, - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "dev": true - }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17092,17 +20741,6 @@ "supports-color": "^6.1.0" } }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -17115,12 +20753,12 @@ } }, "postcss-browser-comments": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-2.0.0.tgz", - "integrity": "sha512-xGG0UvoxwBc4Yx4JX3gc0RuDl1kc4bVihCzzk6UC72YPfq5fu3c717Nu8Un3nvnq1BJ31gBnFXIG/OaUTnpHgA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", + "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", "dev": true, "requires": { - "postcss": "^7.0.2" + "postcss": "^7" }, "dependencies": { "ansi-styles": { @@ -17155,9 +20793,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17177,15 +20815,14 @@ } }, "postcss-calc": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", - "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", + "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", "dev": true, "requires": { - "css-unit-converter": "^1.1.1", - "postcss": "^7.0.5", - "postcss-selector-parser": "^5.0.0-rc.4", - "postcss-value-parser": "^3.3.1" + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" }, "dependencies": { "ansi-styles": { @@ -17219,16 +20856,10 @@ } } }, - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "dev": true - }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17236,16 +20867,11 @@ "supports-color": "^6.1.0" } }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } + "postcss-value-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", + "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", + "dev": true }, "supports-color": { "version": "6.1.0", @@ -17300,9 +20926,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17364,9 +20990,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17427,9 +21053,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17491,9 +21117,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17554,9 +21180,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17620,9 +21246,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17683,9 +21309,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17745,9 +21371,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17767,12 +21393,12 @@ } }, "postcss-custom-properties": { - "version": "8.0.10", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.10.tgz", - "integrity": "sha512-GDL0dyd7++goDR4SSasYdRNNvp4Gqy1XMzcCnTijiph7VB27XXpJ8bW/AI0i2VSBZ55TpdGhMr37kMSpRfYD0Q==", + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", "dev": true, "requires": { - "postcss": "^7.0.14", + "postcss": "^7.0.17", "postcss-values-parser": "^2.0.1" }, "dependencies": { @@ -17808,9 +21434,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17877,9 +21503,9 @@ "dev": true }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17957,9 +21583,9 @@ "dev": true }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18030,9 +21656,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18092,9 +21718,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18154,9 +21780,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18216,9 +21842,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18279,9 +21905,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18342,9 +21968,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18404,9 +22030,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18466,9 +22092,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18528,9 +22154,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18590,9 +22216,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18652,9 +22278,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18715,9 +22341,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18737,12 +22363,12 @@ } }, "postcss-initial": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.0.tgz", - "integrity": "sha512-WzrqZ5nG9R9fUtrA+we92R4jhVvEB32IIRTzfIG/PLL8UV4CvbF1ugTEHEFX6vWxl41Xt5RTCJPEZkuWzrOM+Q==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", + "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", "dev": true, "requires": { - "lodash.template": "^4.2.4", + "lodash.template": "^4.5.0", "postcss": "^7.0.2" }, "dependencies": { @@ -18778,9 +22404,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18842,9 +22468,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18929,9 +22555,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -18991,9 +22617,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19053,9 +22679,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19118,9 +22744,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19185,9 +22811,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19196,12 +22822,12 @@ } }, "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", "dev": true, "requires": { - "dot-prop": "^4.1.1", + "dot-prop": "^5.2.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } @@ -19259,9 +22885,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19324,9 +22950,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19391,9 +23017,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19456,9 +23082,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19467,12 +23093,12 @@ } }, "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", "dev": true, "requires": { - "dot-prop": "^4.1.1", + "dot-prop": "^5.2.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } @@ -19585,9 +23211,9 @@ } }, "postcss-nesting": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.0.tgz", - "integrity": "sha512-WSsbVd5Ampi3Y0nk/SKr5+K34n52PqMqEfswu6RtU4r7wA8vSD+gM8/D9qq4aJkHImwn1+9iEFTbjoWsQeqtaQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", + "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", "dev": true, "requires": { "postcss": "^7.0.2" @@ -19625,9 +23251,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19647,15 +23273,16 @@ } }, "postcss-normalize": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-7.0.1.tgz", - "integrity": "sha512-NOp1fwrG+6kVXWo7P9SizCHX6QvioxFD/hZcI2MLxPmVnFJFC0j0DDpIuNw2tUDeCFMni59gCVgeJ1/hYhj2OQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", + "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", "dev": true, "requires": { - "@csstools/normalize.css": "^9.0.1", - "browserslist": "^4.1.1", - "postcss": "^7.0.2", - "postcss-browser-comments": "^2.0.0" + "@csstools/normalize.css": "^10.1.0", + "browserslist": "^4.6.2", + "postcss": "^7.0.17", + "postcss-browser-comments": "^3.0.0", + "sanitize.css": "^10.0.0" }, "dependencies": { "ansi-styles": { @@ -19690,9 +23317,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19752,9 +23379,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19816,9 +23443,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19881,9 +23508,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19946,9 +23573,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20010,9 +23637,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20074,9 +23701,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20138,9 +23765,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20202,10 +23829,16 @@ } } }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20266,9 +23899,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20330,9 +23963,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20392,9 +24025,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20454,9 +24087,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20517,9 +24150,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20539,27 +24172,27 @@ } }, "postcss-preset-env": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.6.0.tgz", - "integrity": "sha512-I3zAiycfqXpPIFD6HXhLfWXIewAWO8emOKz+QSsxaUZb9Dp8HbF5kUf+4Wy/AxR33o+LRoO8blEWCHth0ZsCLA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", + "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", "dev": true, "requires": { - "autoprefixer": "^9.4.9", - "browserslist": "^4.4.2", - "caniuse-lite": "^1.0.30000939", + "autoprefixer": "^9.6.1", + "browserslist": "^4.6.4", + "caniuse-lite": "^1.0.30000981", "css-blank-pseudo": "^0.1.4", "css-has-pseudo": "^0.10.0", "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.3.0", - "postcss": "^7.0.14", + "cssdb": "^4.4.0", + "postcss": "^7.0.17", "postcss-attribute-case-insensitive": "^4.0.1", "postcss-color-functional-notation": "^2.0.1", "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.2", + "postcss-color-hex-alpha": "^5.0.3", "postcss-color-mod-function": "^3.0.3", "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.7", - "postcss-custom-properties": "^8.0.9", + "postcss-custom-media": "^7.0.8", + "postcss-custom-properties": "^8.0.11", "postcss-custom-selectors": "^5.1.2", "postcss-dir-pseudo-class": "^5.0.0", "postcss-double-position-gradients": "^1.0.0", @@ -20615,9 +24248,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20684,9 +24317,9 @@ "dev": true }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20760,9 +24393,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20825,9 +24458,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20887,9 +24520,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20949,9 +24582,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -21012,9 +24645,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -21075,9 +24708,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -21159,9 +24792,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -21223,9 +24856,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -21266,6 +24899,12 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -21273,9 +24912,9 @@ "dev": true }, "pretty-bytes": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.2.0.tgz", - "integrity": "sha512-ujANBhiUsl9AhREUDUEY1GPOharMGm8x8juS7qOHybcLi7XsKfrYQ88hSly1l2i0klXHTDYrlL8ihMCG55Dc3w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", + "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==", "dev": true }, "pretty-error": { @@ -21397,15 +25036,6 @@ "react-is": "^16.8.1" } }, - "property-information": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.1.0.tgz", - "integrity": "sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg==", - "dev": true, - "requires": { - "xtend": "^4.0.1" - } - }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -21422,12 +25052,6 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "psl": { "version": "1.1.32", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", @@ -21495,6 +25119,16 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -21568,78 +25202,102 @@ } }, "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", + "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "prop-types": "^15.6.2" } }, "react-app-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.1.tgz", - "integrity": "sha512-LbVpT1NdzTdDDs7xEZdebjDrqsvKi5UyVKUQqtTYYNyC1JJYVAwNQWe4ybWvoT2V2WW9PGVO2u5Y6aVj4ER/Ow==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", + "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", "dev": true, "requires": { - "core-js": "3.0.1", - "object-assign": "4.1.1", - "promise": "8.0.2", - "raf": "3.4.1", - "regenerator-runtime": "0.13.2", - "whatwg-fetch": "3.0.0" + "core-js": "^3.5.0", + "object-assign": "^4.1.1", + "promise": "^8.0.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.3", + "whatwg-fetch": "^3.0.0" }, "dependencies": { "promise": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.2.tgz", - "integrity": "sha512-EIyzM39FpVOMbqgzEHhxdrEhtOSDOtjMZQ0M6iVfCE+kWNgCkAyOdnuCWqfmflylftfadU6FkiMgHZA2kUzwRw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.3.tgz", + "integrity": "sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw==", "dev": true, "requires": { "asap": "~2.0.6" } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true } } }, "react-dev-utils": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.0.1.tgz", - "integrity": "sha512-pnaeMo/Pxel8aZpxk1WwxT3uXxM3tEwYvsjCYn5R7gNxjhN1auowdcLDzFB8kr7rafAj2rxmvfic/fbac5CzwQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.0.tgz", + "integrity": "sha512-MwrvQW2TFjLblhqpDNeqCXHBkz3G5vc7k4wntgutAJZX4ia3o07eGKo6uYGhUOeJ0hfOxcpJFNFk7+4XCc1S8g==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "address": "1.0.3", - "browserslist": "4.5.4", + "@babel/code-frame": "7.8.3", + "address": "1.1.2", + "browserslist": "4.8.6", "chalk": "2.4.2", - "cross-spawn": "6.0.5", + "cross-spawn": "7.0.1", "detect-port-alt": "1.1.6", - "escape-string-regexp": "1.0.5", - "filesize": "3.6.1", - "find-up": "3.0.0", - "fork-ts-checker-webpack-plugin": "1.1.1", + "escape-string-regexp": "2.0.0", + "filesize": "6.0.1", + "find-up": "4.1.0", + "fork-ts-checker-webpack-plugin": "3.1.1", "global-modules": "2.0.0", "globby": "8.0.2", - "gzip-size": "5.0.0", + "gzip-size": "5.1.1", "immer": "1.10.0", - "inquirer": "6.2.2", - "is-root": "2.0.0", + "inquirer": "7.0.4", + "is-root": "2.1.0", "loader-utils": "1.2.3", - "opn": "5.4.0", - "pkg-up": "2.0.0", - "react-error-overlay": "^5.1.6", + "open": "^7.0.2", + "pkg-up": "3.1.0", + "react-error-overlay": "^6.0.6", "recursive-readdir": "2.2.2", - "shell-quote": "1.6.1", - "sockjs-client": "1.3.0", - "strip-ansi": "5.2.0", + "shell-quote": "1.7.2", + "strip-ansi": "6.0.0", "text-table": "0.2.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { @@ -21652,14 +25310,14 @@ } }, "browserslist": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", - "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "version": "4.8.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz", + "integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000955", - "electron-to-chromium": "^1.3.122", - "node-releases": "^1.1.13" + "caniuse-lite": "^1.0.30001023", + "electron-to-chromium": "^1.3.341", + "node-releases": "^1.1.47" } }, "chalk": { @@ -21671,45 +25329,117 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } } }, - "inquirer": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", - "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", "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" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "is-wsl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "open": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.0.2.tgz", + "integrity": "sha512-70E/pFTPr7nZ9nLDPNTcj3IVqnNvKuP4VsBmoKV9YGTnChe0mlS3C4qM7qKarhZ8rGaHKLfo+vBTHXDp6ZSyLQ==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" } }, - "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "shebang-regex": "^3.0.0" } }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "supports-color": { @@ -21720,24 +25450,33 @@ "requires": { "has-flag": "^3.0.0" } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "react-dom": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", - "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz", + "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "scheduler": "^0.18.0" } }, "react-error-overlay": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.6.tgz", - "integrity": "sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.6.tgz", + "integrity": "sha512-Yzpno3enVzSrSCnnljmr4b/2KUQSMZaPuqmS26t9k4nW7uwJk6STWmH9heNjPuvqUTO3jOSPkHoKgO4+Dw7uIw==", "dev": true }, "react-intl": { @@ -21763,75 +25502,212 @@ "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, "react-scripts": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.0.1.tgz", - "integrity": "sha512-LKEjBhVpEB+c312NeJhzF+NATxF7JkHNr5GhtwMeRS1cMeLElMeIu8Ye7WGHtDP7iz7ra4ryy48Zpo6G/cwWUw==", - "dev": true, - "requires": { - "@babel/core": "7.4.3", - "@svgr/webpack": "4.1.0", - "@typescript-eslint/eslint-plugin": "1.6.0", - "@typescript-eslint/parser": "1.6.0", - "babel-eslint": "10.0.1", - "babel-jest": "^24.8.0", - "babel-loader": "8.0.5", - "babel-plugin-named-asset-import": "^0.3.2", - "babel-preset-react-app": "^9.0.0", - "camelcase": "^5.2.0", - "case-sensitive-paths-webpack-plugin": "2.2.0", - "css-loader": "2.1.1", - "dotenv": "6.2.0", - "dotenv-expand": "4.2.0", - "eslint": "^5.16.0", - "eslint-config-react-app": "^4.0.1", - "eslint-loader": "2.1.2", - "eslint-plugin-flowtype": "2.50.1", - "eslint-plugin-import": "2.16.0", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-react": "7.12.4", - "eslint-plugin-react-hooks": "^1.5.0", - "file-loader": "3.0.1", - "fs-extra": "7.0.1", - "fsevents": "2.0.6", - "html-webpack-plugin": "4.0.0-beta.5", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.0.tgz", + "integrity": "sha512-pBqaAroFoHnFAkuX+uSK9Th1uEh2GYdGY2IG1I9/7HmuEf+ls3lLCk1p2GFYRSrLMz6ieQR/SyN6TLIGK3hKRg==", + "dev": true, + "requires": { + "@babel/core": "7.8.4", + "@svgr/webpack": "4.3.3", + "@typescript-eslint/eslint-plugin": "^2.10.0", + "@typescript-eslint/parser": "^2.10.0", + "babel-eslint": "10.0.3", + "babel-jest": "^24.9.0", + "babel-loader": "8.0.6", + "babel-plugin-named-asset-import": "^0.3.6", + "babel-preset-react-app": "^9.1.1", + "camelcase": "^5.3.1", + "case-sensitive-paths-webpack-plugin": "2.3.0", + "css-loader": "3.4.2", + "dotenv": "8.2.0", + "dotenv-expand": "5.1.0", + "eslint": "^6.6.0", + "eslint-config-react-app": "^5.2.0", + "eslint-loader": "3.0.3", + "eslint-plugin-flowtype": "4.6.0", + "eslint-plugin-import": "2.20.0", + "eslint-plugin-jsx-a11y": "6.2.3", + "eslint-plugin-react": "7.18.0", + "eslint-plugin-react-hooks": "^1.6.1", + "file-loader": "4.3.0", + "fs-extra": "^8.1.0", + "fsevents": "2.1.2", + "html-webpack-plugin": "4.0.0-beta.11", "identity-obj-proxy": "3.0.0", - "is-wsl": "^1.1.0", - "jest": "24.7.1", - "jest-environment-jsdom-fourteen": "0.1.0", - "jest-resolve": "24.7.1", - "jest-watch-typeahead": "0.3.0", - "mini-css-extract-plugin": "0.5.0", - "optimize-css-assets-webpack-plugin": "5.0.1", - "pnp-webpack-plugin": "1.2.1", + "jest": "24.9.0", + "jest-environment-jsdom-fourteen": "1.0.1", + "jest-resolve": "24.9.0", + "jest-watch-typeahead": "0.4.2", + "mini-css-extract-plugin": "0.9.0", + "optimize-css-assets-webpack-plugin": "5.0.3", + "pnp-webpack-plugin": "1.6.0", "postcss-flexbugs-fixes": "4.1.0", "postcss-loader": "3.0.0", - "postcss-normalize": "7.0.1", - "postcss-preset-env": "6.6.0", + "postcss-normalize": "8.0.1", + "postcss-preset-env": "6.7.0", "postcss-safe-parser": "4.0.1", - "react-app-polyfill": "^1.0.1", - "react-dev-utils": "^9.0.1", - "resolve": "1.10.0", - "sass-loader": "7.1.0", - "semver": "6.0.0", + "react-app-polyfill": "^1.0.6", + "react-dev-utils": "^10.2.0", + "resolve": "1.15.0", + "resolve-url-loader": "3.1.1", + "sass-loader": "8.0.2", + "semver": "6.3.0", "style-loader": "0.23.1", - "terser-webpack-plugin": "1.2.3", - "ts-pnp": "1.1.2", - "url-loader": "1.1.2", - "webpack": "4.29.6", - "webpack-dev-server": "3.2.1", - "webpack-manifest-plugin": "2.0.4", - "workbox-webpack-plugin": "4.2.0" + "terser-webpack-plugin": "2.3.4", + "ts-pnp": "1.1.5", + "url-loader": "2.3.0", + "webpack": "4.41.5", + "webpack-dev-server": "3.10.2", + "webpack-manifest-plugin": "2.2.0", + "workbox-webpack-plugin": "4.3.1" }, "dependencies": { - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } }, "@jest/core": { @@ -21868,21 +25744,6 @@ "rimraf": "^2.5.4", "slash": "^2.0.0", "strip-ansi": "^5.0.0" - }, - "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - } } }, "@jest/environment": { @@ -21897,17 +25758,6 @@ "jest-mock": "^24.9.0" } }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, "@jest/reporters": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", @@ -21937,43 +25787,14 @@ "string-length": "^2.0.0" }, "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, "@jest/test-sequencer": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", @@ -22008,6 +25829,14 @@ "slash": "^2.0.0", "source-map": "^0.6.1", "write-file-atomic": "2.4.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "@jest/types": { @@ -22021,15 +25850,36 @@ "@types/yargs": "^13.0.0" } }, - "@types/yargs": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.6.tgz", - "integrity": "sha512-IkltIncDQWv6fcAvnHtJ6KtkmY/vtR3bViOaCzpj/A3yNhlfZAgxNe6AEQD1cQrkYD+YsKVo08DSxvNKEsD7BA==", + "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": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", "dev": true, "requires": { - "@types/yargs-parser": "*" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-escapes": { + "version": "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": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -22079,12 +25929,6 @@ "babel-plugin-jest-hoist": "^24.9.0" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -22094,17 +25938,6 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "cliui": { @@ -22118,25 +25951,41 @@ "wrap-ansi": "^5.1.0" } }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, "css-loader": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", - "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", + "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==", "dev": true, "requires": { - "camelcase": "^5.2.0", - "icss-utils": "^4.1.0", + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", "loader-utils": "^1.2.3", "normalize-path": "^3.0.0", - "postcss": "^7.0.14", + "postcss": "^7.0.23", "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^2.0.6", - "postcss-modules-scope": "^2.1.0", - "postcss-modules-values": "^2.0.0", - "postcss-value-parser": "^3.3.0", - "schema-utils": "^1.0.0" + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.1.1", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.0.2", + "schema-utils": "^2.6.0" } }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, "expect": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", @@ -22151,10 +26000,38 @@ "jest-regex-util": "^24.9.0" } }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "find-cache-dir": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", + "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.0", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } + } + }, "fsevents": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.6.tgz", - "integrity": "sha512-vfmKZp3XPM36DNF0qhW+Cdxk7xm7gTEHY1clv1Xq1arwRQuKZgAhw+NZNWbJBtuaNxzNXwhfdPYRrvIbjfS33A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", "dev": true, "optional": true }, @@ -22165,9 +26042,9 @@ "dev": true }, "icss-utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.0.tgz", - "integrity": "sha512-3DEun4VOeMvSczifM3F2cKQrDQ5Pj6WKhkOq6HD4QTnDUAq8MQRxy5TX6Sy1iY6WPBe4gQ3p5vTECjbIkglkkQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", "dev": true, "requires": { "postcss": "^7.0.14" @@ -22182,6 +26059,17 @@ "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "istanbul-lib-source-maps": { @@ -22195,6 +26083,14 @@ "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "istanbul-reports": { @@ -22207,13 +26103,13 @@ } }, "jest": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.7.1.tgz", - "integrity": "sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", "dev": true, "requires": { "import-local": "^2.0.0", - "jest-cli": "^24.7.1" + "jest-cli": "^24.9.0" }, "dependencies": { "jest-cli": { @@ -22273,21 +26169,6 @@ "micromatch": "^3.1.10", "pretty-format": "^24.9.0", "realpath-native": "^1.1.0" - }, - "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - } } }, "jest-docblock": { @@ -22953,31 +26834,6 @@ "pretty-format": "^24.9.0" } }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0" - } - }, "jest-regex-util": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", @@ -23020,21 +26876,6 @@ "jest-worker": "^24.6.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" - }, - "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - } } }, "jest-runtime": { @@ -23066,21 +26907,6 @@ "slash": "^2.0.0", "strip-bom": "^3.0.0", "yargs": "^13.3.0" - }, - "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - } } }, "jest-serializer": { @@ -23108,47 +26934,6 @@ "natural-compare": "^1.4.0", "pretty-format": "^24.9.0", "semver": "^6.2.0" - }, - "dependencies": { - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" } }, "jest-validate": { @@ -23165,21 +26950,6 @@ "pretty-format": "^24.9.0" } }, - "jest-watcher": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", - "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", - "dev": true, - "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", - "string-length": "^2.0.0" - } - }, "jest-worker": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", @@ -23188,6 +26958,17 @@ "requires": { "merge-stream": "^2.0.0", "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "jsdom": { @@ -23222,22 +27003,63 @@ "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 - } } }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, "node-notifier": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", @@ -23274,21 +27096,89 @@ "p-reduce": "^1.0.0" } }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", "supports-color": "^6.1.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 + }, + "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" + } + } } }, "postcss-modules-extract-imports": { @@ -23301,20 +27191,21 @@ } }, "postcss-modules-local-by-default": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", - "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", "dev": true, "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0", - "postcss-value-parser": "^3.3.1" + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" } }, "postcss-modules-scope": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz", - "integrity": "sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz", + "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==", "dev": true, "requires": { "postcss": "^7.0.6", @@ -23322,19 +27213,31 @@ } }, "postcss-modules-values": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", - "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", "dev": true, "requires": { - "icss-replace-symbols": "^1.1.0", + "icss-utils": "^4.0.0", "postcss": "^7.0.6" } }, + "postcss-value-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", + "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", + "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -23349,10 +27252,26 @@ "glob": "^7.1.3" } }, + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" + } + }, "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "string-width": { @@ -23381,17 +27300,80 @@ "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0" + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "terser-webpack-plugin": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.4.tgz", + "integrity": "sha512-Nv96Nws2R2nrFOpbzF6IxRDpIkkIfmhvOws+IqMvYdFLO7o6wAILWFKONFgaYy8+T4LVz77DQW0f7wOeDEAjrg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "cacache": "^13.0.1", + "find-cache-dir": "^3.2.0", + "jest-worker": "^25.1.0", + "p-limit": "^2.2.2", + "schema-utils": "^2.6.4", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.4.3", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "throat": { @@ -23400,36 +27382,153 @@ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "webpack": { - "version": "4.29.6", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.6.tgz", - "integrity": "sha512-MwBwpiE1BQpMDkbnUUaW6K8RFZjljJHArC6tWQJoFm0oQtfoSebtg4Y7/QHnJ/SddtjYLHaKGX64CFjG5rehJw==", + "version": "4.41.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.5.tgz", + "integrity": "sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-module-context": "1.8.5", "@webassemblyjs/wasm-edit": "1.8.5", "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", + "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true + }, + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "whatwg-url": { @@ -23493,6 +27592,28 @@ } } }, + "react-test-renderer": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.12.0.tgz", + "integrity": "sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.18.0" + }, + "dependencies": { + "scheduler": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", + "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -23604,9 +27725,9 @@ "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" }, "regenerator-transform": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", - "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", "dev": true, "requires": { "private": "^0.1.6" @@ -23621,16 +27742,79 @@ "safe-regex": "^1.1.0" } }, - "regexp-tree": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", - "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", + "regex-parser": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", + "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + } + } + }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", "dev": true }, "regexpu-core": { @@ -23656,17 +27840,6 @@ "jsesc": "~0.5.0" } }, - "rehype-parse": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-6.0.0.tgz", - "integrity": "sha512-V2OjMD0xcSt39G4uRdMTqDXXm6HwkUbLMDayYKA/d037j8/OtVSQ+tqKwYWOuyBeoCs/3clXRe30VUjeMDTBSA==", - "dev": true, - "requires": { - "hast-util-from-parse5": "^5.0.0", - "parse5": "^5.0.0", - "xtend": "^4.0.1" - } - }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -23831,12 +28004,6 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, - "requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -23915,13 +28082,93 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, + "resolve-url-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", + "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", + "dev": true, + "requires": { + "adjust-sourcemap-loader": "2.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.21", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "onetime": "^2.0.0", + "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, @@ -23930,6 +28177,36 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", + "dev": true, + "requires": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", + "dev": true + } + } + }, + "rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", + "dev": true + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -23984,9 +28261,9 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -24026,64 +28303,89 @@ "walker": "~1.0.5" } }, + "sanitize.css": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", + "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==", + "dev": true + }, "sass-loader": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", - "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", "dev": true, "requires": { - "clone-deep": "^2.0.1", - "loader-utils": "^1.0.1", - "lodash.tail": "^4.1.1", - "neo-async": "^2.5.0", - "pify": "^3.0.0", - "semver": "^5.5.0" + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" }, "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "requires": { - "for-own": "^1.0.0", "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" } }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", "dev": true, "requires": { - "for-in": "^1.0.1" + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" } }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "kind-of": "^6.0.2" } } } @@ -24103,9 +28405,9 @@ } }, "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", + "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -24129,12 +28431,12 @@ "dev": true }, "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", "dev": true, "requires": { - "node-forge": "0.7.5" + "node-forge": "0.9.0" } }, "semver": { @@ -24192,9 +28494,9 @@ } }, "serialize-javascript": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", "dev": true }, "serve-index": { @@ -24655,23 +28957,12 @@ "requires": { "faye-websocket": "^0.10.0", "uuid": "^3.0.1" - }, - "dependencies": { - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - } } }, "sockjs-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", "dev": true, "requires": { "debug": "^3.2.5", @@ -24690,9 +28981,27 @@ "requires": { "ms": "^2.1.1" } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } } } }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -24730,12 +29039,6 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, - "space-separated-tokens": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz", - "integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==", - "dev": true - }, "sparkles": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", @@ -24775,9 +29078,9 @@ "dev": true }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -24802,9 +29105,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -24972,6 +29275,12 @@ "readable-stream": "^2.0.2" } }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, "string-hash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", @@ -25042,6 +29351,26 @@ "function-bind": "^1.0.2" } }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -25060,6 +29389,14 @@ "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + } } }, "strip-ansi": { @@ -25186,9 +29523,9 @@ } }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -25197,12 +29534,12 @@ } }, "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", "dev": true, "requires": { - "dot-prop": "^4.1.1", + "dot-prop": "^5.2.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } @@ -25265,19 +29602,24 @@ "prop-types": "^15.5.0" } }, + "svg-parser": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.3.tgz", + "integrity": "sha512-fnCWiifNhK8i2Z7b9R5tbNahpxrRdAaQbnoxKlT2KrSCj9Kq/yBSgulCRgBJRhy1dPnSY5slg5ehPUnzpEcHlg==", + "dev": true + }, "svgo": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.2.2.tgz", - "integrity": "sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "dev": true, "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.28", - "css-url-regex": "^1.1.0", - "csso": "^3.5.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", "object.values": "^1.1.0", @@ -25324,23 +29666,41 @@ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, "table": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz", - "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", + "ajv": "^6.10.2", + "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -25389,30 +29749,92 @@ } }, "terser": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", - "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", + "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", "dev": true, "requires": { - "commander": "^2.19.0", + "commander": "^2.20.0", "source-map": "~0.6.1", - "source-map-support": "~0.5.10" + "source-map-support": "~0.5.12" } }, "terser-webpack-plugin": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz", - "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", "dev": true, "requires": { - "cacache": "^11.0.2", - "find-cache-dir": "^2.0.0", + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.4.0", + "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", - "terser": "^3.16.1", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, + "terser": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", + "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } } }, "test-exclude": { @@ -25465,9 +29887,9 @@ } }, "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, "time-stamp": { @@ -25613,12 +30035,6 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, - "trough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", - "dev": true - }, "ts-import-plugin": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/ts-import-plugin/-/ts-import-plugin-1.5.5.tgz", @@ -25713,9 +30129,9 @@ } }, "ts-pnp": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.2.tgz", - "integrity": "sha512-f5Knjh7XCyRIzoC/z1Su1yLLRrPrFCgtUAh/9fCSP6NKbATwpOL1+idQVXQokK9GRFURn/jYPGPfegIctwunoA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.5.tgz", + "integrity": "sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA==", "dev": true }, "tslib": { @@ -25838,9 +30254,9 @@ "dev": true }, "tsutils": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.11.0.tgz", - "integrity": "sha512-RRtGX1FVfHm1+P9XVqN+RxqUa8ZCZ2LjaPyaRUQH7Wvn9cYAkpz/cZKy+BWU/+fncFqjW/+PVgRWF4Ky5IGbjQ==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -25958,24 +30374,6 @@ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - } - } - }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -26039,36 +30437,6 @@ "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", "dev": true }, - "unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" - }, - "dependencies": { - "vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", - "dev": true, - "requires": { - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - } - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -26120,12 +30488,6 @@ "through2-filter": "^3.0.0" } }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -26186,12 +30548,6 @@ "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -26230,21 +30586,55 @@ "dev": true }, "url-loader": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", - "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "mime": "^2.0.3", - "schema-utils": "^1.0.0" + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" }, "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true + }, + "schema-utils": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", + "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" + } } } }, @@ -26362,9 +30752,9 @@ "dev": true }, "vendors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", - "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", "dev": true }, "verror": { @@ -26422,57 +30812,6 @@ } } }, - "vfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.0.tgz", - "integrity": "sha512-WMNeHy5djSl895BqE86D7WqA0Ie5fAIeGCa7V1EqiXyJg5LaGch2SUaZueok5abYQGH6mXEAsZ45jkoILIOlyA==", - "dev": true, - "requires": { - "@types/unist": "^2.0.2", - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "dependencies": { - "unist-util-stringify-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz", - "integrity": "sha512-Zqlf6+FRI39Bah8Q6ZnNGrEHUhwJOkHde2MHVk96lLyftfJJckaPslKgzhVcviXj8KcE9UJM9F+a4JEiBUTYgA==", - "dev": true, - "requires": { - "@types/unist": "^2.0.2" - } - }, - "vfile-message": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.0.tgz", - "integrity": "sha512-YS6qg6UpBfIeiO+6XlhPOuJaoLvt1Y9g2cmlwqhBOOU0XRV8j5RLeoz72t6PWLvNXq3EBG1fQ05wNPrUoz0deQ==", - "dev": true, - "requires": { - "@types/unist": "^2.0.2", - "unist-util-stringify-position": "^1.1.1" - }, - "dependencies": { - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - } - } - } - } - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - }, "vinyl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", @@ -26617,9 +30956,9 @@ "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" }, "vscode-nls-dev": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-3.2.6.tgz", - "integrity": "sha512-PsL6k363fp5vHZEVJX0ywT7Uem1WvqnFG/eRGxsjOIPYAXQQl8bhJSxm+kNofM8nchZOAnScbtFRz70z9evkqw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-3.3.1.tgz", + "integrity": "sha512-fug18D7CXb8pv8JoQ0D0JmZaIYDQoKLiyZxkAy5P8Cln/FwlNsdzwQILDph62EdGY5pvsJ2Jd1T5qgHAExe/tg==", "dev": true, "requires": { "ansi-colors": "^3.2.3", @@ -26633,201 +30972,119 @@ "typescript": "^2.6.2", "vinyl": "^2.1.0", "xml2js": "^0.4.19", - "yargs": "^10.1.1" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } + "yargs": "^13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "color-convert": "^1.9.0" } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "event-stream": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", + "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" } }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "p-try": "^1.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "ansi-regex": "^4.1.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, "typescript": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", "dev": true }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } }, "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" } }, "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -26893,12 +31150,6 @@ "minimalistic-assert": "^1.0.0" } }, - "web-namespaces": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.3.tgz", - "integrity": "sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA==", - "dev": true - }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -27011,167 +31262,103 @@ } }, "webpack-dev-middleware": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", - "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", "dev": true, "requires": { "memory-fs": "^0.4.1", - "mime": "^2.4.2", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", "range-parser": "^1.2.1", "webpack-log": "^2.0.0" }, "dependencies": { "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true } } }, "webpack-dev-server": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.2.1.tgz", - "integrity": "sha512-sjuE4mnmx6JOh9kvSbPYw3u/6uxCLHNWfhWaIPwcXWsvWOPN+nc5baq4i9jui3oOBRXGonK9+OI0jVkaz6/rCw==", + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.2.tgz", + "integrity": "sha512-pxZKPYb+n77UN8u9YxXT4IaIrGcNtijh/mi8TXbErHmczw0DtPnMTTjHj+eNjkqLOaAZM/qD7V59j/qJsEiaZA==", "dev": true, "requires": { "ansi-html": "0.0.7", "bonjour": "^3.5.0", - "chokidar": "^2.0.0", - "compression": "^1.5.2", - "connect-history-api-fallback": "^1.3.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", "debug": "^4.1.1", - "del": "^3.0.0", - "express": "^4.16.2", - "html-entities": "^1.2.0", - "http-proxy-middleware": "^0.19.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "0.19.1", "import-local": "^2.0.0", - "internal-ip": "^4.2.0", + "internal-ip": "^4.3.0", "ip": "^1.1.5", - "killable": "^1.0.0", - "loglevel": "^1.4.1", - "opn": "^5.1.0", - "portfinder": "^1.0.9", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.6", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.25", "schema-utils": "^1.0.0", - "selfsigned": "^1.9.1", - "semver": "^5.6.0", - "serve-index": "^1.7.2", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "^4.0.0", - "strip-ansi": "^3.0.0", + "sockjs-client": "1.4.0", + "spdy": "^4.0.1", + "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", - "webpack-dev-middleware": "^3.5.1", + "webpack-dev-middleware": "^3.7.2", "webpack-log": "^2.0.0", - "yargs": "12.0.2" + "ws": "^6.2.1", + "yargs": "12.0.5" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "dev": true, - "requires": { - "xregexp": "4.0.0" - } - }, - "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "globby": "^6.1.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "p-map": "^1.1.1", - "pify": "^3.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "supports-color": { @@ -27183,33 +31370,13 @@ "has-flag": "^3.0.0" } }, - "yargs": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", - "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^2.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^10.1.0" - } - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "async-limiter": "~1.0.0" } } } @@ -27225,14 +31392,28 @@ } }, "webpack-manifest-plugin": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.0.4.tgz", - "integrity": "sha512-nejhOHexXDBKQOj/5v5IZSfCeTO3x1Dt1RZEcGfBSul891X/eLIcIVH31gwxPDdsi2Z8LKKFGpM4w9+oTBOSCg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", "dev": true, "requires": { "fs-extra": "^7.0.0", "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", "tapable": "^1.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "webpack-sources": { @@ -27246,12 +31427,13 @@ } }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -27312,6 +31494,12 @@ "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -27476,14 +31664,14 @@ "dev": true }, "workbox-webpack-plugin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-4.2.0.tgz", - "integrity": "sha512-YZsiA+y/ns/GdWRaBsfYv8dln1ebWtGnJcTOg1ppO0pO1tScAHX0yGtHIjndxz3L/UUhE8b0NQE9KeLNwJwA5A==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz", + "integrity": "sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ==", "dev": true, "requires": { "@babel/runtime": "^7.0.0", "json-stable-stringify": "^1.0.1", - "workbox-build": "^4.2.0" + "workbox-build": "^4.3.1" } }, "workbox-window": { @@ -27575,31 +31763,25 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", "dev": true, "requires": { "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "xmlbuilder": "~11.0.0" } }, "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true }, "xmlchars": { @@ -27612,12 +31794,6 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -27635,6 +31811,15 @@ "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true }, + "yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.3" + } + }, "yargs": { "version": "12.0.5", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", diff --git a/package.json b/package.json index 730019a8e..0c716c8f6 100644 --- a/package.json +++ b/package.json @@ -1,362 +1,354 @@ { - "name": "__EXTENSIONNAME__", - "displayName": "__DISPLAYNAME__", - "description": "__DESCRIPTION__", - "version": "0.0.0-UNTRACKEDVERSION", - "publisher": "__PUBLISHER__", - "instrumentationKey": "__AIKEY__", - "icon": "assets/icon.png", - "engines": { - "vscode": "^1.34.0" - }, - "categories": [ - "Other" - ], - "preview": true, - "license": "MIT", - "homepage": "https://github.com/microsoft/vscode-python-devicesimulator", - "repository": { - "type": "git", - "url": "https://github.com/microsoft/vscode-python-devicesimulator" - }, - "bugs": { - "url": "https://github.com/microsoft/vscode-python-devicesimulator/issues" - }, - "keywords": [ - "python", - "CircuitPython", - "Adafruit" - ], - "activationEvents": [ - "onCommand:deviceSimulatorExpress.openSerialMonitor", - "onCommand:deviceSimulatorExpress.openSimulator", - "onCommand:deviceSimulatorExpress.runSimulator", - "onCommand:deviceSimulatorExpress.newFile", - "onCommand:deviceSimulatorExpress.runDevice", - "onCommand:deviceSimulatorExpress.runSimulatorEditorButton", - "onCommand:deviceSimulatorExpress.selectSerialPort", - "onDebug" - ], - "main": "./out/extension.js", - "contributes": { - "commands": [ - { - "command": "deviceSimulatorExpress.changeBaudRate", - "title": "%deviceSimulatorExpressExtension.commands.changeBaudRate%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - }, - { - "command": "deviceSimulatorExpress.closeSerialMonitor", - "title": "%deviceSimulatorExpressExtension.commands.closeSerialMonitor%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - }, - { - "command": "deviceSimulatorExpress.openSerialMonitor", - "title": "%deviceSimulatorExpressExtension.commands.openSerialMonitor%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - }, - { - "command": "deviceSimulatorExpress.openSimulator", - "title": "%deviceSimulatorExpressExtension.commands.openSimulator%", - "category": "%deviceSimulatorExpressExtension.commands.label%", - "icon": { - "light": "./assets/light-theme/open-simulator.svg", - "dark": "./assets/dark-theme/open-simulator.svg" - } - }, - { - "command": "deviceSimulatorExpress.runSimulator", - "title": "%deviceSimulatorExpressExtension.commands.runSimulator%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - }, - { - "command": "deviceSimulatorExpress.runSimulatorEditorButton", - "title": "%deviceSimulatorExpressExtension.commands.runSimulator%", - "category": "%deviceSimulatorExpressExtension.commands.label%", - "icon": { - "light": "./assets/light-theme/run-on-simulator.svg", - "dark": "./assets/dark-theme/run-on-simulator.svg" - } - }, - { - "command": "deviceSimulatorExpress.newFile", - "title": "%deviceSimulatorExpressExtension.commands.newFile%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - }, - { - "command": "deviceSimulatorExpress.runDevice", - "title": "%deviceSimulatorExpressExtension.commands.runDevice%", - "category": "%deviceSimulatorExpressExtension.commands.label%", - "icon": { - "light": "./assets/light-theme/save-to-board.svg", - "dark": "./assets/dark-theme/save-to-board.svg" - } - }, - { - "command": "deviceSimulatorExpress.selectSerialPort", - "title": "%deviceSimulatorExpressExtension.commands.selectSerialPort%", - "category": "%deviceSimulatorExpressExtension.commands.label%" - } - ], - "colors": [ - { - "id": "highContrastButtonBorderOverride.color", - "description": "Color for the high contrast border updated", - "defaults": { - "dark": "debugToolBar.background", - "light": "debugToolBar.background", - "highContrast": "#6FC3DF" - } - }, - { - "id": "badgeForegroundOverride", - "description": "Color that fixes the issue with midnight blue ", - "defaults": { - "dark": "#FFFFFF", - "light": "badge.foreground", - "highContrast": "#FFFFFF" - } - } + "name": "__EXTENSIONNAME__", + "displayName": "__DISPLAYNAME__", + "description": "__DESCRIPTION__", + "version": "0.0.0-UNTRACKEDVERSION", + "publisher": "__PUBLISHER__", + "instrumentationKey": "__AIKEY__", + "icon": "assets/icon.png", + "engines": { + "vscode": "^1.34.0" + }, + "categories": [ + "Other" ], - "menus": { - "commandPalette": [ - { - "command": "deviceSimulatorExpress.runSimulatorEditorButton", - "when": "false" - } - ], - "editor/title": [ - { - "when": "editorLangId==python && config.deviceSimulatorExpress.showOpenIconInEditorTitleMenu", - "command": "deviceSimulatorExpress.openSimulator", - "group": "navigation@1" - }, - { - "when": "editorLangId==python && config.deviceSimulatorExpress.showSimulatorIconInEditorTitleMenu", - "command": "deviceSimulatorExpress.runSimulatorEditorButton", - "group": "navigation@2" - }, - { - "when": "editorLangId==python && config.deviceSimulatorExpress.showDeviceIconInEditorTitleMenu", - "command": "deviceSimulatorExpress.runDevice", - "group": "navigation@3" - } - ] + "preview": true, + "license": "MIT", + "homepage": "https://github.com/microsoft/vscode-python-devicesimulator", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/vscode-python-devicesimulator" }, - "configuration": { - "type": "object", - "title": "%deviceSimulatorExpressExtension.configuration.title%", - "properties": { - "deviceSimulatorExpress.enableUSBDetection": { - "type": "boolean", - "default": true - }, - "deviceSimulatorExpress.showOpenIconInEditorTitleMenu": { - "type": "boolean", - "default": true, - "description": "%deviceSimulatorExpressExtension.configuration.properties.open%", - "scope": "resource" - }, - "deviceSimulatorExpress.showSimulatorIconInEditorTitleMenu": { - "type": "boolean", - "default": true, - "description": "%deviceSimulatorExpressExtension.configuration.properties.simulator%", - "scope": "resource" - }, - "deviceSimulatorExpress.showDeviceIconInEditorTitleMenu": { - "type": "boolean", - "default": true, - "description": "%deviceSimulatorExpressExtension.configuration.properties.device%", - "scope": "resource" - }, - "deviceSimulatorExpress.showDependencyInstall": { - "type": "boolean", - "default": true, - "scope": "resource" - }, - "deviceSimulatorExpress.showNewFilePopup": { - "type": "boolean", - "default": true, - "scope": "resource" - }, - "deviceSimulatorExpress.debuggerServerPort": { - "type": "number", - "default": 5577, - "description": "%deviceSimulatorExpressExtension.configuration.properties.debuggerPort%", - "scope": "resource" - } - } + "bugs": { + "url": "https://github.com/microsoft/vscode-python-devicesimulator/issues" }, - "breakpoints": [ - { - "language": "python" - } + "keywords": [ + "python", + "CircuitPython", + "Adafruit", + "microbit", + "MicroPython" + ], + "activationEvents": [ + "onCommand:deviceSimulatorExpress.common.installDependencies", + "onCommand:deviceSimulatorExpress.common.runSimulator", + "onCommand:deviceSimulatorExpress.cpx.deployToDevice", + "onCommand:deviceSimulatorExpress.cpx.newFile", + "onCommand:deviceSimulatorExpress.cpx.openSerialMonitor", + "onCommand:deviceSimulatorExpress.cpx.openSimulator", + "onCommand:deviceSimulatorExpress.cpx.selectSerialPort", + "onCommand:deviceSimulatorExpress.microbit.newFile", + "onCommand:deviceSimulatorExpress.microbit.openSimulator", + "onDebug" ], - "debuggers": [ - { - "type": "deviceSimulatorExpress", - "label": "Device Simulator Express Debugger", - "languages": [ - "python" + "main": "./out/extension.js", + "contributes": { + "commands": [ + { + "command": "deviceSimulatorExpress.common.installDependencies", + "title": "%deviceSimulatorExpressExtension.commands.common.installDependencies%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.common.runSimulator", + "title": "%deviceSimulatorExpressExtension.commands.common.runSimulator%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.changeBaudRate", + "title": "%deviceSimulatorExpressExtension.commands.cpx.changeBaudRate%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.closeSerialMonitor", + "title": "%deviceSimulatorExpressExtension.commands.cpx.closeSerialMonitor%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.deployToDevice", + "title": "%deviceSimulatorExpressExtension.commands.cpx.deployToDevice%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.newFile", + "title": "%deviceSimulatorExpressExtension.commands.cpx.newFile%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.openSerialMonitor", + "title": "%deviceSimulatorExpressExtension.commands.cpx.openSerialMonitor%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.openSimulator", + "title": "%deviceSimulatorExpressExtension.commands.cpx.openSimulator%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.cpx.selectSerialPort", + "title": "%deviceSimulatorExpressExtension.commands.cpx.selectSerialPort%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.microbit.openSimulator", + "title": "%deviceSimulatorExpressExtension.commands.microbit.openSimulator%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + }, + { + "command": "deviceSimulatorExpress.microbit.newFile", + "title": "%deviceSimulatorExpressExtension.commands.microbit.newFile%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%" + } ], - "configurationAttributes": { - "launch": { - "properties": { - "program": { - "type": "string", - "description": "Absolute path to the code file.", - "default": "${file}" - }, - "stopOnEntry": { - "type": "boolean", - "description": "Automatically stop after launch.", - "default": true - }, - "console": { - "enum": [ - "internalConsole", - "integratedTerminal", - "externalTerminal" - ], - "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", - "default": "integratedTerminal" - }, - "args": { - "type": "array", - "description": "Command line arguments passed to the program.", - "default": [], - "items": { - "filePath": "string", - "serverPort": "string" + "menus": { + "commandPalette": [ + { + "command": "deviceSimulatorExpress.microbit.openSimulator", + "title": "%deviceSimulatorExpressExtension.commands.microbit.openSimulator%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%", + "when": "config.deviceSimulatorExpress.previewMode" + }, + { + "command": "deviceSimulatorExpress.microbit.newFile", + "title": "%deviceSimulatorExpressExtension.commands.microbit.newFile%", + "category": "%deviceSimulatorExpressExtension.commands.common.label%", + "when": "config.deviceSimulatorExpress.previewMode" } - }, - "rules": { - "type": "array", - "description": "Debugger rules.", - "default": [], - "items": { - "path": "string", - "include": "boolean" + ] + }, + "colors": [ + { + "id": "highContrastButtonBorderOverride.color", + "description": "Color for the high contrast border updated", + "defaults": { + "dark": "debugToolBar.background", + "light": "debugToolBar.background", + "highContrast": "#6FC3DF" + } + }, + { + "id": "badgeForegroundOverride", + "description": "Color that fixes the issue with midnight blue ", + "defaults": { + "dark": "#FFFFFF", + "light": "badge.foreground", + "highContrast": "#FFFFFF" + } + } + ], + "configuration": { + "type": "object", + "title": "%deviceSimulatorExpressExtension.configuration.title%", + "properties": { + "deviceSimulatorExpress.configNewEnvironmentUponSwitch": { + "type": "boolean", + "default": false, + "description": "%deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange%", + "scope": "resource" + }, + "deviceSimulatorExpress.enableUSBDetection": { + "type": "boolean", + "default": true + }, + "deviceSimulatorExpress.showDependencyInstall": { + "type": "boolean", + "default": true, + "description": "%deviceSimulatorExpressExtension.configuration.properties.dependencyChecker%", + "scope": "resource" + }, + "deviceSimulatorExpress.showNewFilePopup": { + "type": "boolean", + "default": true, + "scope": "resource" + }, + "deviceSimulatorExpress.debuggerServerPort": { + "type": "number", + "default": 5577, + "description": "%deviceSimulatorExpressExtension.configuration.properties.debuggerPort%", + "scope": "resource" + }, + "deviceSimulatorExpress.previewMode": { + "type": "boolean", + "default": false, + "description": "%deviceSimulatorExpressExtension.configuration.properties.previewMode%", + "scope": "resource" } - } } - } }, - "initialConfigurations": [ - { - "type": "deviceSimulatorExpress", - "request": "launch", - "name": "Device Simulator Express Debugger", - "console": "integratedTerminal" - } + "breakpoints": [ + { + "language": "python" + } ], - "configurationSnippets": [ - { - "label": "Device Simulator Express Debugger : Launch", - "description": "Device Simulator Express Debugger - A configuration for debugging a python code file for the Device Simulator Express simulator.", - "body": { - "type": "deviceSimulatorExpress", - "request": "launch", - "name": "Device Simulator Express Debugger", - "console": "integratedTerminal" + "debuggers": [ + { + "type": "deviceSimulatorExpress", + "label": "Device Simulator Express Debugger", + "languages": [ + "python" + ], + "configurationAttributes": { + "launch": { + "properties": { + "program": { + "type": "string", + "description": "Absolute path to the code file.", + "default": "${file}" + }, + "stopOnEntry": { + "type": "boolean", + "description": "Automatically stop after launch.", + "default": true + }, + "console": { + "enum": [ + "internalConsole", + "integratedTerminal", + "externalTerminal" + ], + "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", + "default": "integratedTerminal" + }, + "args": { + "type": "array", + "description": "Command line arguments passed to the program.", + "default": [], + "items": { + "filePath": "string", + "serverPort": "string" + } + }, + "rules": { + "type": "array", + "description": "Debugger rules.", + "default": [], + "items": { + "path": "string", + "include": "boolean" + } + } + } + } + }, + "initialConfigurations": [ + { + "type": "deviceSimulatorExpress", + "request": "launch", + "name": "Device Simulator Express Debugger", + "console": "integratedTerminal" + } + ], + "configurationSnippets": [ + { + "label": "Device Simulator Express Debugger : Launch", + "description": "Device Simulator Express Debugger - A configuration for debugging a python code file for the Device Simulator Express simulator.", + "body": { + "type": "deviceSimulatorExpress", + "request": "launch", + "name": "Device Simulator Express Debugger", + "console": "integratedTerminal" + } + } + ] } - } ] - } + }, + "scripts": { + "start": "webpack-dev-server", + "vscode:prepublish": "npm run compile", + "build": "gulp build", + "clean": "gulp clean", + "compile": "npm-run-all compile:*", + "compile:extension": "gulp compile", + "compile:views": "webpack --mode development", + "watch": "npm-run-all -p watch:*", + "watch:extension": "tsc --watch", + "watch:views": "webpack --watch --mode development", + "pretest": "npm run compile", + "test": "npm-run-all test:*", + "test:extension-tests": "node ./out/test/runTest.js", + "test:ts": "jest", + "test:api-tests": "pytest src", + "lint": "npm-run-all lint:*", + "lint:ts": "tslint -c tslint.json src/**/*.{ts,tsx}", + "lint:python": "pylint src", + "format": "npm-run-all format:*", + "format:ts": "prettier --config .prettierrc.yaml --write src/**/*.{css,ts,tsx}", + "format:python": "black src", + "check": "npm-run-all check:*", + "check:ts": "prettier --config .prettierrc.yaml --check src/**/*.{css,ts,tsx}", + "check:python": "black src --check", + "package": "vsce package" + }, + "devDependencies": { + "@types/glob": "^7.1.1", + "@types/node": "^10.12.21", + "@types/react": "16.8.6", + "@types/react-dom": "16.8.4", + "@types/vscode": "^1.34.0", + "css-loader": "^1.0.0", + "del": "^4.0.0", + "event-stream": "^4.0.1", + "gulp": "^4.0.2", + "gulp-cli": "^2.1.0", + "gulp-filter": "^5.1.0", + "gulp-sourcemaps": "^2.6.5", + "gulp-typescript": "^5.0.1", + "less": "^3.7.0", + "less-loader": "^4.1.0", + "mocha": "^6.1.4", + "npm-run-all": "^4.1.3", + "prettier": "^1.19.1", + "react-scripts": "^3.4.0", + "style-loader": "^0.21.0", + "ts-import-plugin": "^1.5.4", + "ts-loader": "^4.4.2", + "tslint": "^5.12.1", + "tslint-config-prettier": "^1.18.0", + "tslint-microsoft-contrib": "^6.1.0", + "tslint-react": "^3.6.0", + "tslint-react-hooks": "^2.0.0", + "typescript": "^3.3.1", + "typescript-react-intl": "^0.4.0", + "version-from-git": "^1.1.1", + "vsce": "^1.47.0", + "vscode-nls-dev": "^3.2.6", + "vscode-test": "^1.0.0", + "webpack": "^4.15.1", + "webpack-cli": "^3.0.8" + }, + "dependencies": { + "@babel/preset-typescript": "^7.8.3", + "@testing-library/jest-dom": "^5.0.2", + "@testing-library/react": "^9.4.0", + "@types/jest": "^24.9.0", + "@types/open": "^6.1.0", + "@types/react-test-renderer": "^16.9.0", + "@types/socket.io": "^2.1.2", + "babel-jest": "^25.1.0", + "compare-versions": "^3.5.1", + "eventemitter2": "^5.0.1", + "glob": "^7.1.4", + "jest": "^25.1.0", + "jest-transform-css": "^2.0.0", + "office-ui-fabric-react": "^7.85.0", + "open": "^6.4.0", + "os": "^0.1.1", + "react": "^16.9.0", + "react-dom": "^16.9.0", + "react-intl": "^3.1.9", + "react-test-renderer": "^16.9.0", + "socket.io": "^2.2.0", + "svg-inline-react": "^3.1.0", + "ts-jest": "^25.0.0", + "util": "^0.12.1", + "vscode-extension-telemetry": "^0.1.1", + "vscode-nls": "^4.1.0" + }, + "eslintConfig": { + "extends": "react-app" + }, + "extensionDependencies": [ + "ms-python.python" ] - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "build": "gulp build", - "clean": "gulp clean", - "compile": "npm-run-all compile:*", - "compile:extension": "gulp compile", - "compile:views": "webpack --mode development", - "watch": "npm-run-all -p watch:*", - "watch:extension": "tsc --watch", - "watch:views": "webpack --watch --mode development", - "pretest": "npm run compile", - "test": "npm-run-all test:*", - "test:extension-tests": "node ./out/test/runTest.js", - "test:react": "jest", - "test:api-tests": "pytest src", - "lint": "npm-run-all lint:*", - "lint:ts": "tslint -c tslint.json src/**/*.{ts,tsx}", - "lint:python": "pylint src", - "format": "npm-run-all format:*", - "format:ts": "prettier --config .prettierrc.yaml --write src/**/*.{css,ts,tsx}", - "format:python": "black src", - "check": "npm-run-all check:*", - "check:ts": "prettier --config .prettierrc.yaml --check src/**/*.{css,ts,tsx}", - "check:python": "black src --check", - "package": "vsce package" - }, - "devDependencies": { - "@types/glob": "^7.1.1", - "@types/node": "^10.12.21", - "@types/react": "16.8.18", - "@types/react-dom": "16.8.4", - "@types/vscode": "^1.34.0", - "css-loader": "^1.0.0", - "del": "^4.0.0", - "event-stream": "^4.0.1", - "gulp": "^4.0.2", - "gulp-cli": "^2.1.0", - "gulp-filter": "^5.1.0", - "gulp-sourcemaps": "^2.6.5", - "gulp-typescript": "^5.0.1", - "less": "^3.7.0", - "less-loader": "^4.1.0", - "mocha": "^6.1.4", - "npm-run-all": "^4.1.3", - "prettier": "^1.19.1", - "react-scripts": "3.0.1", - "style-loader": "^0.21.0", - "ts-import-plugin": "^1.5.4", - "ts-loader": "^4.4.2", - "tslint": "^5.12.1", - "tslint-config-prettier": "^1.18.0", - "tslint-microsoft-contrib": "^6.1.0", - "tslint-react": "^3.6.0", - "tslint-react-hooks": "^2.0.0", - "typescript": "^3.3.1", - "typescript-react-intl": "^0.4.0", - "version-from-git": "^1.1.1", - "vsce": "^1.47.0", - "vscode-nls-dev": "^3.2.6", - "vscode-test": "^1.0.0", - "webpack": "^4.15.1", - "webpack-cli": "^3.0.8" - }, - "dependencies": { - "@babel/preset-typescript": "^7.8.3", - "@testing-library/jest-dom": "^5.0.2", - "@testing-library/react": "^9.4.0", - "@types/jest": "^24.9.0", - "@types/open": "^6.1.0", - "@types/socket.io": "^2.1.2", - "babel-jest": "^25.1.0", - "compare-versions": "^3.5.1", - "eventemitter2": "^5.0.1", - "glob": "^7.1.4", - "jest": "^25.1.0", - "jest-transform-css": "^2.0.0", - "open": "^6.4.0", - "os": "^0.1.1", - "react": "^16.8.6", - "react-dom": "^16.8.6", - "react-intl": "^3.1.9", - "socket.io": "^2.2.0", - "svg-inline-react": "^3.1.0", - "ts-jest": "^25.0.0", - "util": "^0.12.1", - "vscode-extension-telemetry": "^0.1.1", - "vscode-nls": "^4.1.0" - }, - "eslintConfig": { - "extends": "react-app" - }, - "extensionDependencies": [ - "ms-python.python" - ] } diff --git a/package.nls.json b/package.nls.json index 49d2906a0..1092a8d4a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -1,16 +1,19 @@ { - "deviceSimulatorExpressExtension.commands.changeBaudRate": "Change Baud Rate", - "deviceSimulatorExpressExtension.commands.closeSerialMonitor": "Close Serial Monitor", - "deviceSimulatorExpressExtension.commands.label": "Device Simulator Express", - "deviceSimulatorExpressExtension.commands.openSerialMonitor": "Open Serial Monitor", - "deviceSimulatorExpressExtension.commands.openSimulator": "Open Simulator", - "deviceSimulatorExpressExtension.commands.runSimulator": "Run Simulator", - "deviceSimulatorExpressExtension.commands.newFile": "New File", - "deviceSimulatorExpressExtension.commands.runDevice": "Deploy to Device", - "deviceSimulatorExpressExtension.commands.selectSerialPort": "Select Serial Port", + "deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies", + "deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express", + "deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator", + "deviceSimulatorExpressExtension.commands.cpx.changeBaudRate": "[Circuit Playground Express] Change Baud Rate", + "deviceSimulatorExpressExtension.commands.cpx.closeSerialMonitor": "[Circuit Playground Express] Close Serial Monitor", + "deviceSimulatorExpressExtension.commands.cpx.openSerialMonitor": "[Circuit Playground Express] Open Serial Monitor", + "deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator", + "deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File", + "deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device", + "deviceSimulatorExpressExtension.commands.cpx.selectSerialPort": "[Circuit Playground Express] Select Serial Port", + "deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator", + "deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File", "deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration", - "deviceSimulatorExpressExtension.configuration.properties.open": "Whether to show 'Open Simulator' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.device": "Whether to show 'Run Device' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.simulator": "Whether to show 'Run Simulator' icon in editor title menu.", - "deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger." + "deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.", + "deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.", + "deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask for dependency downloads. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files.", + "deviceSimulatorExpressExtension.configuration.properties.previewMode": "Enable this to test out and play with the new micro:bit simulator!" } diff --git a/src/adafruit_circuitplayground/constants.py b/src/adafruit_circuitplayground/constants.py index 26642a710..a96083795 100644 --- a/src/adafruit_circuitplayground/constants.py +++ b/src/adafruit_circuitplayground/constants.py @@ -7,6 +7,8 @@ BRIGHTNESS_RANGE_ERROR = "The brightness value should be a number between 0 and 1." +CPX = "CPX" + INDEX_ERROR = ( "The index is not a valid number, you can access the Neopixels from 0 to 9." ) @@ -25,23 +27,23 @@ VALID_PIXEL_ASSIGN_ERROR = "The pixel color value should be a tuple with three values between 0 and 255 or a hexadecimal color between 0x000000 and 0xFFFFFF." -TELEMETRY_EVENT_NAMES = { - "TAPPED": "API.TAPPED", - "PLAY_FILE": "API.PLAY.FILE", - "PLAY_TONE": "API.PLAY.TONE", - "START_TONE": "API.START.TONE", - "STOP_TONE": "API.STOP.TONE", - "DETECT_TAPS": "API.DETECT.TAPS", - "ADJUST_THRESHOLD": "API.ADJUST.THRESHOLD", - "RED_LED": "API.RED.LED", - "PIXELS": "API.PIXELS", -} ERROR_SENDING_EVENT = "Error trying to send event to the process : " TIME_DELAY = 0.03 -DEFAULT_PORT = "5577" - EVENTS_BUTTON_PRESS = ["button_a", "button_b", "switch"] EVENTS_SENSOR_CHANGED = ["temperature", "light", "motion_x", "motion_y", "motion_z"] + +ALL_EXPECTED_INPUT_EVENTS = [ + "button_a", + "button_b", + "switch", + "temperature", + "light", + "shake", + "motion_x", + "motion_y", + "motion_z", + "touch", +] diff --git a/src/adafruit_circuitplayground/debugger_communication_client.py b/src/adafruit_circuitplayground/debugger_communication_client.py deleted file mode 100644 index 0536550ea..000000000 --- a/src/adafruit_circuitplayground/debugger_communication_client.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. - -import sys -import json -import socketio -from . import express -from . import constants as CONSTANTS - - -# Create Socket Client -sio = socketio.Client(reconnection_attempts=2) - -# TODO: Get port from process_user_code.py via childprocess communication - - -# Initialize connection -def init_connection(port=CONSTANTS.DEFAULT_PORT): - sio.connect("http://localhost:{}".format(port)) - - -# Transfer the user's inputs to the API -def __update_api_state(data, expected_events): - try: - event_state = json.loads(data) - for event in expected_events: - express.cpx._Express__state[event] = event_state.get( - event, express.cpx._Express__state[event] - ) - except Exception as e: - print(CONSTANTS.ERROR_SENDING_EVENT, e, file=sys.stderr, flush=True) - - -# Method : Update State -def update_state(state): - sio.emit("updateState", state) - - -## Events Handlers ## - - -# Event : Button pressed (A, B, A+B, Switch) -@sio.on("button_press") -def button_press(data): - __update_api_state(data, CONSTANTS.EVENTS_BUTTON_PRESS) - - -# Event : Sensor changed (Temperature, light, Motion) -@sio.on("sensor_changed") -def sensor_changed(data): - __update_api_state(data, CONSTANTS.EVENTS_SENSOR_CHANGED) diff --git a/src/adafruit_circuitplayground/express.py b/src/adafruit_circuitplayground/express.py index f08e1b65c..884f4a723 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -5,12 +5,15 @@ import sys import os import playsound + +from common import utils +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent from .pixel import Pixel -from . import utils from . import constants as CONSTANTS from collections import namedtuple from applicationinsights import TelemetryClient -from .telemetry import telemetry_py +import common Acceleration = namedtuple("acceleration", ["x", "y", "z"]) @@ -50,25 +53,29 @@ def __init__(self): @property def acceleration(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_ACCELERATION) return Acceleration( self.__state["motion_x"], self.__state["motion_y"], self.__state["motion_z"] ) @property def button_a(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BUTTON_A) return self.__state["button_a"] @property def button_b(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BUTTON_B) return self.__state["button_b"] @property def detect_taps(self): - telemetry_py.send_telemetry("DETECT_TAPS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_DETECT_TAPS) return self.__state["detect_taps"] @detect_taps.setter def detect_taps(self, value): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_DETECT_TAPS) value_int = int(value) self.__state["detect_taps"] = ( value_int if (value_int == 1 or value_int == 2) else 1 @@ -78,36 +85,45 @@ def detect_taps(self, value): def tapped(self): """ Not Implemented! """ - telemetry_py.send_telemetry("TAPPED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TAPPED) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) @property def red_led(self): - telemetry_py.send_telemetry("RED_LED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_RED_LED) return self.__state["red_led"] @red_led.setter def red_led(self, value): - telemetry_py.send_telemetry("RED_LED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_RED_LED) self.__state["red_led"] = bool(value) self.__show() @property def switch(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_SWITCH) return self.__state["switch"] @property def temperature(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TEMPERATURE) return self.__state["temperature"] @property def light(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_LIGHT) return self.__state["light"] def __show(self): - utils.show(self.__state, self.__debug_mode) + if self.__debug_mode: + common.debugger_communication_client.debug_send_to_simulator( + self.__state, CONSTANTS.CPX + ) + else: + utils.send_to_simulator(self.__state, CONSTANTS.CPX) def __touch(self, i): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TOUCH) return self.__state["touch"][i - 1] @property @@ -142,14 +158,15 @@ def adjust_touch_threshold(self, adjustement): """Not implemented! The CPX Simulator doesn't use capacitive touch threshold. """ - telemetry_py.send_telemetry("ADJUST_THRESHOLD") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_ADJUST_THRESHOLD) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def shake(self, shake_threshold=30): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_SHAKE) return self.__state["shake"] def play_file(self, file_name): - telemetry_py.send_telemetry("PLAY_FILE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PLAY_FILE) file_name = utils.remove_leading_slashes(file_name) abs_path_parent_dir = os.path.abspath( os.path.join(self.__abs_path_to_code_file, os.pardir) @@ -174,20 +191,26 @@ def play_file(self, file_name): def play_tone(self, frequency, duration): """ Not Implemented! """ - telemetry_py.send_telemetry("PLAY_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PLAY_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def start_tone(self, frequency): """ Not Implemented! """ - telemetry_py.send_telemetry("START_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_START_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def stop_tone(self): """ Not Implemented! """ - telemetry_py.send_telemetry("STOP_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_STOP_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) + def update_state(self, new_state): + for event in CONSTANTS.ALL_EXPECTED_INPUT_EVENTS: + self._Express__state[event] = new_state.get( + event, self._Express__state[event] + ) + cpx = Express() diff --git a/src/adafruit_circuitplayground/pixel.py b/src/adafruit_circuitplayground/pixel.py index 3833de2f7..18e0028fc 100644 --- a/src/adafruit_circuitplayground/pixel.py +++ b/src/adafruit_circuitplayground/pixel.py @@ -3,11 +3,12 @@ import json import sys +import common + +from common import utils +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent from . import constants as CONSTANTS -from . import utils -from applicationinsights import TelemetryClient -from . import constants as CONSTANTS -from .telemetry import telemetry_py class Pixel: @@ -19,7 +20,13 @@ def __init__(self, state, debug_mode=False): def show(self): # Send the state to the extension so that React re-renders the Webview - utils.show(self.__state, self.__debug_mode) + # or send the state to the debugger (within this library) + if self.__debug_mode: + common.debugger_communication_client.debug_send_to_simulator( + self.__state, CONSTANTS.CPX + ) + else: + common.utils.send_to_simulator(self.__state, CONSTANTS.CPX) def __show_if_auto_write(self): if self.auto_write: @@ -32,11 +39,11 @@ def __getitem__(self, index): if type(index) is not slice: if not self.__valid_index(index): raise IndexError(CONSTANTS.INDEX_ERROR) - telemetry_py.send_telemetry("PIXELS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS) return self.__state["pixels"][index] def __setitem__(self, index, val): - telemetry_py.send_telemetry("PIXELS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS) is_slice = False if type(index) is slice: is_slice = True @@ -109,12 +116,14 @@ def __valid_rgb_value(self, pixValue): @property def brightness(self): + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BRIGHTNESS) return self.__state["brightness"] @brightness.setter def brightness(self, brightness): if not self.__valid_brightness(brightness): raise ValueError(CONSTANTS.BRIGHTNESS_RANGE_ERROR) + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BRIGHTNESS) self.__state["brightness"] = brightness self.__show_if_auto_write() diff --git a/src/adafruit_circuitplayground/telemetry.py b/src/adafruit_circuitplayground/telemetry.py deleted file mode 100644 index 9fd1edb1c..000000000 --- a/src/adafruit_circuitplayground/telemetry.py +++ /dev/null @@ -1,41 +0,0 @@ -from . import constants as CONSTANTS -from applicationinsights import TelemetryClient - - -class Telemetry: - def __init__(self): - # State of the telemetry - self.__enable_telemetry = True - self.telemetry_state = { - "DETECT_TAPS": False, - "TAPPED": False, - "RED_LED": False, - "ADJUST_THRESHOLD": False, - "PLAY_FILE": False, - "PLAY_TONE": False, - "START_TONE": False, - "STOP_TONE": False, - "PIXELS": False, - } - self.telemetry_client = TelemetryClient("__AIKEY__") - self.extension_name = "__EXTENSIONNAME__" - - def send_telemetry(self, event_name): - if ( - self.__enable_telemetry - and self.telemetry_available() - and not self.telemetry_state[event_name] - ): - self.telemetry_client.track_event( - "{}/{}".format( - self.extension_name, CONSTANTS.TELEMETRY_EVENT_NAMES[event_name] - ) - ) - self.telemetry_client.flush() - self.telemetry_state[event_name] = True - - def telemetry_available(self): - return self.telemetry_client.context.instrumentation_key != "__AIKEY__" - - -telemetry_py = Telemetry() diff --git a/src/adafruit_circuitplayground/test/test_debugger_communication_client.py b/src/adafruit_circuitplayground/test/test_debugger_communication_client.py deleted file mode 100644 index b25e27eb8..000000000 --- a/src/adafruit_circuitplayground/test/test_debugger_communication_client.py +++ /dev/null @@ -1,63 +0,0 @@ -import pytest -import json # Remove -from unittest import mock -import socketio - -from .. import express -from .. import debugger_communication_client - - -class TestDebuggerCommunicationClient(object): - @mock.patch("socketio.Client.connect") - def test_init_connection(self, mock_connect): - mock_connect.return_value = None - debugger_communication_client.init_connection() - mock_connect.assert_called_once() - - def test_init_connection1(self): - socketio.Client.connect = mock.Mock() - socketio.Client.connect.return_value = None - debugger_communication_client.init_connection() - socketio.Client.connect.assert_called_once() - - def test_update_state(self): - socketio.Client.emit = mock.Mock() - socketio.Client.emit.return_value = None - debugger_communication_client.update_state({}) - socketio.Client.emit.assert_called_once() - - @mock.patch.dict( - express.cpx._Express__state, - {"button_a": False, "button_b": False, "switch": True}, - clear=True, - ) - def test_button_press(self): - data = {"button_a": True, "button_b": True, "switch": True} - serialized_data = json.dumps(data) - debugger_communication_client.button_press(serialized_data) - assert data == express.cpx._Express__state - - @mock.patch.dict( - express.cpx._Express__state, - {"temperature": 0, "light": 0, "motion_x": 0, "motion_y": 0, "motion_z": 0}, - clear=True, - ) - def test_sensor_changed(self): - data = { - "temperature": 1, - "light": 2, - "motion_x": 3, - "motion_y": 4, - "motion_z": 5, - } - serialized_data = json.dumps(data) - debugger_communication_client.sensor_changed(serialized_data) - assert data == express.cpx._Express__state - - @mock.patch("builtins.print") - @mock.patch.dict(express.cpx._Express__state, {}, clear=True) - def test_update_api_state_fail(self, mocked_print): - data = [] - debugger_communication_client.sensor_changed(data) - # Exception is caught and a print is stated to stderr - mocked_print.assert_called_once() diff --git a/src/adafruit_circuitplayground/test/test_utils.py b/src/adafruit_circuitplayground/test/test_utils.py index 3c25128e6..a3c38e1b1 100644 --- a/src/adafruit_circuitplayground/test/test_utils.py +++ b/src/adafruit_circuitplayground/test/test_utils.py @@ -3,7 +3,7 @@ from unittest import mock from .. import constants as CONSTANTS -from .. import utils +from common import utils class TestUtils(object): diff --git a/src/adafruit_circuitplayground/utils.py b/src/adafruit_circuitplayground/utils.py deleted file mode 100644 index 14fddf227..000000000 --- a/src/adafruit_circuitplayground/utils.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. - -import sys -import json -import copy -import time -from . import constants as CONSTANTS -from . import debugger_communication_client -from applicationinsights import TelemetryClient - -previous_state = {} - - -def show(state, debug_mode=False): - global previous_state - if state != previous_state: - previous_state = copy.deepcopy(state) - message = {"type": "state", "data": json.dumps(state)} - if debug_mode: - debugger_communication_client.update_state(json.dumps(message)) - else: - print(json.dumps(message) + "\0", end="", file=sys.__stdout__, flush=True) - time.sleep(CONSTANTS.TIME_DELAY) - - -def remove_leading_slashes(string): - string = string.lstrip("\\/") - return string - - -def escape_if_OSX(file_name): - if sys.platform.startswith(CONSTANTS.MAC_OS): - file_name = file_name.replace(" ", "%20") - return file_name diff --git a/src/check_if_venv.py b/src/check_if_venv.py new file mode 100644 index 000000000..45fd3dd2b --- /dev/null +++ b/src/check_if_venv.py @@ -0,0 +1,11 @@ +# from https://stackoverflow.com/questions/1871549/determine-if-python-is-running-inside-virtualenv +import sys + +isVenv = hasattr(sys, "real_prefix") or ( + hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix +) + +# prints result for frontend to read +# 1 -> is a venv +# 0 -> is NOT a venv +print(int(isVenv)) diff --git a/src/check_python_dependencies.py b/src/check_python_dependencies.py new file mode 100644 index 000000000..2e8f5ba13 --- /dev/null +++ b/src/check_python_dependencies.py @@ -0,0 +1,20 @@ +# from https://stackoverflow.com/questions/16294819/check-if-my-python-has-all-required-packages +import sys +import pkg_resources +import python_constants as CONSTANTS + + +def check_for_dependencies(): + with open(f"{sys.path[0]}/requirements.txt") as f: + dependencies = [x.strip() for x in f.readlines()] + + # here, if a dependency is not met, a DistributionNotFound or VersionConflict + # exception is caught and replaced with a new exception with a clearer description. + try: + pkg_resources.require(dependencies) + except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict) as e: + raise Exception(CONSTANTS.DEPEND_ERR) + + +if __name__ == "__main__": + check_for_dependencies() diff --git a/src/common/__init__.py b/src/common/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/common/constants.py b/src/common/constants.py new file mode 100644 index 000000000..73984933a --- /dev/null +++ b/src/common/constants.py @@ -0,0 +1,10 @@ +MAC_OS = "darwin" + +ERROR_SENDING_EVENT = "Error trying to send event to the process : " + +ACTIVE_DEVICE_FIELD = "active_device" +STATE_FIELD = "state" + +CONNECTION_ATTEMPTS = 10 +TIME_DELAY = 0.03 +DEFAULT_PORT = "5577" diff --git a/src/common/debugger_communication_client.py b/src/common/debugger_communication_client.py new file mode 100644 index 000000000..23035c6f9 --- /dev/null +++ b/src/common/debugger_communication_client.py @@ -0,0 +1,86 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +import sys +import json +import socketio +import copy + +from . import constants as CONSTANTS +from . import utils +import threading + + +from adafruit_circuitplayground.express import cpx +from adafruit_circuitplayground.constants import CPX + +from microbit.__model.microbit_model import __mb as mb +from microbit.__model.constants import MICROBIT + + +device_dict = {CPX: cpx, MICROBIT: mb} +processing_state_event = threading.Event() +previous_state = {} + +# similar to utils.send_to_simulator, but for debugging +# (needs handle to device-specific debugger) +def debug_send_to_simulator(state, active_device): + global previous_state + if state != previous_state: + previous_state = copy.deepcopy(state) + + updated_state = utils.update_state_with_device_name(state, active_device) + message = utils.create_message(updated_state) + + update_state(json.dumps(message)) + + +# Create Socket Client +sio = socketio.Client(reconnection_attempts=CONSTANTS.CONNECTION_ATTEMPTS) + +# TODO: Get port from process_user_code.py via childprocess communication + + +# Initialize connection +def init_connection(port=CONSTANTS.DEFAULT_PORT): + sio.connect("http://localhost:{}".format(port)) + + +# Transfer the user's inputs to the API +def __update_api_state(data): + try: + event_state = json.loads(data) + active_device_string = event_state.get(CONSTANTS.ACTIVE_DEVICE_FIELD) + + if active_device_string is not None: + active_device = device_dict.get(active_device_string) + if active_device is not None: + active_device.update_state(event_state.get(CONSTANTS.STATE_FIELD)) + + except Exception as e: + print(CONSTANTS.ERROR_SENDING_EVENT, e, file=sys.stderr, flush=True) + + +# Method : Update State +def update_state(state): + processing_state_event.clear() + sio.emit("updateState", state) + processing_state_event.wait() + + +# Event : Button pressed (A, B, A+B, Switch) +# or Sensor changed (Temperature, light, Motion) +@sio.on("input_changed") +def input_changed(data): + sio.emit("receivedState", data) + __update_api_state(data) + + +@sio.on("received_state") +def received_state(data): + processing_state_event.set() + + +@sio.on("process_disconnect") +def process_disconnect(data): + sio.disconnect() diff --git a/src/common/telemetry.py b/src/common/telemetry.py new file mode 100644 index 000000000..44a22d058 --- /dev/null +++ b/src/common/telemetry.py @@ -0,0 +1,31 @@ +from applicationinsights import TelemetryClient +from .telemetry_events import TelemetryEvent + + +class Telemetry: + def __init__(self): + # State of the telemetry + self.__enable_telemetry = True + self.telemetry_client = TelemetryClient("__AIKEY__") + self.telemetry_state = dict.fromkeys( + [name for name, _ in TelemetryEvent.__members__.items()], False + ) + self.extension_name = "Device Simulator Express" + + def send_telemetry(self, event_name: TelemetryEvent): + if ( + self.__enable_telemetry + and self.telemetry_available() + and not self.telemetry_state[event_name.name] + ): + self.telemetry_client.track_event( + f"{self.extension_name}/{event_name.value}" + ) + self.telemetry_client.flush() + self.telemetry_state[event_name.name] = True + + def telemetry_available(self): + return self.telemetry_client.context.instrumentation_key == "__AIKEY__" + + +telemetry_py = Telemetry() diff --git a/src/common/telemetry_events.py b/src/common/telemetry_events.py new file mode 100644 index 000000000..d150076d0 --- /dev/null +++ b/src/common/telemetry_events.py @@ -0,0 +1,33 @@ +import enum + + +class TelemetryEvent(enum.Enum): + CPX_API_ACCELERATION = "CPX.API.ACCELERATION" + CPX_API_BUTTON_A = "CPX.API.BUTTON.A" + CPX_API_BUTTON_B = "CPX.API.BUTTON.B" + CPX_API_SWITCH = "CPX.API.SWITCH" + CPX_API_TEMPERATURE = "CPX.API.TEMPERATURE" + CPX_API_BRIGHTNESS = "CPX.API.BRIGHTNESS" + CPX_API_LIGHT = "CPX.API.LIGHT" + CPX_API_TOUCH = "CPX.API.TOUCH" + CPX_API_SHAKE = "CPX.API.SHAKE" + CPX_API_TAPPED = "CPX.API.TAPPED" + CPX_API_PLAY_FILE = "CPX.API.PLAY.FILE" + CPX_API_PLAY_TONE = "CPX.API.PLAY.TONE" + CPX_API_START_TONE = "CPX.API.START.TONE" + CPX_API_STOP_TONE = "CPX.API.STOP.TONE" + CPX_API_DETECT_TAPS = "CPX.API.DETECT.TAPS" + CPX_API_ADJUST_THRESHOLD = "CPX.API.ADJUST.THRESHOLD" + CPX_API_RED_LED = "CPX.API.RED.LED" + CPX_API_PIXELS = "CPX.API.PIXELS" + MICROBIT_API_TEMPERATURE = "MICROBIT.API.TEMPERATURE" + MICROBIT_API_ACCELEROMETER = "MICROBIT.API.ACCELEROMETER" + MICROBIT_API_GESTURE = "MICROBIT.API.GESTURE" + MICROBIT_API_DISPLAY_SCROLL = "MICROBIT.API.DISPLAY.SCROLL" + MICROBIT_API_DISPLAY_SHOW = "MICROBIT.API.DISPLAY.SHOW" + MICROBIT_API_DISPLAY_OTHER = "MICROBIT.API.DISPLAY_OTHER" + MICROBIT_API_LIGHT_LEVEL = "MICROBIT.API.LIGHT.LEVEL" + MICROBIT_API_IMAGE_CREATION = "MICROBIT.API.IMAGE.CREATION" + MICROBIT_API_IMAGE_OTHER = "MICROBIT.API.IMAGE.OTHER" + MICROBIT_API_IMAGE_STATIC = "MICROBIT.API.IMAGE.STATIC" + MICROBIT_API_BUTTON = "MICROBIT.API.BUTTON" diff --git a/src/common/test/test_debugger_communication_client.py b/src/common/test/test_debugger_communication_client.py new file mode 100644 index 000000000..0706ad149 --- /dev/null +++ b/src/common/test/test_debugger_communication_client.py @@ -0,0 +1,178 @@ +import pytest +import json # Remove +from unittest import mock +import socketio +import threading + +from adafruit_circuitplayground import express +from common import debugger_communication_client +from common import constants as CONSTANTS +from adafruit_circuitplayground.constants import CPX + + +class TestDebuggerCommunicationClient(object): + @mock.patch("socketio.Client.connect") + def test_init_connection(self, mock_connect): + mock_connect.return_value = None + debugger_communication_client.init_connection() + mock_connect.assert_called_once() + + def test_init_connection1(self): + socketio.Client.connect = mock.Mock() + socketio.Client.connect.return_value = None + debugger_communication_client.init_connection() + socketio.Client.connect.assert_called_once() + + def test_update_state(self): + threading.Event.clear = mock.Mock() + threading.Event.wait = mock.Mock() + socketio.Client.emit = mock.Mock() + socketio.Client.emit.return_value = None + debugger_communication_client.update_state( + {CONSTANTS.ACTIVE_DEVICE_FIELD: CPX, CONSTANTS.STATE_FIELD: {}} + ) + socketio.Client.emit.assert_called_once() + + @mock.patch.dict( + express.cpx._Express__state, + { + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [ + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + ], + "red_led": False, + "switch": False, + "temperature": 0, + "light": 0, + "motion_x": 0, + "motion_y": 0, + "motion_z": 0, + "touch": [False] * 7, + "shake": False, + }, + clear=True, + ) + def test_button_press(self): + data = { + CONSTANTS.ACTIVE_DEVICE_FIELD: CPX, + CONSTANTS.STATE_FIELD: {"button_a": True, "button_b": True, "switch": True}, + } + expected_data = { + "brightness": 1.0, + "button_a": True, + "button_b": True, + "pixels": [ + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + ], + "red_led": False, + "switch": True, + "temperature": 0, + "light": 0, + "motion_x": 0, + "motion_y": 0, + "motion_z": 0, + "touch": [False] * 7, + "shake": False, + } + serialized_data = json.dumps(data) + debugger_communication_client.input_changed(serialized_data) + assert expected_data == express.cpx._Express__state + + @mock.patch.dict( + express.cpx._Express__state, + { + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [ + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + ], + "red_led": False, + "switch": False, + "temperature": 0, + "light": 0, + "motion_x": 0, + "motion_y": 0, + "motion_z": 0, + "touch": [False] * 7, + "shake": False, + }, + clear=True, + ) + def test_input_changed(self): + data = { + CONSTANTS.ACTIVE_DEVICE_FIELD: CPX, + CONSTANTS.STATE_FIELD: { + "temperature": 1, + "light": 2, + "motion_x": 3, + "motion_y": 4, + "motion_z": 5, + }, + } + expected_data = { + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [ + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + (0, 0, 0), + ], + "red_led": False, + "switch": False, + "temperature": 1, + "light": 2, + "motion_x": 3, + "motion_y": 4, + "motion_z": 5, + "touch": [False] * 7, + "shake": False, + } + serialized_data = json.dumps(data) + debugger_communication_client.input_changed(serialized_data) + assert expected_data == express.cpx._Express__state + + @mock.patch("builtins.print") + @mock.patch.dict(express.cpx._Express__state, {}, clear=True) + def test_update_api_state_fail(self, mocked_print): + data = [] + debugger_communication_client.input_changed(data) + # Exception is caught and a print is stated to stderr + mocked_print.assert_called_once() diff --git a/src/common/utils.py b/src/common/utils.py new file mode 100644 index 000000000..a468044f7 --- /dev/null +++ b/src/common/utils.py @@ -0,0 +1,49 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +from . import constants as CONSTANTS +import json +import copy +import time +import sys + +previous_state = {} + + +def update_state_with_device_name(state, device_name): + updated_state = dict(state) + + state_ext = { + "device_name": device_name, + } + updated_state.update(state_ext) + + return updated_state + + +def create_message(state): + message = {"type": "state", "data": json.dumps(state)} + return message + + +def send_to_simulator(state, device_name): + global previous_state + + updated_state = update_state_with_device_name(state, device_name) + message = create_message(updated_state) + + if updated_state != previous_state: + previous_state = copy.deepcopy(updated_state) + print(json.dumps(message) + "\0", end="", file=sys.__stdout__, flush=True) + time.sleep(CONSTANTS.TIME_DELAY) + + +def remove_leading_slashes(string): + string = string.lstrip("\\/") + return string + + +def escape_if_OSX(file_name): + if sys.platform.startswith(CONSTANTS.MAC_OS): + file_name = file_name.replace(" ", "%20") + return file_name diff --git a/src/constants.ts b/src/constants.ts index 0a2db62dc..7c537c122 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -17,18 +17,23 @@ const localize: nls.LocalizeFunc = nls.config({ })(); export const CONFIG = { + CONFIG_ENV_ON_SWITCH: + "deviceSimulatorExpress.configNewEnvironmentUponSwitch", + PYTHON_PATH: "python.pythonPath", + ENABLE_PREVIEW_MODE: "deviceSimulatorExpress.previewMode", SHOW_DEPENDENCY_INSTALL: "deviceSimulatorExpress.showDependencyInstall", SHOW_NEW_FILE_POPUP: "deviceSimulatorExpress.showNewFilePopup", }; export const CONSTANTS = { DEBUG_CONFIGURATION_TYPE: "deviceSimulatorExpress", - DEPENDENCY_CHECKER: { - PIP3: "pip3", - PYTHON: "python", - PYTHON3: "python3.7", + DEVICE_NAME: { + CPX: "CPX", + MICROBIT: "micro:bit", }, ERROR: { + BAD_PYTHON_PATH: + 'Your interpreter is not pointing to a valid Python executable. Please select a different interpreter (CTRL+SHIFT+P and type "python.selectInterpreter") and restart the application', COMPORT_UNKNOWN_ERROR: "Writing to COM port (GetOverlappedResult): Unknown error code 121", CPX_FILE_ERROR: localize( @@ -46,7 +51,8 @@ export const CONSTANTS = { "[ERROR] A debugging session is currently in progress, please stop it before running your code. \n" ), DEPENDENCY_DOWNLOAD_ERROR: - "Package downloads failed. Some functionalities may not work. Try restarting the simulator or review the installation docs.", + "Dependency download could not be completed. Functionality may be limited. Please review the installation docs.", + FAILED_TO_OPEN_SERIAL_PORT: (port: string): string => { return localize( "error.failedToOpenSerialPort", @@ -67,10 +73,18 @@ export const CONSTANTS = { "error.incorrectFileNameForDevicePopup", 'Seems like you have a different file name than what CPX requires, please rename it to "code.py" or "main.py".' ), + INSTALLATION_ERROR: localize( + "error.installationError", + "Installation Error" + ), INVALID_FILE_EXTENSION_DEBUG: localize( "error.invalidFileExtensionDebug", "The file you tried to run isn't a Python file." ), + INVALID_PYTHON_PATH: localize( + "error.invalidPythonPath", + 'We found that your selected Python interpreter version is too low to run the extension. Please upgrade to version 3.7+ or select a different interpreter (CTRL+SHIFT+P and type "python.selectInterpreter") and restart the application.' + ), NO_DEVICE: localize( "error.noDevice", "No plugged in boards detected. Please double check if your board is connected and/or properly formatted" @@ -87,6 +101,10 @@ export const CONSTANTS = { "error.noProgramFoundDebug", "Cannot find a program to debug." ), + NO_PIP: localize( + "error.noPip", + "We found that you don't have Pip installed on your computer, please install it and try again." + ), NO_PYTHON_PATH: localize( "error.noPythonPath", "We found that you don't have Python 3 installed on your computer, please install the latest version, add it to your PATH and try again." @@ -105,12 +123,16 @@ export const CONSTANTS = { }, FILESYSTEM: { OUTPUT_DIRECTORY: "out", - PYTHON_LIBS_DIR: "python_libs", + PYTHON_VENV_DIR: "venv", }, INFO: { + ALREADY_SUCCESSFUL_INSTALL: localize( + "info.successfulInstall", + "Your current configuration is already successfully set up for the Device Simulator Expresss." + ), ARE_YOU_SURE: localize( "info.areYouSure", - "Are you sure you don't want to install the dependencies? The extension can't run without installing it" + "Are you sure you don't want to install the dependencies? The extension can't run without installing them." ), CLOSED_SERIAL_PORT: (port: string) => { return localize( @@ -147,19 +169,23 @@ export const CONSTANTS = { }, FIRST_TIME_WEBVIEW: localize( "info.firstTimeWebview", - 'To reopen the simulator click on the "Open Simulator" button on the upper right corner of the text editor, or select the command "Open Simulator" from command palette.' + 'To reopen the simulator select the command "Open Simulator" from command palette.' ), INCORRECT_FILE_NAME_FOR_SIMULATOR_POPUP: localize( "info.incorrectFileNameForSimulatorPopup", 'We want your code to work on your actual board as well. Make sure you name your file "code.py" or "main.py" to be able to run your code on an actual physical device' ), - INSTALLING_PYTHON_DEPENDENCIES: localize( - "info.installingPythonDependencies", - "The Python packages are currently being installed. You will be prompt a message telling you when the installation is done." + INSTALLING_PYTHON_VENV: localize( + "info.installingPythonVenv", + "A virtual environment is currently being created. The required Python packages will be installed. You will be prompted a message telling you when the installation is done." ), - INSTALL_PYTHON_DEPENDENCIES: localize( + INSTALL_PYTHON_DEPS: localize( "info.installPythonDependencies", - "Do you want us to try and install this extensions dependencies for you?" + "Do you want us to try and install this extension's dependencies on your selected Python interpreter for you?" + ), + INSTALL_PYTHON_VENV: localize( + "info.installPythonVenv", + "Do you want us to try and install this extension's dependencies via virtual environment for you?" ), INVALID_FILE_NAME_DEBUG: localize( "info.invalidFileNameDebug", @@ -189,15 +215,27 @@ export const CONSTANTS = { RUNNING_CODE: localize("info.runningCode", "Running user code"), SUCCESSFUL_INSTALL: localize( "info.successfulInstall", - "Successfully installed Python dependencies." + "Successfully set up the Python environment." ), - THIRD_PARTY_WEBSITE: localize( - "info.thirdPartyWebsite", + THIRD_PARTY_WEBSITE_ADAFRUIT: localize( + "info.thirdPartyWebsiteAdafruit", 'By clicking "Agree and Proceed" you will be redirected to adafruit.com, a third party website not managed by Microsoft. Please note that your activity on adafruit.com is subject to Adafruit\'s privacy policy' ), + THIRD_PARTY_WEBSITE_PIP: localize( + "info.thirdPartyWebsitePip", + 'By clicking "Agree and Proceed" you will be redirected to pip.pypa.io, a third party website not managed by Microsoft. Please note that your activity on pip.pypa.io is subject to PyPA\'s privacy policy' + ), + THIRD_PARTY_WEBSITE_PYTHON: localize( + "info.thirdPartyWebsitePython", + 'By clicking "Agree and Proceed" you will be redirected to python.org, a third party website not managed by Microsoft. Please note that your activity on python.org is subject to Python\'s privacy policy' + ), + UPDATED_TO_EXTENSION_VENV: localize( + "info.updatedToExtensionsVenv", + "Automatically updated interpreter to point to extension's virtual environment." + ), WELCOME_OUTPUT_TAB: localize( "info.welcomeOutputTab", - "Welcome to the Adafruit Simulator output tab!\n\n" + "Welcome to the Device Simulator Express output tab!\n\n" ), }, LABEL: { @@ -207,6 +245,7 @@ export const CONSTANTS = { ), }, LINKS: { + DOWNLOAD_PIP: "https://pip.pypa.io/en/stable/installing/", DOWNLOAD_PYTHON: "https://www.python.org/downloads/", EXAMPLE_CODE: "https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples", @@ -233,6 +272,10 @@ export const CONSTANTS = { ), }, NAME: localize("name", "Device Simulator Express"), + TEMPLATE: { + CPX: "cpx_template.py", + MICROBIT: "microbit_template.py", + }, WARNING: { ACCEPT_AND_RUN: localize( "warning.agreeAndRun", @@ -274,57 +317,72 @@ export enum CONFIG_KEYS { export enum TelemetryEventName { FAILED_TO_OPEN_SIMULATOR = "SIMULATOR.FAILED_TO_OPEN", + // Debugger + CPX_DEBUGGER_INIT_SUCCESS = "CPX.DEBUGGER.INIT.SUCCESS", + CPX_DEBUGGER_INIT_FAIL = "CPX.DEBUGGER.INIT.FAIL", + MICROBIT_DEBUGGER_INIT_SUCCESS = "MICROBIT.DEBUGGER.INIT.SUCCESS", + MICROBIT_DEBUGGER_INIT_FAIL = "MICROBIT.DEBUGGER.INIT.FAIL", + // Extension commands - COMMAND_DEPLOY_DEVICE = "COMMAND.DEPLOY.DEVICE", - COMMAND_NEW_FILE = "COMMAND.NEW.FILE", - COMMAND_OPEN_SIMULATOR = "COMMAND.OPEN.SIMULATOR", COMMAND_RUN_SIMULATOR_BUTTON = "COMMAND.RUN.SIMULATOR_BUTTON", COMMAND_RUN_PALETTE = "COMMAND.RUN.PALETTE", - COMMAND_RUN_EDITOR_ICON = "COMMAND.RUN.EDITOR_ICON", - COMMAND_SERIAL_MONITOR_CHOOSE_PORT = "COMMAND.SERIAL_MONITOR.CHOOSE_PORT", - COMMAND_SERIAL_MONITOR_OPEN = "COMMAND.SERIAL_MONITOR.OPEN", - COMMAND_SERIAL_MONITOR_BAUD_RATE = "COMMAND.SERIAL_MONITOR.BAUD_RATE", - COMMAND_SERIAL_MONITOR_CLOSE = "COMMAND.SERIAL_MONITOR.CLOSE", + COMMAND_INSTALL_EXTENSION_DEPENDENCIES = "COMMAND.INSTALL.EXTENSION.DEPENDENCIES", + + CPX_COMMAND_DEPLOY_DEVICE = "CPX.COMMAND.DEPLOY.DEVICE", + CPX_COMMAND_NEW_FILE = "CPX.COMMAND.NEW.FILE.CPX", + CPX_COMMAND_OPEN_SIMULATOR = "CPX.COMMAND.OPEN.SIMULATOR", + CPX_COMMAND_SERIAL_MONITOR_CHOOSE_PORT = "CPX.COMMAND.SERIAL_MONITOR.CHOOSE_PORT", + CPX_COMMAND_SERIAL_MONITOR_OPEN = "CPX.COMMAND.SERIAL_MONITOR.OPEN", + CPX_COMMAND_SERIAL_MONITOR_BAUD_RATE = "CPX.COMMAND.SERIAL_MONITOR.BAUD_RATE", + CPX_COMMAND_SERIAL_MONITOR_CLOSE = "CPX.COMMAND.SERIAL_MONITOR.CLOSE", + + MICROBIT_COMMAND_NEW_FILE = "MICROBIT.COMMAND.NEW.FILE", + MICROBIT_COMMAND_OPEN_SIMULATOR = "MICROBIT.COMMAND.OPEN.SIMULATOR", // Simulator interaction - SIMULATOR_BUTTON_A = "SIMULATOR.BUTTON.A", - SIMULATOR_BUTTON_B = "SIMULATOR.BUTTON.B", - SIMULATOR_BUTTON_AB = "SIMULATOR.BUTTON.AB", - SIMULATOR_SWITCH = "SIMULATOR.SWITCH", + CPX_SIMULATOR_BUTTON_A = "CPX.SIMULATOR.BUTTON.A", + CPX_SIMULATOR_BUTTON_B = "CPX.SIMULATOR.BUTTON.B", + CPX_SIMULATOR_BUTTON_AB = "CPX.SIMULATOR.BUTTON.AB", + CPX_SIMULATOR_SWITCH = "CPX.SIMULATOR.SWITCH", + + MICROBIT_SIMULATOR_BUTTON_A = "MICROBIT.SIMULATOR.BUTTON.A", + MICROBIT_SIMULATOR_BUTTON_B = "MICROBIT.SIMULATOR.BUTTON.B", + MICROBIT_SIMULATOR_BUTTON_AB = "MICROBIT.SIMULATOR.BUTTON.AB", // Sensors - SIMULATOR_TEMPERATURE_SENSOR = "SIMULATOR.TEMPERATURE", - SIMULATOR_LIGHT_SENSOR = " SIMULATOR.LIGHT", - SIMULATOR_MOTION_SENSOR = "SIMULATOR.MOTION", - SIMULATOR_SHAKE = "SIMULATOR.SHAKE", - SIMULATOR_CAPACITIVE_TOUCH = "SIMULATOR.CAPACITIVE.TOUCH", + CPX_SIMULATOR_TEMPERATURE_SENSOR = "CPX.SIMULATOR.TEMPERATURE", + CPX_SIMULATOR_LIGHT_SENSOR = "CPX.SIMULATOR.LIGHT", + CPX_SIMULATOR_MOTION_SENSOR = "CPX.SIMULATOR.MOTION", + CPX_SIMULATOR_SHAKE = "CPX.SIMULATOR.SHAKE", + CPX_SIMULATOR_CAPACITIVE_TOUCH = "CPX.SIMULATOR.CAPACITIVE.TOUCH", + + MICROBIT_SIMULATOR_TEMPERATURE_SENSOR = "MICROBIT.SIMULATOR.TEMPERATURE", + MICROBIT_SIMULATOR_LIGHT_SENSOR = "MICROBIT.SIMULATOR.LIGHT", + MICROBIT_SIMULATOR_MOTION_SENSOR = "MICROBIT.SIMULATOR.MOTION", // Pop-up dialog - CLICK_DIALOG_DONT_SHOW = "CLICK.DIALOG.DONT.SHOW", - CLICK_DIALOG_EXAMPLE_CODE = "CLICK.DIALOG.EXAMPLE.CODE", - CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE = "CLICK.DIALOG.HELP.DEPLOY.TO.DEVICE", - CLICK_DIALOG_TUTORIALS = "CLICK.DIALOG.TUTORIALS", + CPX_CLICK_DIALOG_DONT_SHOW = "CPX.CLICK.DIALOG.DONT.SHOW", + CPX_CLICK_DIALOG_EXAMPLE_CODE = "CPX.CLICK.DIALOG.EXAMPLE.CODE", + CPX_CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE = "CPX.CLICK.DIALOG.HELP.DEPLOY.TO.DEVICE", + CPX_CLICK_DIALOG_TUTORIALS = "CPX.CLICK.DIALOG.TUTORIALS", - ERROR_PYTHON_DEVICE_PROCESS = "ERROR.PYTHON.DEVICE.PROCESS", ERROR_PYTHON_PROCESS = "ERROR.PYTHON.PROCESS", - ERROR_COMMAND_NEW_FILE = "ERROR.COMMAND.NEW.FILE", - ERROR_DEPLOY_WITHOUT_DEVICE = "ERROR.DEPLOY.WITHOUT.DEVICE", + CPX_ERROR_COMMAND_NEW_FILE = "CPX.ERROR.COMMAND.NEW.FILE", + CPX_ERROR_DEPLOY_WITHOUT_DEVICE = "CPX.ERROR.DEPLOY.WITHOUT.DEVICE", + CPX_ERROR_PYTHON_DEVICE_PROCESS = "CPX.ERROR.PYTHON.DEVICE.PROCESS", + CPX_SUCCESS_COMMAND_DEPLOY_DEVICE = "CPX.SUCCESS.COMMAND.DEPLOY.DEVICE", - SUCCESS_COMMAND_DEPLOY_DEVICE = "SUCCESS.COMMAND.DEPLOY.DEVICE", + MICROBIT_ERROR_COMMAND_NEW_FILE = "MICROBIT.ERROR.COMMAND.NEW.FILE", // Performance - PERFORMANCE_DEPLOY_DEVICE = "PERFORMANCE.DEPLOY.DEVICE", - PERFORMANCE_NEW_FILE = "PERFORMANCE.NEW.FILE", - PERFORMANCE_OPEN_SIMULATOR = "PERFORMANCE.OPEN.SIMULATOR", -} + CPX_PERFORMANCE_DEPLOY_DEVICE = "CPX.PERFORMANCE.DEPLOY.DEVICE", + CPX_PERFORMANCE_NEW_FILE = "CPX.PERFORMANCE.NEW.FILE", + CPX_PERFORMANCE_OPEN_SIMULATOR = "CPX.PERFORMANCE.OPEN.SIMULATOR", -export enum WebviewMessages { - BUTTON_PRESS = "button-press", - PLAY_SIMULATOR = "play-simulator", - SENSOR_CHANGED = "sensor-changed", - REFRESH_SIMULATOR = "refresh-simulator", - SLIDER_TELEMETRY = "slider-telemetry", + MICROBIT_PERFORMANCE_NEW_FILE = "MICROBIT.PERFORMANCE.NEW.FILE", + MICROBIT_PERFORMANCE_OPEN_SIMULATOR = "MICROBIT.PERFORMANCE.OPEN.SIMULATOR", } +export const DEFAULT_DEVICE = CONSTANTS.DEVICE_NAME.CPX; // tslint:disable-next-line: no-namespace export namespace DialogResponses { @@ -367,6 +425,12 @@ export namespace DialogResponses { export const MESSAGE_UNDERSTOOD: MessageItem = { title: localize("dialogResponses.messageUnderstood", "Got It"), }; + export const INSTALL_PIP: MessageItem = { + title: localize( + "dialogResponses.installPip", + "Install from Pip's webpage" + ), + }; export const INSTALL_PYTHON: MessageItem = { title: localize( "dialogResponses.installPython", @@ -397,4 +461,21 @@ export const STATUS_BAR_PRIORITY = { BAUD_RATE: 40, }; +export const VERSIONS = { + MIN_PY_VERSION: "3.7.0", +}; + +export const HELPER_FILES = { + CHECK_IF_VENV_PY: "check_if_venv.py", + CHECK_PYTHON_DEPENDENCIES: "check_python_dependencies.py", + DEVICE_PY: "device.py", + PROCESS_USER_CODE_PY: "process_user_code.py", + PYTHON_EXE: "python.exe", + PYTHON: "python", +}; + +export const GLOBAL_ENV_VARS = { + PYTHON: "python", +}; + export default CONSTANTS; diff --git a/src/debug_user_code.py b/src/debug_user_code.py index 8d5b57873..c4b3dd2c5 100644 --- a/src/debug_user_code.py +++ b/src/debug_user_code.py @@ -6,7 +6,10 @@ import traceback from pathlib import Path import python_constants as CONSTANTS +import check_python_dependencies +# will propagate errors if dependencies aren't sufficient +check_python_dependencies.check_for_dependencies() # Insert absolute path to Adafruit library into sys.path abs_path_to_parent_dir = os.path.dirname(os.path.abspath(__file__)) @@ -15,12 +18,12 @@ # Insert absolute path to python libraries into sys.path abs_path_to_parent_dir = os.path.dirname(os.path.abspath(__file__)) -abs_path_to_lib = os.path.join(abs_path_to_parent_dir, CONSTANTS.PYTHON_LIBS_DIR) sys.path.insert(0, abs_path_to_lib) # This import must happen after the sys.path is modified from adafruit_circuitplayground.express import cpx -from adafruit_circuitplayground import debugger_communication_client +from microbit.__model.microbit_model import __mb as mb +from common import debugger_communication_client ## Execute User Code ## @@ -45,6 +48,7 @@ cpx._Express__abs_path_to_code_file = abs_path_to_code_file cpx._Express__debug_mode = True cpx.pixels._Pixel__set_debug_mode(True) +mb._MicrobitModel__set_debug_mode(True) # Execute the user's code file with open(abs_path_to_code_file) as user_code_file: diff --git a/src/debugger/debugAdapter.ts b/src/debugger/debugAdapter.ts new file mode 100644 index 000000000..59a78482e --- /dev/null +++ b/src/debugger/debugAdapter.ts @@ -0,0 +1,49 @@ +import { DebugAdapterTracker, DebugConsole, DebugSession } from "vscode"; +import { DebuggerCommunicationService } from "../service/debuggerCommunicationService"; +import { MessagingService } from "../service/messagingService"; +import { DEBUG_COMMANDS } from "../view/constants"; + +export class DebugAdapter implements DebugAdapterTracker { + private readonly console: DebugConsole | undefined; + private readonly messagingService: MessagingService; + private debugCommunicationService: DebuggerCommunicationService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService, + debugCommunicationService: DebuggerCommunicationService + ) { + this.console = debugSession.configuration.console; + this.messagingService = messagingService; + this.debugCommunicationService = debugCommunicationService; + } + onWillStartSession() { + // To Implement + } + onWillReceiveMessage(message: any): void { + if (message.command) { + // Only send pertinent debug messages + switch (message.command) { + case DEBUG_COMMANDS.CONTINUE: + this.messagingService.sendStartMessage(); + break; + case DEBUG_COMMANDS.STACK_TRACE: + this.messagingService.sendPauseMessage(); + break; + case DEBUG_COMMANDS.DISCONNECT: + // Triggered on stop event for debugger + if (!message.arguments.restart) { + this.debugCommunicationService.handleStopEvent(); + } + break; + } + } + } + // A debugger error should unlock the webview + onError() { + this.messagingService.sendStartMessage(); + } + // Device is always running when exiting debugging mode + onExit() { + this.messagingService.sendStartMessage(); + } +} diff --git a/src/debugger/debugAdapterFactory.ts b/src/debugger/debugAdapterFactory.ts new file mode 100644 index 000000000..5b0e2b401 --- /dev/null +++ b/src/debugger/debugAdapterFactory.ts @@ -0,0 +1,33 @@ +import { + DebugAdapterTracker, + DebugAdapterTrackerFactory, + DebugSession, + ProviderResult, +} from "vscode"; +import { DebuggerCommunicationService } from "../service/debuggerCommunicationService"; +import { MessagingService } from "../service/messagingService"; +import { DebugAdapter } from "./debugAdapter"; + +export class DebugAdapterFactory implements DebugAdapterTrackerFactory { + private debugSession: DebugSession; + private messagingService: MessagingService; + private debugCommunicationService: DebuggerCommunicationService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService, + debugCommunicationService: DebuggerCommunicationService + ) { + this.debugSession = debugSession; + this.messagingService = messagingService; + this.debugCommunicationService = debugCommunicationService; + } + public createDebugAdapterTracker( + session: DebugSession + ): ProviderResult { + return new DebugAdapter( + session, + this.messagingService, + this.debugCommunicationService + ); + } +} diff --git a/src/debuggerCommunicationServer.ts b/src/debuggerCommunicationServer.ts index 76eb02f42..86a4aeef2 100644 --- a/src/debuggerCommunicationServer.ts +++ b/src/debuggerCommunicationServer.ts @@ -6,15 +6,32 @@ import * as socketio from "socket.io"; import { WebviewPanel } from "vscode"; import { SERVER_INFO } from "./constants"; +export const DEBUGGER_MESSAGES = { + EMITTER: { + INPUT_CHANGED: "input_changed", + RECEIVED_STATE: "received_state", + DISCONNECT: "process_disconnect", + }, + LISTENER: { + UPDATE_STATE: "updateState", + RECEIVED_STATE: "receivedState", + DISCONNECT: "disconnect", + }, +}; + export class DebuggerCommunicationServer { private port: number; private serverHttp: http.Server; private serverIo: socketio.Server; private simulatorWebview: WebviewPanel | undefined; + private currentActiveDevice; + private isPendingResponse = false; + private pendingCallbacks: Function[] = []; constructor( webviewPanel: WebviewPanel | undefined, - port = SERVER_INFO.DEFAULT_SERVER_PORT + port = SERVER_INFO.DEFAULT_SERVER_PORT, + currentActiveDevice: string ) { this.port = port; this.serverHttp = new http.Server(); @@ -24,28 +41,41 @@ export class DebuggerCommunicationServer { this.simulatorWebview = webviewPanel; this.initEventsHandlers(); console.info(`Server running on port ${this.port}`); + + this.currentActiveDevice = currentActiveDevice; } + // send the message to start closing the connection public closeConnection(): void { - this.serverIo.close(); - this.serverHttp.close(); - console.info("Closing the server"); + this.sendDisconnectEvent(); } public setWebview(webviewPanel: WebviewPanel | undefined) { this.simulatorWebview = webviewPanel; } - - // Emit Buttons Inputs Events - public emitButtonPress(newState: string): void { - console.log(`Emit Button Press: ${newState} \n`); - this.serverIo.emit("button_press", newState); + // Events are pushed when the previous processed event is over + public emitInputChanged(newState: string): void { + if (this.isPendingResponse) { + this.pendingCallbacks.push(() => { + this.serverIo.emit( + DEBUGGER_MESSAGES.EMITTER.INPUT_CHANGED, + newState + ); + }); + } else { + this.serverIo.emit( + DEBUGGER_MESSAGES.EMITTER.INPUT_CHANGED, + newState + ); + this.isPendingResponse = true; + } } - - // Emit Sensors Inputs Events - public emitSensorChanged(newState: string): void { - console.log(`Emit Sensor Changed: ${newState} \n`); - this.serverIo.emit("sensor_changed", newState); + public disconnectFromPort() { + this.serverIo.close(); + this.serverHttp.close(); + } + private sendDisconnectEvent() { + this.serverIo.emit(DEBUGGER_MESSAGES.EMITTER.DISCONNECT, {}); } private initHttpServer(): void { @@ -57,14 +87,25 @@ export class DebuggerCommunicationServer { private initEventsHandlers(): void { this.serverIo.on("connection", (socket: any) => { - console.log("Connection received"); - - socket.on("updateState", (data: any) => { + socket.on(DEBUGGER_MESSAGES.LISTENER.UPDATE_STATE, (data: any) => { this.handleState(data); + this.serverIo.emit( + DEBUGGER_MESSAGES.EMITTER.RECEIVED_STATE, + {} + ); + }); + socket.on(DEBUGGER_MESSAGES.LISTENER.RECEIVED_STATE, () => { + if (this.pendingCallbacks.length > 0) { + const currentCall = this.pendingCallbacks.shift(); + currentCall(); + this.isPendingResponse = true; + } else { + this.isPendingResponse = false; + } }); - socket.on("disconnect", () => { - console.log("Socket disconnected"); + socket.on(DEBUGGER_MESSAGES.LISTENER.DISCONNECT, () => { + this.serverIo.emit(DEBUGGER_MESSAGES.EMITTER.DISCONNECT, {}); if (this.simulatorWebview) { this.simulatorWebview.webview.postMessage({ command: "reset-state", @@ -81,6 +122,7 @@ export class DebuggerCommunicationServer { console.log(`State recieved: ${messageToWebview.data}`); if (this.simulatorWebview) { this.simulatorWebview.webview.postMessage({ + active_device: this.currentActiveDevice, command: "set-state", state: JSON.parse(messageToWebview.data), }); diff --git a/src/extension.ts b/src/extension.ts index 888015803..c14532a0a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,40 +4,56 @@ import * as cp from "child_process"; import * as fs from "fs"; import * as open from "open"; +import * as os from "os"; import * as path from "path"; import * as vscode from "vscode"; import { CONFIG, CONSTANTS, CPX_CONFIG_FILE, + DEFAULT_DEVICE, DialogResponses, + GLOBAL_ENV_VARS, + HELPER_FILES, SERVER_INFO, TelemetryEventName, - WebviewMessages, } from "./constants"; import { CPXWorkspace } from "./cpxWorkspace"; +import { DebugAdapterFactory } from "./debugger/debugAdapterFactory"; import { DebuggerCommunicationServer } from "./debuggerCommunicationServer"; import * as utils from "./extension_utils/utils"; import { SerialMonitor } from "./serialMonitor"; +import { DebuggerCommunicationService } from "./service/debuggerCommunicationService"; +import { MessagingService } from "./service/messagingService"; import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurationProvider"; import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; +import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants"; +import { PopupService } from "./service/PopupService"; +import getPackageInfo from "./telemetry/getPackageInfo"; +import { registerDefaultFontFaces } from "office-ui-fabric-react"; let currentFileAbsPath: string = ""; let currentTextDocument: vscode.TextDocument; let telemetryAI: TelemetryAI; -let pythonExecutableName: string = "python"; +let pythonExecutablePath: string = GLOBAL_ENV_VARS.PYTHON; let configFileCreated: boolean = false; let inDebugMode: boolean = false; -let debuggerCommunicationHandler: DebuggerCommunicationServer; // Notification booleans let firstTimeClosed: boolean = true; let shouldShowInvalidFileNamePopup: boolean = true; let shouldShowRunCodePopup: boolean = true; +const messagingService = new MessagingService(); +const debuggerCommunicationService = new DebuggerCommunicationService(); + +let currentActiveDevice: string = DEFAULT_DEVICE; + export let outChannel: vscode.OutputChannel | undefined; function loadScript(context: vscode.ExtensionContext, scriptPath: string) { - return ``; } @@ -50,11 +66,23 @@ const setPathAndSendMessage = ( if (currentPanel) { currentPanel.webview.postMessage({ command: "current-file", - state: { running_file: newFilePath }, + active_device: currentActiveDevice, + + state: { + running_file: newFilePath, + }, }); } }; +const sendCurrentDeviceMessage = (currentPanel: vscode.WebviewPanel) => { + if (currentPanel) { + currentPanel.webview.postMessage({ + command: VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE, + active_device: currentActiveDevice, + }); + } +}; // Extension activation export async function activate(context: vscode.ExtensionContext) { console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED); @@ -72,11 +100,8 @@ export async function activate(context: vscode.ExtensionContext) { // doesn't trigger lint errors updatePylintArgs(context); - pythonExecutableName = await utils.setPythonExectuableName(); - - await utils.checkPythonDependencies(context, pythonExecutableName); + pythonExecutablePath = await utils.setupEnv(context); - // Generate cpx.json try { utils.generateCPXConfig(); configFileCreated = true; @@ -85,7 +110,7 @@ export async function activate(context: vscode.ExtensionContext) { configFileCreated = false; } - if (pythonExecutableName === "") { + if (pythonExecutablePath === "") { return; } @@ -100,8 +125,21 @@ export async function activate(context: vscode.ExtensionContext) { } ); + const currVersionReleaseName = + "release_note_" + getPackageInfo(context).extensionVersion; + const viewedReleaseNote = context.globalState.get( + currVersionReleaseName, + false + ); + + if (!viewedReleaseNote) { + PopupService.openReleaseNote(); + context.globalState.update(currVersionReleaseName, true); + } + const openWebview = () => { if (currentPanel) { + messagingService.setWebview(currentPanel.webview); currentPanel.reveal(vscode.ViewColumn.Beside); } else { currentPanel = vscode.window.createWebviewPanel( @@ -123,6 +161,7 @@ export async function activate(context: vscode.ExtensionContext) { ); currentPanel.webview.html = getWebviewContent(context); + messagingService.setWebview(currentPanel.webview); if (messageListener !== undefined) { messageListener.dispose(); @@ -146,26 +185,29 @@ export async function activate(context: vscode.ExtensionContext) { // Handle messages from webview messageListener = currentPanel.webview.onDidReceiveMessage( message => { - const messageJson = JSON.stringify(message.text); + const messageJson = JSON.stringify({ + active_device: currentActiveDevice, + state: message.text, + }); switch (message.command) { - case WebviewMessages.BUTTON_PRESS: + case WEBVIEW_MESSAGES.BUTTON_PRESS: // Send input to the Python process handleButtonPressTelemetry(message.text); console.log(`About to write ${messageJson} \n`); if ( inDebugMode && - debuggerCommunicationHandler + debuggerCommunicationService.getCurrentDebuggerServer() ) { - debuggerCommunicationHandler.emitButtonPress( - messageJson - ); + debuggerCommunicationService + .getCurrentDebuggerServer() + .emitInputChanged(messageJson); } else if (childProcess) { childProcess.stdin.write( messageJson + "\n" ); } break; - case WebviewMessages.PLAY_SIMULATOR: + case WEBVIEW_MESSAGES.TOGGLE_PLAY_STOP: console.log(`Play button ${messageJson} \n`); if (message.text.state as boolean) { setPathAndSendMessage( @@ -187,30 +229,42 @@ export async function activate(context: vscode.ExtensionContext) { } else { killProcessIfRunning(); } + + if (childProcess) { + childProcess.stdin.write( + messageJson + "\n" + ); + } + break; - case WebviewMessages.SENSOR_CHANGED: - checkForTelemetry(message.text); + + case WEBVIEW_MESSAGES.SENSOR_CHANGED: + handleGestureTelemetry(message.text); console.log(`Sensor changed ${messageJson} \n`); if ( inDebugMode && - debuggerCommunicationHandler + debuggerCommunicationService.getCurrentDebuggerServer() ) { - debuggerCommunicationHandler.emitSensorChanged( - messageJson - ); + debuggerCommunicationService + .getCurrentDebuggerServer() + .emitInputChanged(messageJson); } else if (childProcess) { childProcess.stdin.write( messageJson + "\n" ); } break; - case WebviewMessages.REFRESH_SIMULATOR: + case WEBVIEW_MESSAGES.REFRESH_SIMULATOR: console.log("Refresh button"); runSimulatorCommand(); break; - case WebviewMessages.SLIDER_TELEMETRY: + case WEBVIEW_MESSAGES.SLIDER_TELEMETRY: handleSensorTelemetry(message.text); break; + case WEBVIEW_MESSAGES.SWITCH_DEVICE: + switchDevice(message.text.active_device); + killProcessIfRunning(); + break; default: vscode.window.showInformationMessage( CONSTANTS.ERROR.UNEXPECTED_MESSAGE @@ -232,8 +286,12 @@ export async function activate(context: vscode.ExtensionContext) { currentPanel.onDidDispose( () => { currentPanel = undefined; - if (debuggerCommunicationHandler) { - debuggerCommunicationHandler.setWebview(undefined); + if ( + debuggerCommunicationService.getCurrentDebuggerServer() + ) { + debuggerCommunicationService + .getCurrentDebuggerServer() + .setWebview(undefined); } killProcessIfRunning(); if (firstTimeClosed) { @@ -247,31 +305,66 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions ); } + sendCurrentDeviceMessage(currentPanel); + }; + + const openCPXWebview = () => { + switchDevice(CONSTANTS.DEVICE_NAME.CPX); + openWebview(); + }; + + const openMicrobitWebview = () => { + switchDevice(CONSTANTS.DEVICE_NAME.MICROBIT); + openWebview(); }; // Open Simulator on the webview - const openSimulator: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.openSimulator", + const cpxOpenSimulator: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.openSimulator", + () => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_COMMAND_OPEN_SIMULATOR + ); + telemetryAI.runWithLatencyMeasure( + openCPXWebview, + TelemetryEventName.CPX_PERFORMANCE_OPEN_SIMULATOR + ); + } + ); + + const microbitOpenSimulator: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.microbit.openSimulator", () => { telemetryAI.trackFeatureUsage( - TelemetryEventName.COMMAND_OPEN_SIMULATOR + TelemetryEventName.MICROBIT_COMMAND_OPEN_SIMULATOR ); telemetryAI.runWithLatencyMeasure( - openWebview, - TelemetryEventName.PERFORMANCE_OPEN_SIMULATOR + openMicrobitWebview, + TelemetryEventName.MICROBIT_PERFORMANCE_OPEN_SIMULATOR ); } ); - const openTemplateFile = () => { - const fileName = "template.py"; - const filePath = __dirname + path.sep + fileName; + const openCPXTemplateFile = () => { + switchDevice(CONSTANTS.DEVICE_NAME.CPX); + openTemplateFile(CONSTANTS.TEMPLATE.CPX); + }; + + const openMicrobitTemplateFile = () => { + switchDevice(CONSTANTS.DEVICE_NAME.MICROBIT); + openTemplateFile(CONSTANTS.TEMPLATE.MICROBIT); + }; + + const openTemplateFile = (template: string) => { + const fileName = template; + const filePath = + __dirname + path.sep + "templates" + path.sep + fileName; const file = fs.readFileSync(filePath, "utf8"); const showNewFilePopup: boolean = vscode.workspace .getConfiguration() .get(CONFIG.SHOW_NEW_FILE_POPUP); - if (showNewFilePopup) { + if (showNewFilePopup && template === CONSTANTS.TEMPLATE.CPX) { vscode.window .showInformationMessage( CONSTANTS.INFO.NEW_FILE, @@ -285,21 +378,24 @@ export async function activate(context: vscode.ExtensionContext) { .getConfiguration() .update(CONFIG.SHOW_NEW_FILE_POPUP, false); telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_DONT_SHOW + TelemetryEventName.CPX_CLICK_DIALOG_DONT_SHOW ); } else if (selection === DialogResponses.EXAMPLE_CODE) { open(CONSTANTS.LINKS.EXAMPLE_CODE); telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_EXAMPLE_CODE + TelemetryEventName.CPX_CLICK_DIALOG_EXAMPLE_CODE ); } else if (selection === DialogResponses.TUTORIALS) { const okAction = () => { open(CONSTANTS.LINKS.TUTORIALS); telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_TUTORIALS + TelemetryEventName.CPX_CLICK_DIALOG_TUTORIALS ); }; - utils.showPrivacyModal(okAction); + utils.showPrivacyModal( + okAction, + CONSTANTS.INFO.THIRD_PARTY_WEBSITE_ADAFRUIT + ); } }); } @@ -314,20 +410,43 @@ export async function activate(context: vscode.ExtensionContext) { }), // tslint:disable-next-line: no-unused-expression (error: any) => { - telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_COMMAND_NEW_FILE - ); + handleNewFileErrorTelemetry(); console.error(`Failed to open a new text document: ${error}`); }; }; - const newFile: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.newFile", + const cpxNewFile: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.newFile", + () => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_COMMAND_NEW_FILE + ); + telemetryAI.runWithLatencyMeasure( + openCPXTemplateFile, + TelemetryEventName.CPX_PERFORMANCE_NEW_FILE + ); + } + ); + + const microbitNewFile: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.microbit.newFile", () => { - telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_NEW_FILE); + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_COMMAND_NEW_FILE + ); telemetryAI.runWithLatencyMeasure( - openTemplateFile, - TelemetryEventName.PERFORMANCE_NEW_FILE + openMicrobitTemplateFile, + TelemetryEventName.MICROBIT_PERFORMANCE_NEW_FILE + ); + } + ); + + const installDependencies: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.common.installDependencies", + async () => { + pythonExecutablePath = await utils.setupEnv(context, true); + telemetryAI.trackFeatureUsage( + TelemetryEventName.COMMAND_INSTALL_EXTENSION_DEPENDENCIES ); } ); @@ -336,7 +455,10 @@ export async function activate(context: vscode.ExtensionContext) { if (childProcess !== undefined) { if (currentPanel) { console.info("Sending clearing state command"); - currentPanel.webview.postMessage({ command: "reset-state" }); + currentPanel.webview.postMessage({ + command: "reset-state", + active_device: currentActiveDevice, + }); } // TODO: We need to check the process was correctly killed childProcess.kill(); @@ -436,20 +558,23 @@ export async function activate(context: vscode.ExtensionContext) { if (selection === DialogResponses.DONT_SHOW) { shouldShowInvalidFileNamePopup = false; telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_DONT_SHOW + TelemetryEventName.CPX_CLICK_DIALOG_DONT_SHOW ); } }); } // Activate the run webview button - currentPanel.webview.postMessage({ command: "activate-play" }); + currentPanel.webview.postMessage({ + command: "activate-play", + active_device: currentActiveDevice, + }); - childProcess = cp.spawn(pythonExecutableName, [ + childProcess = cp.spawn(pythonExecutablePath, [ utils.getPathToScript( context, CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, - "process_user_code.py" + HELPER_FILES.PROCESS_USER_CODE_PY ), currentFileAbsPath, JSON.stringify({ enable_telemetry: utils.getTelemetryState() }), @@ -480,12 +605,19 @@ export async function activate(context: vscode.ExtensionContext) { console.log( `Process state output = ${messageToWebview.data}` ); - currentPanel.webview.postMessage({ - command: "set-state", - state: JSON.parse( - messageToWebview.data - ), - }); + const messageData = JSON.parse( + messageToWebview.data + ); + if ( + messageData.device_name === + currentActiveDevice + ) { + currentPanel.webview.postMessage({ + active_device: currentActiveDevice, + command: "set-state", + state: messageData, + }); + } break; case "print": @@ -530,6 +662,7 @@ export async function activate(context: vscode.ExtensionContext) { if (currentPanel) { console.log("Sending clearing state command"); currentPanel.webview.postMessage({ + active_device: currentActiveDevice, command: "reset-state", }); } @@ -542,19 +675,9 @@ export async function activate(context: vscode.ExtensionContext) { } }; - const runSimulatorEditorButton: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.runSimulatorEditorButton", - () => { - telemetryAI.trackFeatureUsage( - TelemetryEventName.COMMAND_RUN_EDITOR_ICON - ); - runSimulatorCommand(); - } - ); - // Send message to the webview const runSimulator: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.runSimulator", + "deviceSimulatorExpress.common.runSimulator", () => { telemetryAI.trackFeatureUsage( TelemetryEventName.COMMAND_RUN_PALETTE @@ -563,7 +686,7 @@ export async function activate(context: vscode.ExtensionContext) { } ); - const deployCodeToDevice = async () => { + const cpxDeployCodeToDevice = async () => { console.info("Sending code to device"); utils.logToOutputChannel( @@ -606,11 +729,11 @@ export async function activate(context: vscode.ExtensionContext) { CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath) ); - const deviceProcess = cp.spawn(pythonExecutableName, [ + const deviceProcess = cp.spawn(pythonExecutablePath, [ utils.getPathToScript( context, CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, - "device.py" + HELPER_FILES.DEVICE_PY ), currentFileAbsPath, ]); @@ -628,7 +751,7 @@ export async function activate(context: vscode.ExtensionContext) { switch (messageToWebview.type) { case "complete": telemetryAI.trackFeatureUsage( - TelemetryEventName.SUCCESS_COMMAND_DEPLOY_DEVICE + TelemetryEventName.CPX_SUCCESS_COMMAND_DEPLOY_DEVICE ); utils.logToOutputChannel( outChannel, @@ -638,7 +761,7 @@ export async function activate(context: vscode.ExtensionContext) { case "no-device": telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_DEPLOY_WITHOUT_DEVICE + TelemetryEventName.CPX_ERROR_DEPLOY_WITHOUT_DEVICE ); vscode.window .showErrorMessage( @@ -657,10 +780,14 @@ export async function activate(context: vscode.ExtensionContext) { const okAction = () => { open(CONSTANTS.LINKS.HELP); telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE + TelemetryEventName.CPX_CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE ); }; - utils.showPrivacyModal(okAction); + utils.showPrivacyModal( + okAction, + CONSTANTS.INFO + .THIRD_PARTY_WEBSITE_ADAFRUIT + ); } } ); @@ -682,7 +809,7 @@ export async function activate(context: vscode.ExtensionContext) { // Std error output deviceProcess.stderr.on("data", data => { telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS, + TelemetryEventName.CPX_ERROR_PYTHON_DEVICE_PROCESS, { error: `${data}` } ); console.error( @@ -702,15 +829,15 @@ export async function activate(context: vscode.ExtensionContext) { } }; - const runDevice: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.runDevice", + const cpxDeployToDevice: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.deployToDevice", () => { telemetryAI.trackFeatureUsage( - TelemetryEventName.COMMAND_DEPLOY_DEVICE + TelemetryEventName.CPX_COMMAND_DEPLOY_DEVICE ); telemetryAI.runWithLatencyMeasure( - deployCodeToDevice, - TelemetryEventName.PERFORMANCE_DEPLOY_DEVICE + cpxDeployCodeToDevice, + TelemetryEventName.CPX_PERFORMANCE_DEPLOY_DEVICE ); } ); @@ -721,13 +848,13 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(serialMonitor); } - const selectSerialPort: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.selectSerialPort", + const cpxSelectSerialPort: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.selectSerialPort", () => { if (serialMonitor) { telemetryAI.runWithLatencyMeasure(() => { serialMonitor.selectSerialPort(null, null); - }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CHOOSE_PORT); + }, TelemetryEventName.CPX_COMMAND_SERIAL_MONITOR_CHOOSE_PORT); } else { vscode.window.showErrorMessage( CONSTANTS.ERROR.NO_FOLDER_OPENED @@ -737,13 +864,13 @@ export async function activate(context: vscode.ExtensionContext) { } ); - const openSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.openSerialMonitor", + const cpxOpenSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.openSerialMonitor", () => { if (serialMonitor) { telemetryAI.runWithLatencyMeasure( serialMonitor.openSerialMonitor.bind(serialMonitor), - TelemetryEventName.COMMAND_SERIAL_MONITOR_OPEN + TelemetryEventName.CPX_COMMAND_SERIAL_MONITOR_OPEN ); } else { vscode.window.showErrorMessage( @@ -754,13 +881,13 @@ export async function activate(context: vscode.ExtensionContext) { } ); - const changeBaudRate: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.changeBaudRate", + const cpxChangeBaudRate: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.changeBaudRate", () => { if (serialMonitor) { telemetryAI.runWithLatencyMeasure( serialMonitor.changeBaudRate.bind(serialMonitor), - TelemetryEventName.COMMAND_SERIAL_MONITOR_BAUD_RATE + TelemetryEventName.CPX_COMMAND_SERIAL_MONITOR_BAUD_RATE ); } else { vscode.window.showErrorMessage( @@ -771,13 +898,29 @@ export async function activate(context: vscode.ExtensionContext) { } ); - const closeSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.closeSerialMonitor", + const cpxCloseSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.cpx.closeSerialMonitor", (port, showWarning = true) => { if (serialMonitor) { telemetryAI.runWithLatencyMeasure(() => { serialMonitor.closeSerialMonitor(port, showWarning); - }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CLOSE); + }, TelemetryEventName.CPX_COMMAND_SERIAL_MONITOR_CLOSE); + } else { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FOLDER_OPENED + ); + console.info("Serial monitor is not defined."); + } + } + ); + + const showReleaseNote = vscode.commands.registerCommand( + "deviceSimulatorExpress.", + (port, showWarning = true) => { + if (serialMonitor) { + telemetryAI.runWithLatencyMeasure(() => { + serialMonitor.closeSerialMonitor(port, showWarning); + }, TelemetryEventName.CPX_COMMAND_SERIAL_MONITOR_CLOSE); } else { vscode.window.showErrorMessage( CONSTANTS.ERROR.NO_FOLDER_OPENED @@ -809,29 +952,45 @@ export async function activate(context: vscode.ExtensionContext) { utils.getPathToScript(context, "out/", "debug_user_code.py") ); + const debugAdapterFactory = new DebugAdapterFactory( + vscode.debug.activeDebugSession, + messagingService, + debuggerCommunicationService + ); + vscode.debug.registerDebugAdapterTrackerFactory( + "python", + debugAdapterFactory + ); // On Debug Session Start: Init comunication const debugSessionsStarted = vscode.debug.onDidStartDebugSession(() => { if (simulatorDebugConfiguration.deviceSimulatorExpressDebug) { // Reinitialize process killProcessIfRunning(); - console.log("Debug Started"); inDebugMode = true; try { // Shut down existing server on debug restart - if (debuggerCommunicationHandler) { - debuggerCommunicationHandler.closeConnection(); - debuggerCommunicationHandler = undefined; + if (debuggerCommunicationService.getCurrentDebuggerServer()) { + debuggerCommunicationService.resetCurrentDebuggerServer(); } - debuggerCommunicationHandler = new DebuggerCommunicationServer( - currentPanel, - utils.getServerPortConfig() + debuggerCommunicationService.setCurrentDebuggerServer( + new DebuggerCommunicationServer( + currentPanel, + utils.getServerPortConfig(), + currentActiveDevice + ) ); + + handleDebuggerTelemetry(); + openWebview(); if (currentPanel) { - debuggerCommunicationHandler.setWebview(currentPanel); + debuggerCommunicationService + .getCurrentDebuggerServer() + .setWebview(currentPanel); currentPanel.webview.postMessage({ + currentActiveDevice, command: "activate-play", }); } @@ -840,6 +999,9 @@ export async function activate(context: vscode.ExtensionContext) { console.error( `Error trying to init the server on port ${utils.getServerPortConfig()}` ); + + handleDebuggerFailTelemetry(); + vscode.window.showErrorMessage( CONSTANTS.ERROR.DEBUGGER_SERVER_INIT_FAILED( utils.getServerPortConfig() @@ -853,35 +1015,47 @@ export async function activate(context: vscode.ExtensionContext) { // On Debug Session Stop: Stop communiation const debugSessionStopped = vscode.debug.onDidTerminateDebugSession(() => { if (simulatorDebugConfiguration.deviceSimulatorExpressDebug) { - console.log("Debug Stopped"); inDebugMode = false; simulatorDebugConfiguration.deviceSimulatorExpressDebug = false; - if (debuggerCommunicationHandler) { - debuggerCommunicationHandler.closeConnection(); - debuggerCommunicationHandler = undefined; + if (debuggerCommunicationService.getCurrentDebuggerServer()) { + debuggerCommunicationService.resetCurrentDebuggerServer(); } if (currentPanel) { - currentPanel.webview.postMessage({ command: "reset-state" }); + currentPanel.webview.postMessage({ + command: "reset-state", + active_device: currentActiveDevice, + }); } } }); + const configsChanged = vscode.workspace.onDidChangeConfiguration( + async () => { + if (utils.checkConfig(CONFIG.CONFIG_ENV_ON_SWITCH)) { + pythonExecutablePath = await utils.setupEnv(context); + } + } + ); + context.subscriptions.push( - changeBaudRate, - closeSerialMonitor, - openSerialMonitor, - openSimulator, - newFile, + installDependencies, runSimulator, - runSimulatorEditorButton, - runDevice, - selectSerialPort, + cpxChangeBaudRate, + cpxCloseSerialMonitor, + cpxDeployToDevice, + cpxNewFile, + cpxOpenSerialMonitor, + cpxOpenSimulator, + cpxSelectSerialPort, + microbitOpenSimulator, + microbitNewFile, vscode.debug.registerDebugConfigurationProvider( CONSTANTS.DEBUG_CONFIGURATION_TYPE, simulatorDebugConfiguration ), debugSessionsStarted, - debugSessionStopped + debugSessionStopped, + configsChanged ); } @@ -918,61 +1092,204 @@ const updateCurrentFileIfPython = async ( } }; +const handleDebuggerTelemetry = () => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_DEBUGGER_INIT_SUCCESS + ); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_DEBUGGER_INIT_SUCCESS + ); + break; + default: + break; + } +}; + +const handleDebuggerFailTelemetry = () => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_DEBUGGER_INIT_FAIL + ); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_DEBUGGER_INIT_FAIL + ); + break; + default: + break; + } +}; + const handleButtonPressTelemetry = (buttonState: any) => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + handleCPXButtonPressTelemetry(buttonState); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + handleMicrobitButtonPressTelemetry(buttonState); + break; + default: + break; + } +}; + +const handleGestureTelemetry = (sensorState: any) => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + handleCPXGestureTelemetry(sensorState); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + break; + default: + break; + } +}; + +const handleSensorTelemetry = (sensor: string) => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + handleCPXSensorTelemetry(sensor); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + handleMicrobitSensorTelemetry(sensor); + break; + default: + break; + } +}; + +const handleCPXButtonPressTelemetry = (buttonState: any) => { if (buttonState.button_a && buttonState.button_b) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_AB); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_SIMULATOR_BUTTON_AB + ); } else if (buttonState.button_a) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_A); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_SIMULATOR_BUTTON_A + ); } else if (buttonState.button_b) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_B); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_SIMULATOR_BUTTON_B + ); } else if (buttonState.switch) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SWITCH); + telemetryAI.trackFeatureUsage(TelemetryEventName.CPX_SIMULATOR_SWITCH); } }; -const handleSensorTelemetry = (sensor: string) => { +const handleCPXGestureTelemetry = (sensorState: any) => { + if (sensorState.shake) { + handleCPXSensorTelemetry("shake"); + } else if (sensorState.touch) { + handleCPXSensorTelemetry("touch"); + } +}; + +const handleCPXSensorTelemetry = (sensor: string) => { switch (sensor) { case "temperature": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_TEMPERATURE_SENSOR + TelemetryEventName.CPX_SIMULATOR_TEMPERATURE_SENSOR ); break; case "light": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_LIGHT_SENSOR + TelemetryEventName.CPX_SIMULATOR_LIGHT_SENSOR ); break; case "motion_x": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_MOTION_SENSOR + TelemetryEventName.CPX_SIMULATOR_MOTION_SENSOR ); break; case "motion_y": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_MOTION_SENSOR + TelemetryEventName.CPX_SIMULATOR_MOTION_SENSOR ); break; case "motion_z": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_MOTION_SENSOR + TelemetryEventName.CPX_SIMULATOR_MOTION_SENSOR ); break; case "shake": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SHAKE); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_SIMULATOR_SHAKE + ); break; case "touch": telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_CAPACITIVE_TOUCH + TelemetryEventName.CPX_SIMULATOR_CAPACITIVE_TOUCH ); break; } }; -const checkForTelemetry = (sensorState: any) => { - if (sensorState.shake) { - handleSensorTelemetry("shake"); - } else if (sensorState.touch) { - handleSensorTelemetry("touch"); +const handleMicrobitButtonPressTelemetry = (buttonState: any) => { + if (buttonState.button_a && buttonState.button_b) { + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_BUTTON_AB + ); + } else if (buttonState.button_a) { + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_BUTTON_A + ); + } else if (buttonState.button_b) { + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_BUTTON_B + ); + } +}; + +const handleMicrobitSensorTelemetry = (sensor: string) => { + switch (sensor) { + case "temperature": + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_TEMPERATURE_SENSOR + ); + break; + case "light": + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_LIGHT_SENSOR + ); + break; + case "motion_x": + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_MOTION_SENSOR + ); + break; + case "motion_y": + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_MOTION_SENSOR + ); + break; + case "motion_z": + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_SIMULATOR_MOTION_SENSOR + ); + break; + } +}; + +const handleNewFileErrorTelemetry = () => { + switch (currentActiveDevice) { + case CONSTANTS.DEVICE_NAME.CPX: + telemetryAI.trackFeatureUsage( + TelemetryEventName.CPX_ERROR_COMMAND_NEW_FILE + ); + break; + case CONSTANTS.DEVICE_NAME.MICROBIT: + telemetryAI.trackFeatureUsage( + TelemetryEventName.MICROBIT_ERROR_COMMAND_NEW_FILE + ); + break; + default: + break; } }; @@ -985,35 +1302,20 @@ const updatePythonExtraPaths = () => { }; const updatePylintArgs = (context: vscode.ExtensionContext) => { - const outPath: string = createEscapedPath( + const outPath: string = utils.createEscapedPath( context.extensionPath, CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY ); - const pyLibsPath: string = createEscapedPath( - context.extensionPath, - CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, - CONSTANTS.FILESYSTEM.PYTHON_LIBS_DIR - ); // update pylint args to extend system path // to include python libs local to extention updateConfigLists( "python.linting.pylintArgs", - [ - "--init-hook", - `import sys; sys.path.extend([\"${outPath}\",\"${pyLibsPath}\"])`, - ], + ["--init-hook", `import sys; sys.path.append(\"${outPath}\")`], vscode.ConfigurationTarget.Workspace ); }; -const createEscapedPath = (...pieces: string[]) => { - const initialPath: string = path.join(...pieces); - - // escape all instances of backslashes - return initialPath.replace(/\\/g, "\\\\"); -}; - const updateConfigLists = ( section: string, newItems: string[], @@ -1042,14 +1344,18 @@ function getWebviewContent(context: vscode.ExtensionContext) {
- + ${loadScript(context, "out/vendor.js")} ${loadScript(context, "out/simulator.js")} `; } +function switchDevice(deviceName: string) { + currentActiveDevice = deviceName; +} // this method is called when your extension is deactivated export async function deactivate() { diff --git a/src/extension_utils/dependencyChecker.ts b/src/extension_utils/dependencyChecker.ts deleted file mode 100644 index de18806cc..000000000 --- a/src/extension_utils/dependencyChecker.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as cp from "child_process"; -import * as compareVersions from "compare-versions"; -import * as os from "os"; -import * as util from "util"; -import { CONSTANTS } from "../constants"; -const exec = util.promisify(cp.exec); - -interface IPayloadResponse { - payload: IDependency; -} - -interface IDependency { - dependency: string; - installed: boolean; -} - -const PYTHON3_REGEX = RegExp("^(Python )(3\\.[0-9]+\\.[0-9]+)"); -const MINIMUM_PYTHON_VERSION = "3.7.0"; - -export class DependencyChecker { - constructor() {} - - public async checkDependency( - dependencyName: string - ): Promise { - let state: boolean = false; - if (dependencyName === CONSTANTS.DEPENDENCY_CHECKER.PYTHON) { - if ( - await this.runCommandVersion( - CONSTANTS.DEPENDENCY_CHECKER.PYTHON3, - MINIMUM_PYTHON_VERSION - ) - ) { - state = true; - dependencyName = CONSTANTS.DEPENDENCY_CHECKER.PYTHON3; - } else if ( - await this.runCommandVersion( - CONSTANTS.DEPENDENCY_CHECKER.PYTHON, - MINIMUM_PYTHON_VERSION - ) - ) { - state = true; - dependencyName = CONSTANTS.DEPENDENCY_CHECKER.PYTHON; - } else { - state = false; - } - } - return { - payload: { - dependency: dependencyName, - installed: state, - }, - }; - } - - private async runCommandVersion( - command: string, - versionDependency?: string - ) { - let installed: boolean = false; - try { - const { stdout } = await exec(command + " --version"); - const matches = PYTHON3_REGEX.exec(stdout); - if (versionDependency) { - installed = matches - ? compareVersions(matches[2], versionDependency) >= 0 - : false; - } else { - installed = true; - } - } catch (err) { - installed = false; - } - return installed; - } -} diff --git a/src/extension_utils/utils.ts b/src/extension_utils/utils.ts index a9c61a37f..ba51c6815 100644 --- a/src/extension_utils/utils.ts +++ b/src/extension_utils/utils.ts @@ -13,20 +13,26 @@ import { CONSTANTS, CPX_CONFIG_FILE, DialogResponses, + GLOBAL_ENV_VARS, + HELPER_FILES, SERVER_INFO, USER_CODE_NAMES, + VERSIONS, } from "../constants"; import { CPXWorkspace } from "../cpxWorkspace"; import { DeviceContext } from "../deviceContext"; -import { DependencyChecker } from "./dependencyChecker"; const exec = util.promisify(cp.exec); +const errorChannel = vscode.window.createOutputChannel( + CONSTANTS.ERROR.INSTALLATION_ERROR +); + // tslint:disable-next-line: export-name export const getPathToScript = ( context: vscode.ExtensionContext, folderName: string, - fileName: string + fileName: string = "" ) => { const onDiskPath = vscode.Uri.file( path.join(context.extensionPath, folderName, fileName) @@ -42,10 +48,13 @@ export const validCodeFileName = (filePath: string) => { ); }; -export const showPrivacyModal = (okAction: () => void) => { +export const showPrivacyModal = ( + okAction: () => void, + thirdPartyDisclaimer: string +) => { vscode.window .showInformationMessage( - `${CONSTANTS.INFO.THIRD_PARTY_WEBSITE}: ${CONSTANTS.LINKS.PRIVACY}`, + `${thirdPartyDisclaimer}: ${CONSTANTS.LINKS.PRIVACY}`, DialogResponses.AGREE_AND_PROCEED, DialogResponses.CANCEL ) @@ -160,45 +169,33 @@ export function generateCPXConfig(): void { mkdirRecursivelySync(path.dirname(cpxConfigFilePath)); fs.writeFileSync(cpxConfigFilePath, JSON.stringify(cpxJson, null, 4)); } -export const checkPythonDependency = async () => { - const dependencyChecker: DependencyChecker = new DependencyChecker(); - const result = await dependencyChecker.checkDependency( - CONSTANTS.DEPENDENCY_CHECKER.PYTHON - ); - return result.payload; -}; -export const checkPipDependency = async () => { - const dependencyChecker: DependencyChecker = new DependencyChecker(); - const result = await dependencyChecker.checkDependency( - CONSTANTS.DEPENDENCY_CHECKER.PIP3 - ); - return result.payload; -}; - -export const setPythonExectuableName = async () => { - // Find our what command is the PATH for python - let executableName: string = ""; - const dependencyCheck = await checkPythonDependency(); - if (dependencyCheck.installed) { - executableName = dependencyCheck.dependency; - } else { +export const isPipInstalled = async (pythonExecutablePath: string) => { + try { + const { stdout } = await executePythonCommand( + pythonExecutablePath, + " -m pip" + ); + return true; + } catch (err) { vscode.window .showErrorMessage( - CONSTANTS.ERROR.NO_PYTHON_PATH, - DialogResponses.INSTALL_PYTHON + CONSTANTS.ERROR.NO_PIP, + DialogResponses.INSTALL_PIP ) .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.INSTALL_PYTHON) { + if (selection === DialogResponses.INSTALL_PIP) { const okAction = () => { - open(CONSTANTS.LINKS.DOWNLOAD_PYTHON); + open(CONSTANTS.LINKS.DOWNLOAD_PIP); }; - showPrivacyModal(okAction); + showPrivacyModal( + okAction, + CONSTANTS.INFO.THIRD_PARTY_WEBSITE_PIP + ); } }); + return false; } - - return executableName; }; export const addVisibleTextEditorCallback = ( @@ -227,7 +224,7 @@ export const addVisibleTextEditorCallback = ( export const filterForPythonFiles = (textEditors: vscode.TextEditor[]) => { return textEditors - .filter(editor => editor.document.languageId === "python") + .filter(editor => editor.document.languageId === GLOBAL_ENV_VARS.PYTHON) .map(editor => editor.document.fileName); }; @@ -258,105 +255,231 @@ export const checkConfig = (configName: string): boolean => { return vscode.workspace.getConfiguration().get(configName) === true; }; -export const checkPythonDependencies = async ( +export const getConfig = (configName: string): string => { + return vscode.workspace.getConfiguration().get(configName); +}; + +export const createEscapedPath = (...pieces: string[]) => { + const initialPath: string = path.join(...pieces); + + // escape all special characters + // https://stackoverflow.com/questions/1779858/how-do-i-escape-a-string-for-a-shell-command-in-node + return `"` + initialPath.replace(/(["'$`\\])/g, "\\$1") + `"`; +}; + +export const getTelemetryState = () => { + return vscode.workspace + .getConfiguration() + .get("telemetry.enableTelemetry", true); +}; + +// Setup code starts + +export const checkIfVenv = async ( context: vscode.ExtensionContext, - pythonExecutable: string + pythonExecutablePath: string ) => { - let hasInstalledDependencies: boolean = false; - const pathToLibs: string = getPathToScript( + const venvCheckerPath: string = getPathToScript( context, CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, - CONSTANTS.FILESYSTEM.PYTHON_LIBS_DIR + HELPER_FILES.CHECK_IF_VENV_PY ); - if (checkPipDependency() && checkPythonDependency()) { - if (checkConfig(CONFIG.SHOW_DEPENDENCY_INSTALL)) { - // check if ./out/python_libs exists; if not, the dependencies - // for adafruit_circuitpython are not (successfully) installed yet - hasInstalledDependencies = - fs.existsSync(pathToLibs) || - (await promptInstallPythonDependencies( - context, - pythonExecutable, - pathToLibs - )); - } + const { stdout } = await executePythonCommand( + pythonExecutablePath, + `"${venvCheckerPath}"` + ); + return stdout.trim() === "1"; +}; + +export const executePythonCommand = async ( + pythonExecutablePath: string, + command: string +) => { + return exec(`${createEscapedPath(pythonExecutablePath)} ${command}`); +}; + +export const validatePythonVersion = async (pythonExecutablePath: string) => { + const { stdout } = await executePythonCommand( + pythonExecutablePath, + "--version" + ); + if (stdout < VERSIONS.MIN_PY_VERSION) { + vscode.window + .showInformationMessage( + CONSTANTS.ERROR.INVALID_PYTHON_PATH, + DialogResponses.INSTALL_PYTHON + ) + .then((installChoice: vscode.MessageItem | undefined) => { + if (installChoice === DialogResponses.INSTALL_PYTHON) { + const okAction = () => { + open(CONSTANTS.LINKS.DOWNLOAD_PYTHON); + }; + showPrivacyModal( + okAction, + CONSTANTS.INFO.THIRD_PARTY_WEBSITE_PYTHON + ); + } + }); + return false; } else { - hasInstalledDependencies = false; + return true; } - return hasInstalledDependencies; }; -export const promptInstallPythonDependencies = ( +export const hasVenv = async (context: vscode.ExtensionContext) => { + const pathToEnv: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.PYTHON_VENV_DIR + ); + + return fs.existsSync(pathToEnv); +}; + +export const promptInstallVenv = ( context: vscode.ExtensionContext, pythonExecutable: string, - pathToLibs: string + pythonExecutableName: string ) => { return vscode.window .showInformationMessage( - CONSTANTS.INFO.INSTALL_PYTHON_DEPENDENCIES, + CONSTANTS.INFO.INSTALL_PYTHON_VENV, DialogResponses.YES, DialogResponses.NO ) .then((selection: vscode.MessageItem | undefined) => { if (selection === DialogResponses.YES) { - return installPythonDependencies( + return installPythonVenv( context, pythonExecutable, - pathToLibs + pythonExecutableName ); - } else if (selection === DialogResponses.NO) { - return vscode.window - .showInformationMessage( - CONSTANTS.INFO.ARE_YOU_SURE, - DialogResponses.INSTALL_NOW, - DialogResponses.DONT_INSTALL - ) - .then((installChoice: vscode.MessageItem | undefined) => { - if (installChoice === DialogResponses.INSTALL_NOW) { - return installPythonDependencies( - context, - pythonExecutable, - pathToLibs - ); - } else { - return false; - } - }); + } else { + // return pythonExecutable, notifying the caller + // that the user was unwilling to create venv + // and by default, this will trigger the extension to + // try using pythonExecutable + return pythonExecutable; } }); }; -export const getTelemetryState = () => { - return vscode.workspace - .getConfiguration() - .get("telemetry.enableTelemetry", true); + +export const getPythonVenv = async ( + context: vscode.ExtensionContext, + pythonExecutableName: string +) => { + const subFolder = os.platform() === "win32" ? "Scripts" : "bin"; + + return getPathToScript( + context, + path.join(CONSTANTS.FILESYSTEM.PYTHON_VENV_DIR, subFolder), + pythonExecutableName + ); }; -export const installPythonDependencies = async ( +export const installPythonVenv = async ( context: vscode.ExtensionContext, pythonExecutable: string, - pathToLibs: string + pythonExecutableName: string ) => { - let installed: boolean = false; - try { - vscode.window.showInformationMessage( - CONSTANTS.INFO.INSTALLING_PYTHON_DEPENDENCIES - ); + const pathToEnv: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.PYTHON_VENV_DIR + ); - const requirementsPath: string = getPathToScript( - context, - CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, - "requirements.txt" - ); + vscode.window.showInformationMessage(CONSTANTS.INFO.INSTALLING_PYTHON_VENV); + + const pythonPath: string = await getPythonVenv( + context, + pythonExecutableName + ); + try { + // make venv // run command to download dependencies to out/python_libs - const { stdout } = await exec( - `${pythonExecutable} -m pip install -r ${requirementsPath} -t ${pathToLibs}` + await executePythonCommand(pythonExecutable, `-m venv "${pathToEnv}"`); + } catch (err) { + vscode.window + .showErrorMessage( + `Virtual environment for download could not be completed. Using original interpreter at: ${pythonExecutable}.`, + DialogResponses.READ_INSTALL_MD + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.READ_INSTALL_MD) { + open(CONSTANTS.LINKS.INSTALL); + } + }); + + console.error(err); + + return pythonExecutable; + } + + return installDependenciesWrapper(context, pythonPath, pythonExecutable); +}; + +export const areDependenciesInstalled = async ( + context: vscode.ExtensionContext, + pythonPath: string +) => { + const dependencyCheckerPath: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + HELPER_FILES.CHECK_PYTHON_DEPENDENCIES + ); + try { + // python script will throw exception + // if not all dependencies are downloaded + const { stdout } = await executePythonCommand( + pythonPath, + `"${dependencyCheckerPath}"` ); + + // output for debugging purposes console.info(stdout); - installed = true; + return true; + } catch (err) { + return false; + } +}; +export const installDependencies = async ( + context: vscode.ExtensionContext, + pythonPath: string +) => { + const requirementsPath: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + "requirements.txt" + ); + + if (!isPipInstalled(pythonPath)) { + return false; + } + + try { + const { stdout } = await executePythonCommand( + pythonPath, + `-m pip install -r "${requirementsPath}"` + ); + + console.info(stdout); vscode.window.showInformationMessage(CONSTANTS.INFO.SUCCESSFUL_INSTALL); + return true; } catch (err) { + return false; + } +}; + +export const installDependenciesWrapper = async ( + context: vscode.ExtensionContext, + pythonPath: string, + backupPythonPath: string = "" +) => { + let errMessage = CONSTANTS.ERROR.DEPENDENCY_DOWNLOAD_ERROR; + if (backupPythonPath !== "") { + errMessage = `${errMessage} Using original interpreter at: ${backupPythonPath}.`; + } + if (!(await installDependencies(context, pythonPath))) { vscode.window .showErrorMessage( CONSTANTS.ERROR.DEPENDENCY_DOWNLOAD_ERROR, @@ -367,9 +490,175 @@ export const installPythonDependencies = async ( open(CONSTANTS.LINKS.INSTALL); } }); + return backupPythonPath; + } + return pythonPath; +}; +export const getCurrentpythonExecutablePath = async () => { + let originalpythonExecutablePath = ""; - console.error(err); - installed = false; + // try to get name from interpreter + try { + originalpythonExecutablePath = getConfig(CONFIG.PYTHON_PATH); + } catch (err) { + originalpythonExecutablePath = GLOBAL_ENV_VARS.PYTHON; + } + + if ( + originalpythonExecutablePath === GLOBAL_ENV_VARS.PYTHON || + originalpythonExecutablePath === "" + ) { + try { + const { stdout } = await executePythonCommand( + GLOBAL_ENV_VARS.PYTHON, + `-c "import sys; print(sys.executable)"` + ); + originalpythonExecutablePath = stdout.trim(); + } catch (err) { + vscode.window + .showErrorMessage( + CONSTANTS.ERROR.NO_PYTHON_PATH, + DialogResponses.INSTALL_PYTHON + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.INSTALL_PYTHON) { + const okAction = () => { + open(CONSTANTS.LINKS.DOWNLOAD_PYTHON); + }; + showPrivacyModal( + okAction, + CONSTANTS.INFO.THIRD_PARTY_WEBSITE_PYTHON + ); + } + }); + + // no python installed, cannot get path + return ""; + } } - return installed; + // fix path to be absolute + if (!path.isAbsolute(originalpythonExecutablePath)) { + originalpythonExecutablePath = path.join( + vscode.workspace.rootPath, + originalpythonExecutablePath + ); + } + + if (!fs.existsSync(originalpythonExecutablePath)) { + await vscode.window.showErrorMessage(CONSTANTS.ERROR.BAD_PYTHON_PATH); + return ""; + } + + if (!(await validatePythonVersion(originalpythonExecutablePath))) { + return ""; + } + + return originalpythonExecutablePath; +}; +export const setupEnv = async ( + context: vscode.ExtensionContext, + needsResponse: boolean = false +) => { + const originalpythonExecutablePath = await getCurrentpythonExecutablePath(); + let pythonExecutablePath = originalpythonExecutablePath; + let pythonExecutableName: string = + os.platform() === "win32" + ? HELPER_FILES.PYTHON_EXE + : HELPER_FILES.PYTHON; + + if (!(await areDependenciesInstalled(context, pythonExecutablePath))) { + // environment needs to install dependencies + if (!(await checkIfVenv(context, pythonExecutablePath))) { + const pythonExecutablePathVenv = await getPythonVenv( + context, + pythonExecutableName + ); + if (await hasVenv(context)) { + // venv in extention exists with wrong dependencies + if ( + !(await areDependenciesInstalled( + context, + pythonExecutablePathVenv + )) + ) { + pythonExecutablePath = await installDependenciesWrapper( + context, + pythonExecutablePathVenv, + pythonExecutablePath + ); + } else { + pythonExecutablePath = pythonExecutablePathVenv; + } + } else { + pythonExecutablePath = await promptInstallVenv( + context, + originalpythonExecutablePath, + pythonExecutableName + ); + } + + if (pythonExecutablePath === pythonExecutablePathVenv) { + vscode.window.showInformationMessage( + CONSTANTS.INFO.UPDATED_TO_EXTENSION_VENV + ); + vscode.workspace + .getConfiguration() + .update(CONFIG.PYTHON_PATH, pythonExecutablePath); + } + } + if (pythonExecutablePath === originalpythonExecutablePath) { + // going with original interpreter, either because + // already in venv or error in creating custom venv + if (checkConfig(CONFIG.SHOW_DEPENDENCY_INSTALL)) { + await vscode.window + .showInformationMessage( + CONSTANTS.INFO.INSTALL_PYTHON_DEPS, + DialogResponses.INSTALL_NOW, + DialogResponses.DONT_INSTALL + ) + .then( + async ( + installChoice: vscode.MessageItem | undefined + ) => { + if (installChoice === DialogResponses.INSTALL_NOW) { + await installDependenciesWrapper( + context, + pythonExecutablePath + ); + } else { + await vscode.window + .showInformationMessage( + CONSTANTS.INFO.ARE_YOU_SURE, + DialogResponses.INSTALL_NOW, + DialogResponses.DONT_INSTALL + ) + .then( + async ( + installChoice2: + | vscode.MessageItem + | undefined + ) => { + if ( + installChoice2 === + DialogResponses.INSTALL_NOW + ) { + await installDependenciesWrapper( + context, + pythonExecutablePath + ); + } + } + ); + } + } + ); + } + } + } else if (needsResponse) { + vscode.window.showInformationMessage( + CONSTANTS.INFO.ALREADY_SUCCESSFUL_INSTALL + ); + } + + return pythonExecutablePath; }; diff --git a/src/latest_release_note.ts b/src/latest_release_note.ts new file mode 100644 index 000000000..a4e1ddabd --- /dev/null +++ b/src/latest_release_note.ts @@ -0,0 +1,67 @@ +// TODO: find a better way of loading html into a string +export const LATEST_RELEASE_NOTE = `

Device Simulator Express Release Notes 👩🏾‍💻 👨🏾‍💻 (Feb. 27, 2020)

+

+ Welcome to the first update to the Device Simulator Express! Please feel free to enable our feature flag in + Settings + (under the setting titled “deviceSimulatorExpress.previewMode” in the User settings). +

+

Changes

+

+

Fixes (enabled by default):

+
    +
  • Enabled support for “from adafruit_circuitplayground import cp” as an import statement for the CPX and + changed + “New File” template to use this format.
  • + +
  • State for sensor selection persists.
  • +
  • More reliable dependency installation and more informative setup fail information.
  • +
  • Fixes to Serial Monitor for CPX device deployment.
  • +
  • More robust debugger functionality.
  • +
  • Fixed spelling and clarity errors in documentation and pop-up messages.
  • +
+

New features (only available with feature flag enabled):

+
    +
  • BBC micro:bit simulator and debugger – open up a new micro:bit file, write code for the micro:bit and + test it out! +
      +
    • Ability to interact with LEDs, buttons, and sensors.
    • +
    • Includes autocompletion and error flagging.
    • +
    • Supports the following:
    • +
        +
      • Classes: +
          +
        • display
        • +
        • image
        • +
        • accelerometer
        • +
        • button
        • +
        +
      +
        +
      • Global static functions:
      • +
          +
        • sleep()
        • +
        • running_time()
        • +
        • temperature()
        • +
        +
      +
    +
      +
    • Includes accessibility considerations for simulation.
    • +
        +
      • Has ability to use keyboard for button presses and navigation.
      • +
      +
    +
+

+

Upcoming Improvements

+
    +
  • Deploying to device on the micro:bit with serial monitor interaction.
  • +
+
+

Happy Hacking! ✨✨🐍🐍🍰
+       - The Device Simulator Express Team

`; diff --git a/src/microbit/__init__.py b/src/microbit/__init__.py new file mode 100644 index 000000000..e444b34f0 --- /dev/null +++ b/src/microbit/__init__.py @@ -0,0 +1,35 @@ +from .__model.image import Image +from .__model.microbit_model import __mb +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent + +accelerometer = __mb.accelerometer +button_a = __mb.button_a +button_b = __mb.button_b +display = __mb.display + + +def sleep(n): + """ + Wait for ``n`` milliseconds. One second is 1000 milliseconds, so:: + microbit.sleep(1000) + will pause the execution for one second. ``n`` can be an integer or + a floating point number. + """ + __mb.sleep(n) + + +def running_time(): + """ + Return the number of milliseconds since the board was switched on or + restarted. + """ + return __mb.running_time() + + +def temperature(): + """ + Return the temperature of the micro:bit in degrees Celcius. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_TEMPERATURE) + return __mb.temperature() diff --git a/src/microbit/__model/accelerometer.py b/src/microbit/__model/accelerometer.py new file mode 100644 index 000000000..6360ce982 --- /dev/null +++ b/src/microbit/__model/accelerometer.py @@ -0,0 +1,130 @@ +from . import constants as CONSTANTS +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent + + +class Accelerometer: + # The implementation is based off of https://microbit-micropython.readthedocs.io/en/v1.0.1/accelerometer.html. + def __init__(self): + self.__x = 0 + self.__y = 0 + self.__z = 0 + self.__current_gesture = "" + self.__prev_gestures = set() + self.__gestures = [] + + def get_x(self): + """ + Get the acceleration measurement in the ``x`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) + return self.__x + + def get_y(self): + """ + Get the acceleration measurement in the ``y`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) + return self.__y + + def get_z(self): + """ + Get the acceleration measurement in the ``z`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) + return self.__z + + def get_values(self): + """ + Get the acceleration measurements in all axes at once, as a three-element + tuple of integers ordered as X, Y, Z. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) + return (self.__x, self.__y, self.__z) + + def current_gesture(self): + """ + Return the name of the current gesture. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) + self.__add_current_gesture_to_gesture_lists() + return self.__current_gesture + + def is_gesture(self, name): + """ + Return True or False to indicate if the named gesture is currently active. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) + self.__add_current_gesture_to_gesture_lists() + if name not in CONSTANTS.GESTURES: + raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) + return name == self.__current_gesture + + def was_gesture(self, name): + """ + Return True or False to indicate if the named gesture was active since the + last [was_gesture] call. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) + self.__add_current_gesture_to_gesture_lists() + if name not in CONSTANTS.GESTURES: + raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) + was_gesture = name in self.__prev_gestures + self.__prev_gestures.clear() + return was_gesture + + def get_gestures(self): + """ + Return a tuple of the gesture history. The most recent is listed last. + Also clears the gesture history before returning. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) + self.__add_current_gesture_to_gesture_lists() + gestures = tuple(self.__gestures) + self.__gestures.clear() + return gestures + + # Helpers and Hidden Functions + + def __get_accel(self, axis): + if axis == "x": + return self.get_x() + elif axis == "y": + return self.get_y() + elif axis == "z": + return self.get_z() + + def __set_accel(self, axis, accel): + if accel < CONSTANTS.MIN_ACCELERATION or accel > CONSTANTS.MAX_ACCELERATION: + raise ValueError(CONSTANTS.INVALID_ACCEL_ERR) + if axis == "x": + self.__x = accel + elif axis == "y": + self.__y = accel + elif axis == "z": + self.__z = accel + + def __set_gesture(self, gesture): + if gesture in CONSTANTS.GESTURES: + self.__current_gesture = gesture + elif gesture == "": + self.__current_gesture = "" + else: + raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) + + def __add_current_gesture_to_gesture_lists(self): + if self.__current_gesture in CONSTANTS.GESTURES: + self.__gestures.append(self.__current_gesture) + self.__prev_gestures.add(self.__current_gesture) + + def __update(self, axis, accel): + if accel is not None: + previous_accel = self.__get_accel(axis) + if accel != previous_accel: + self.__set_accel(axis, accel) diff --git a/src/microbit/__model/button.py b/src/microbit/__model/button.py new file mode 100644 index 000000000..1bbe4ddbc --- /dev/null +++ b/src/microbit/__model/button.py @@ -0,0 +1,59 @@ +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent + + +class Button: + # The implementation is based off of https://microbit-micropython.readthedocs.io/en/v1.0.1/button.html. + def __init__(self): + self.__pressed = False + self.__presses = 0 + self.__prev_pressed = False + + def is_pressed(self): + """ + Returns ``True`` if the specified button ``button`` is currently being + held down, and ``False`` otherwise. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) + return self.__pressed + + def was_pressed(self): + """ + Returns ``True`` or ``False`` to indicate if the button was pressed + (went from up to down) since the device started or the last time this + method was called. Calling this method will clear the press state so + that the button must be pressed again before this method will return + ``True`` again. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) + res = self.__prev_pressed + self.__prev_pressed = False + return res + + def get_presses(self): + """ + Returns the running total of button presses, and resets this total + to zero before returning. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) + res = self.__presses + self.__presses = 0 + return res + + def __press_down(self): + self.__pressed = True + self.__prev_pressed = True + self.__presses += 1 + + def __release(self): + self.__pressed = False + + def __update(self, is_button_pressed): + if is_button_pressed is not None: + was_button_pressed = self.is_pressed() + + if is_button_pressed != was_button_pressed: + if is_button_pressed: + self.__press_down() + else: + self.__release() diff --git a/src/microbit/__model/constants.py b/src/microbit/__model/constants.py new file mode 100644 index 000000000..141f7fcde --- /dev/null +++ b/src/microbit/__model/constants.py @@ -0,0 +1,167 @@ +MICROBIT = "micro:bit" + +# string arguments for constructor +BLANK_5X5 = "00000:00000:00000:00000:00000:" + +# pre-defined image patterns +IMAGE_PATTERNS = { + "HEART": "09090:99999:99999:09990:00900:", + "HEART_SMALL": "00000:09090:09990:00900:00000:", + "HAPPY": "00000:09090:00000:90009:09990:", + "SMILE": "00000:00000:00000:90009:09990:", + "SAD": "00000:09090:00000:09990:90009:", + "CONFUSED": "00000:09090:00000:09090:90909:", + "ANGRY": "90009:09090:00000:99999:90909:", + "ASLEEP": "00000:99099:00000:09990:00000:", + "SURPRISED": "09090:00000:00900:09090:00900:", + "SILLY": "90009:00000:99999:00909:00999:", + "FABULOUS": "99999:99099:00000:09090:09990:", + "MEH": "09090:00000:00090:00900:09000:", + "YES": "00000:00009:00090:90900:09000:", + "NO": "90009:09090:00900:09090:90009:", + "CLOCK12": "00900:00900:00900:00000:00000:", + "CLOCK11": "09000:09000:00900:00000:00000:", + "CLOCK10": "00000:99000:00900:00000:00000:", + "CLOCK9": "00000:00000:99900:00000:00000:", + "CLOCK8": "00000:00000:00900:99000:00000:", + "CLOCK7": "00000:00000:00900:09000:09000:", + "CLOCK6": "00000:00000:00900:00900:00900:", + "CLOCK5": "00000:00000:00900:00090:00090:", + "CLOCK4": "00000:00000:00900:00099:00000:", + "CLOCK3": "00000:00000:00999:00000:00000:", + "CLOCK2": "00000:00099:00900:00000:00000:", + "CLOCK1": "00090:00090:00900:00000:00000:", + "ARROW_N": "00900:09990:90909:00900:00900:", + "ARROW_NE": "00999:00099:00909:09000:90000:", + "ARROW_E": "00900:00090:99999:00090:00900:", + "ARROW_SE": "90000:09000:00909:00099:00999:", + "ARROW_S": "00900:00900:90909:09990:00900:", + "ARROW_SW": "00009:00090:90900:99000:99900:", + "ARROW_W": "00900:09000:99999:09000:00900:", + "ARROW_NW": "99900:99000:90900:00090:00009:", + "TRIANGLE": "00000:00900:09090:99999:00000:", + "TRIANGLE_LEFT": "90000:99000:90900:90090:99999:", + "CHESSBOARD": "09090:90909:09090:90909:09090:", + "DIAMOND": "00900:09090:90009:09090:00900:", + "DIAMOND_SMALL": "00000:00900:09090:00900:00000:", + "SQUARE": "99999:90009:90009:90009:99999:", + "SQUARE_SMALL": "00000:09990:09090:09990:00000:", + "RABBIT": "90900:90900:99990:99090:99990:", + "COW": "90009:90009:99999:09990:00900:", + "MUSIC_CROTCHET": "00900:00900:00900:99900:99900:", + "MUSIC_QUAVER": "00900:00990:00909:99900:99900:", + "MUSIC_QUAVERS": "09999:09009:09009:99099:99099:", + "PITCHFORK": "90909:90909:99999:00900:00900:", + "XMAS": "00900:09990:00900:09990:99999:", + "PACMAN": "09999:99090:99900:99990:09999:", + "TARGET": "00900:09990:99099:09990:00900:", + "TSHIRT": "99099:99999:09990:09990:09990:", + "ROLLERSKATE": "00099:00099:99999:99999:09090:", + "DUCK": "09900:99900:09999:09990:00000:", + "HOUSE": "00900:09990:99999:09990:09090:", + "TORTOISE": "00000:09990:99999:09090:00000:", + "BUTTERFLY": "99099:99999:00900:99999:99099:", + "STICKFIGURE": "00900:99999:00900:09090:90009:", + "GHOST": "99999:90909:99999:99999:90909:", + "SWORD": "00900:00900:00900:09990:00900:", + "GIRAFFE": "99000:09000:09000:09990:09090:", + "SKULL": "09990:90909:99999:09990:09990:", + "UMBRELLA": "09990:99999:00900:90900:09900:", + "SNAKE": "99000:99099:09090:09990:00000:", +} + +IMAGE_TUPLE_LOOKUP = { + "ALL_CLOCKS": [ + "CLOCK12", + "CLOCK11", + "CLOCK10", + "CLOCK9", + "CLOCK8", + "CLOCK7", + "CLOCK6", + "CLOCK5", + "CLOCK4", + "CLOCK3", + "CLOCK2", + "CLOCK1", + ], + "ALL_ARROWS": [ + "ARROW_N", + "ARROW_NE", + "ARROW_E", + "ARROW_SE", + "ARROW_S", + "ARROW_SW", + "ARROW_W", + "ARROW_NW", + ], +} + +# 5x5 Alphabet +# Taken from https://raw.githubusercontent.com/micropython/micropython/264d80c84e034541bd6e4b461bfece4443ffd0ac/ports/nrf/boards/microbit/modules/microbitfont.h +ALPHABET = b"\x00\x00\x00\x00\x00\x08\x08\x08\x00\x08\x0a\x4a\x40\x00\x00\x0a\x5f\xea\x5f\xea\x0e\xd9\x2e\xd3\x6e\x19\x32\x44\x89\x33\x0c\x92\x4c\x92\x4d\x08\x08\x00\x00\x00\x04\x88\x08\x08\x04\x08\x04\x84\x84\x88\x00\x0a\x44\x8a\x40\x00\x04\x8e\xc4\x80\x00\x00\x00\x04\x88\x00\x00\x0e\xc0\x00\x00\x00\x00\x08\x00\x01\x22\x44\x88\x10\x0c\x92\x52\x52\x4c\x04\x8c\x84\x84\x8e\x1c\x82\x4c\x90\x1e\x1e\xc2\x44\x92\x4c\x06\xca\x52\x5f\xe2\x1f\xf0\x1e\xc1\x3e\x02\x44\x8e\xd1\x2e\x1f\xe2\x44\x88\x10\x0e\xd1\x2e\xd1\x2e\x0e\xd1\x2e\xc4\x88\x00\x08\x00\x08\x00\x00\x04\x80\x04\x88\x02\x44\x88\x04\x82\x00\x0e\xc0\x0e\xc0\x08\x04\x82\x44\x88\x0e\xd1\x26\xc0\x04\x0e\xd1\x35\xb3\x6c\x0c\x92\x5e\xd2\x52\x1c\x92\x5c\x92\x5c\x0e\xd0\x10\x10\x0e\x1c\x92\x52\x52\x5c\x1e\xd0\x1c\x90\x1e\x1e\xd0\x1c\x90\x10\x0e\xd0\x13\x71\x2e\x12\x52\x5e\xd2\x52\x1c\x88\x08\x08\x1c\x1f\xe2\x42\x52\x4c\x12\x54\x98\x14\x92\x10\x10\x10\x10\x1e\x11\x3b\x75\xb1\x31\x11\x39\x35\xb3\x71\x0c\x92\x52\x52\x4c\x1c\x92\x5c\x90\x10\x0c\x92\x52\x4c\x86\x1c\x92\x5c\x92\x51\x0e\xd0\x0c\x82\x5c\x1f\xe4\x84\x84\x84\x12\x52\x52\x52\x4c\x11\x31\x31\x2a\x44\x11\x31\x35\xbb\x71\x12\x52\x4c\x92\x52\x11\x2a\x44\x84\x84\x1e\xc4\x88\x10\x1e\x0e\xc8\x08\x08\x0e\x10\x08\x04\x82\x41\x0e\xc2\x42\x42\x4e\x04\x8a\x40\x00\x00\x00\x00\x00\x00\x1f\x08\x04\x80\x00\x00\x00\x0e\xd2\x52\x4f\x10\x10\x1c\x92\x5c\x00\x0e\xd0\x10\x0e\x02\x42\x4e\xd2\x4e\x0c\x92\x5c\x90\x0e\x06\xc8\x1c\x88\x08\x0e\xd2\x4e\xc2\x4c\x10\x10\x1c\x92\x52\x08\x00\x08\x08\x08\x02\x40\x02\x42\x4c\x10\x14\x98\x14\x92\x08\x08\x08\x08\x06\x00\x1b\x75\xb1\x31\x00\x1c\x92\x52\x52\x00\x0c\x92\x52\x4c\x00\x1c\x92\x5c\x90\x00\x0e\xd2\x4e\xc2\x00\x0e\xd0\x10\x10\x00\x06\xc8\x04\x98\x08\x08\x0e\xc8\x07\x00\x12\x52\x52\x4f\x00\x11\x31\x2a\x44\x00\x11\x31\x35\xbb\x00\x12\x4c\x8c\x92\x00\x11\x2a\x44\x98\x00\x1e\xc4\x88\x1e\x06\xc4\x8c\x84\x86\x08\x08\x08\x08\x08\x18\x08\x0c\x88\x18\x00\x00\x0c\x83\x60" +# We support ASCII characters between these indexes on the microbit +ASCII_START = 32 +ASCII_END = 126 +SPACE_BETWEEN_LETTERS_WIDTH = 1 +WHITESPACE_WIDTH = 3 + +# numerical LED values +LED_HEIGHT = 5 +LED_WIDTH = 5 +BRIGHTNESS_MIN = 0 +BRIGHTNESS_MAX = 9 + +# sensor max/min values +MAX_TEMPERATURE = 125 +MIN_TEMPERATURE = -55 +MAX_LIGHT_LEVEL = 255 +MIN_LIGHT_LEVEL = 0 +MAX_ACCELERATION = 1023 +MIN_ACCELERATION = -1023 + +GESTURES = set( + [ + "up", + "down", + "left", + "right", + "face up", + "face down", + "freefall", + "3g", + "6g", + "8g", + "shake", + ] +) + +# error messages +BRIGHTNESS_ERR = "brightness out of bounds" +COPY_ERR_MESSAGE = "please call copy function first" +INCORR_IMAGE_SIZE = "image data is incorrect size" +INDEX_ERR = "index out of bounds" +NOT_IMPLEMENTED_ERROR = "This method is not implemented by the simulator" +UNSUPPORTED_ADD_TYPE = "unsupported types for __add__:" +SAME_SIZE_ERR = "images must be the same size" +INVALID_GESTURE_ERR = "invalid gesture" +INVALID_ACCEL_ERR = "invalid acceleration" +INVALID_LIGHT_LEVEL_ERR = "invalid light level" +INVALID_TEMPERATURE_ERR = "invalid temperature" + +TIME_DELAY = 0.03 + +EXPECTED_INPUT_BUTTONS = [ + "button_a", + "button_b", +] + +EXPECTED_INPUT_ACCEL = { + "motion_x": "x", + "motion_y": "y", + "motion_z": "z", +} + +EXPECTED_INPUT_LIGHT = "light" + +EXPECTED_INPUT_TEMP = "temperature" diff --git a/src/microbit/__model/display.py b/src/microbit/__model/display.py new file mode 100644 index 000000000..eee651064 --- /dev/null +++ b/src/microbit/__model/display.py @@ -0,0 +1,370 @@ +import copy +import time +import threading +import common + +from common import utils +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent +from . import constants as CONSTANTS +from .image import Image + + +class Display: + # The implementation based off of https://microbit-micropython.readthedocs.io/en/v1.0.1/display.html. + + def __init__(self): + self.__image = Image() + self.__on = True + self.__light_level = 0 + self.__blank_image = Image() + + self.__current_pid = None + self.__lock = threading.Lock() + self.__debug_mode = False + + def scroll(self, value, delay=150, wait=True, loop=False, monospace=False): + """ + Scrolls ``value`` horizontally on the display. If ``value`` is an integer or float it is + first converted to a string using ``str()``. The ``delay`` parameter controls how fast + the text is scrolling. + + If ``wait`` is ``True``, this function will block until the animation is + finished, otherwise the animation will happen in the background. + + If ``loop`` is ``True``, the animation will repeat forever. + + If ``monospace`` is ``True``, the characters will all take up 5 pixel-columns + in width, otherwise there will be exactly 1 blank pixel-column between each + character as they scroll. + + Note that the ``wait``, ``loop`` and ``monospace`` arguments must be specified + using their keyword. + """ + if not wait: + thread = threading.Thread( + target=self.scroll, args=(value, delay, True, loop, monospace) + ) + thread.start() + return + + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_SCROLL) + + # Set current_pid to the thread's identifier + self.__lock.acquire() + self.__current_pid = threading.get_ident() + self.__lock.release() + + if isinstance(value, (str, int, float)): + value = str(value) + else: + raise TypeError(f"can't convert {type(value)} object to str implicitly") + + letters = [] + for c in value: + if monospace: + letters.append(Display.__get_image_from_char(c)) + letters.append( + Image(CONSTANTS.SPACE_BETWEEN_LETTERS_WIDTH, CONSTANTS.LED_HEIGHT) + ) + else: + if c == " ": + letters.append( + Image(CONSTANTS.WHITESPACE_WIDTH, CONSTANTS.LED_HEIGHT) + ) + else: + letters.append( + Display.__strip_unlit_columns(Display.__get_image_from_char(c)) + ) + letters.append( + Image( + CONSTANTS.SPACE_BETWEEN_LETTERS_WIDTH, CONSTANTS.LED_HEIGHT, + ) + ) + appended_image = Display.__create_scroll_image(letters) + + while True: + # Show the scrolled image one square at a time. + for x in range(appended_image.width() - CONSTANTS.LED_WIDTH + 1): + self.__lock.acquire() + + # If show or scroll is called again, there will be a different pid and break + if self.__current_pid != threading.get_ident(): + self.__lock.release() + break + + self.__image.blit( + appended_image, x, 0, CONSTANTS.LED_WIDTH, CONSTANTS.LED_HEIGHT + ) + self.__lock.release() + self.__update_client() + + Display.sleep_ms(delay) + + if not loop: + break + + def show(self, value, delay=400, wait=True, loop=False, clear=False): + """ + Display the ``image``. + + If ``value`` is a string, float or integer, display letters/digits in sequence. + Otherwise, if ``value`` is an iterable sequence of images, display these images in sequence. + Each letter, digit or image is shown with ``delay`` milliseconds between them. + + If ``wait`` is ``True``, this function will block until the animation is + finished, otherwise the animation will happen in the background. + + If ``loop`` is ``True``, the animation will repeat forever. + + If ``clear`` is ``True``, the display will be cleared after the iterable has finished. + + Note that the ``wait``, ``loop`` and ``clear`` arguments must be specified + using their keyword. + """ + if not wait: + thread = threading.Thread( + target=self.show, args=(value, delay, True, loop, clear) + ) + thread.start() + return + + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_SHOW) + + # Set current_pid to the thread's identifier + self.__lock.acquire() + self.__current_pid = threading.get_ident() + self.__lock.release() + + images = [] + use_delay = False + if isinstance(value, Image): + images.append(value.crop(0, 0, CONSTANTS.LED_WIDTH, CONSTANTS.LED_HEIGHT)) + elif isinstance(value, (str, int, float)): + chars = list(str(value)) + for c in chars: + images.append(Display.__get_image_from_char(c)) + if len(chars) > 1: + use_delay = True + else: + # Check if iterable + try: + _ = iter(value) + except TypeError as e: + raise e + + for elem in value: + if isinstance(elem, Image): + images.append( + elem.crop(0, 0, CONSTANTS.LED_WIDTH, CONSTANTS.LED_HEIGHT) + ) + elif isinstance(elem, str) and len(elem) == 1: + images.append(Display.__get_image_from_char(elem)) + # If elem is not char or image, break without iterating through rest of list + else: + break + use_delay = True + + while True: + for image in images: + self.__lock.acquire() + + # If show or scroll is called again, there will be a different pid and break + if self.__current_pid != threading.get_ident(): + self.__lock.release() + break + + self.__image = image + self.__lock.release() + self.__update_client() + + if use_delay: + Display.sleep_ms(delay) + + if not loop: + break + if clear: + self.clear() + + def get_pixel(self, x, y): + """ + Return the brightness of the LED at column ``x`` and row ``y`` as an + integer between 0 (off) and 9 (bright). + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + self.__lock.acquire() + pixel = self.__image.get_pixel(x, y) + self.__lock.release() + return pixel + + def set_pixel(self, x, y, value): + """ + Set the brightness of the LED at column ``x`` and row ``y`` to ``value``, + which has to be an integer between 0 and 9. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + self.__lock.acquire() + self.__image.set_pixel(x, y, value) + self.__lock.release() + self.__update_client() + + def clear(self): + """ + Set the brightness of all LEDs to 0 (off). + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + self.__lock.acquire() + self.__image = Image() + self.__lock.release() + self.__update_client() + + def on(self): + """ + Use on() to turn on the display. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + self.__on = True + + def off(self): + """ + Use off() to turn off the display. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + self.__on = False + + def is_on(self): + """ + Returns ``True`` if the display is on, otherwise returns ``False``. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) + return self.__on + + def read_light_level(self): + """ + Use the display's LEDs in reverse-bias mode to sense the amount of light + falling on the display. Returns an integer between 0 and 255 representing + the light level, with larger meaning more light. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_LIGHT_LEVEL) + return self.__light_level + + def __set_light_level(self, level): + if level < CONSTANTS.MIN_LIGHT_LEVEL or level > CONSTANTS.MAX_LIGHT_LEVEL: + raise ValueError(CONSTANTS.INVALID_LIGHT_LEVEL_ERR) + else: + self.__light_level = level + + # Helpers + + def __get_array(self): + self.__lock.acquire() + if self.is_on(): + leds = copy.deepcopy(self.__image._Image__LED) + else: + leds = self.__blank_image._Image__LED + self.__lock.release() + return leds + + @staticmethod + def __get_image_from_char(c): + # If c is not between the ASCII alphabet we cover, make it a question mark + if ord(c) < CONSTANTS.ASCII_START or ord(c) > CONSTANTS.ASCII_END: + c = "?" + offset = (ord(c) - CONSTANTS.ASCII_START) * CONSTANTS.LED_WIDTH + representative_bytes = CONSTANTS.ALPHABET[ + offset : offset + CONSTANTS.LED_HEIGHT + ] + return Image(Display.__convert_bytearray_to_image_str(representative_bytes)) + + # Removes columns that are not lit + @staticmethod + def __strip_unlit_columns(image): + min_index = CONSTANTS.LED_WIDTH - 1 + max_index = 0 + for row in image._Image__LED: + for index, bit in enumerate(row): + if bit > 0: + min_index = min(min_index, index) + max_index = max(max_index, index) + return image.crop(min_index, 0, max_index - min_index + 1, CONSTANTS.LED_HEIGHT) + + # This method is different from Image's __bytes_to_array. + # This one requires a conversion from binary of the ALPHABET constant to an image. + @staticmethod + def __convert_bytearray_to_image_str(byte_array): + arr = [] + for b in byte_array: + # Convert byte to binary + b_as_bits = str(bin(b))[2:] + sub_arr = [] + while len(sub_arr) < 5: + # Iterate throught bits + # If there is a 1 at b, then the pixel at column b is lit + for bit in b_as_bits[::-1]: + if len(sub_arr) < 5: + sub_arr.insert(0, int(bit) * CONSTANTS.BRIGHTNESS_MAX) + else: + break + # Add 0s to the front until the list is 5 long + while len(sub_arr) < 5: + sub_arr.insert(0, 0) + arr.append(sub_arr) + image_str = "" + for row in arr: + for elem in row: + image_str += str(elem) + image_str += ":" + return image_str + + @staticmethod + def __insert_blank_column(image): + for row in image._Image__LED: + row.append(0) + + @staticmethod + def __create_scroll_image(images): + blank_5x5_image = Image() + front_of_scroll_image = Image(4, 5) + images.insert(0, front_of_scroll_image) + + scroll_image = Image._Image__append_images(images) + end_of_scroll_image = Image() + # Insert columns of 0s until the ending is a 5x5 blank + end_of_scroll_image.blit( + scroll_image, + scroll_image.width() - CONSTANTS.LED_WIDTH, + 0, + CONSTANTS.LED_WIDTH, + CONSTANTS.LED_HEIGHT, + ) + while not Image._Image__same_image(end_of_scroll_image, blank_5x5_image): + Display.__insert_blank_column(scroll_image) + end_of_scroll_image.blit( + scroll_image, + scroll_image.width() - CONSTANTS.LED_WIDTH, + 0, + CONSTANTS.LED_WIDTH, + CONSTANTS.LED_HEIGHT, + ) + + return scroll_image + + def __update_client(self): + sendable_json = {"leds": self.__get_array()} + + if self.__debug_mode: + common.debugger_communication_client.debug_send_to_simulator( + sendable_json, CONSTANTS.MICROBIT + ) + else: + common.utils.send_to_simulator(sendable_json, CONSTANTS.MICROBIT) + + def __update_light_level(self, new_light_level): + if new_light_level is not None: + previous_light_level = self.read_light_level() + if new_light_level != previous_light_level: + self.__set_light_level(new_light_level) + + @staticmethod + def sleep_ms(ms): + time.sleep(ms / 1000) diff --git a/src/microbit/__model/image.py b/src/microbit/__model/image.py new file mode 100644 index 000000000..391e17e1e --- /dev/null +++ b/src/microbit/__model/image.py @@ -0,0 +1,539 @@ +from . import constants as CONSTANTS +from .producer_property import ProducerProperty +from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent + + +class Image: + """ + If ``string`` is used, it has to consist of digits 0-9 arranged into + lines, describing the image, for example:: + + image = Image("90009:" + "09090:" + "00900:" + "09090:" + "90009") + + will create a 5×5 image of an X. The end of a line is indicated by a colon. + It's also possible to use a newline (\\n) to indicate the end of a line + like this:: + + image = Image("90009\\n" + "09090\\n" + "00900\\n" + "09090\\n" + "90009") + + The other form creates an empty image with ``width`` columns and + ``height`` rows. Optionally ``buffer`` can be an array of + ``width``×``height`` integers in range 0-9 to initialize the image:: + + Image(2, 2, b'\x08\x08\x08\x08') + + or:: + + Image(2, 2, bytearray([9,9,9,9])) + + Will create a 2 x 2 pixel image at full brightness. + + .. note:: + + Keyword arguments cannot be passed to ``buffer``. + """ + + # Attributes assigned (to functions) later; + # having this here helps the pylint. + HEART = None + HEART_SMALL = None + HAPPY = None + SMILE = None + SAD = None + CONFUSED = None + ANGRY = None + ASLEEP = None + SURPRISED = None + SILLY = None + FABULOUS = None + MEH = None + YES = None + NO = None + CLOCK12 = None + CLOCK11 = None + CLOCK10 = None + CLOCK9 = None + CLOCK8 = None + CLOCK7 = None + CLOCK6 = None + CLOCK5 = None + CLOCK4 = None + CLOCK3 = None + CLOCK2 = None + CLOCK1 = None + ARROW_N = None + ARROW_NE = None + ARROW_E = None + ARROW_SE = None + ARROW_S = None + ARROW_SW = None + ARROW_W = None + ARROW_NW = None + TRIANGLE = None + TRIANGLE_LEFT = None + CHESSBOARD = None + DIAMOND = None + DIAMOND_SMALL = None + SQUARE = None + SQUARE_SMALL = None + RABBIT = None + COW = None + MUSIC_CROTCHET = None + MUSIC_QUAVER = None + MUSIC_QUAVERS = None + PITCHFORK = None + XMAS = None + PACMAN = None + TARGET = None + TSHIRT = None + ROLLERSKATE = None + DUCK = None + HOUSE = None + TORTOISE = None + BUTTERFLY = None + STICKFIGURE = None + GHOST = None + SWORD = None + GIRAFFE = None + SKULL = None + UMBRELLA = None + SNAKE = None + ALL_CLOCKS = None + ALL_ARROWS = None + + # implementing image model as described here: + # https://microbit-micropython.readthedocs.io/en/v1.0.1/image.html + + def __init__(self, *args, **kwargs): + # Depending on the number of arguments + # in constructor, it treat args differently. + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_CREATION) + if len(args) == 0: + # default constructor + self.__LED = self.__string_to_square_array(CONSTANTS.BLANK_5X5) + elif len(args) == 1: + pattern = args[0] + if isinstance(pattern, str): + self.__LED = self.__string_to_square_array(pattern) + else: + raise TypeError("Image(s) takes a string") + else: + + width = args[0] + height = args[1] + + if width < 0 or height < 0: + # This is not in original, but ideally, + # image should fail non-silently + raise ValueError(CONSTANTS.INDEX_ERR) + + if len(args) == 3: + # This option is for potential third bytearray arguments + byte_arr = args[2] + self.__LED = self.__bytes_to_array(width, height, byte_arr) + else: + self.__LED = self.__create_leds(width, height) + self.read_only = False + + def width(self): + """ + Return the number of columns in the image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + if len(self.__LED) > 0: + return len(self.__LED[0]) + else: + return 0 + + def height(self): + """ + Return the numbers of rows in the image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return len(self.__LED) + + def set_pixel(self, x, y, value): + """ + Set the brightness of the pixel at column ``x`` and row ``y`` to the + ``value``, which has to be between 0 (dark) and 9 (bright). + + This method will raise an exception when called on any of the built-in + read-only images, like ``Image.HEART``. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + if self.read_only: + raise TypeError(CONSTANTS.COPY_ERR_MESSAGE) + elif not self.__valid_pos(x, y): + raise ValueError(CONSTANTS.INDEX_ERR) + elif not self.__valid_brightness(value): + raise ValueError(CONSTANTS.BRIGHTNESS_ERR) + else: + self.__LED[y][x] = value + + def get_pixel(self, x, y): + """ + Return the brightness of pixel at column ``x`` and row ``y`` as an + integer between 0 and 9. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + if self.__valid_pos(x, y): + return self.__LED[y][x] + else: + raise ValueError(CONSTANTS.INDEX_ERR) + + def shift_up(self, n): + """ + Return a new image created by shifting the picture up by ``n`` rows. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return self.__shift_vertical(-n) + + def shift_down(self, n): + """ + Return a new image created by shifting the picture down by ``n`` rows. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return self.__shift_vertical(n) + + def shift_right(self, n): + """ + Return a new image created by shifting the picture right by ``n`` + columns. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return self.__shift_horizontal(n) + + def shift_left(self, n): + """ + Return a new image created by shifting the picture left by ``n`` + columns. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return self.__shift_horizontal(-n) + + def crop(self, x, y, w, h): + """ + Return a new image by cropping the picture to a width of ``w`` and a + height of ``h``, starting with the pixel at column ``x`` and row ``y``. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + res = Image(w, h) + res.blit(self, x, y, w, h) + return res + + def copy(self): + """ + Return an exact copy of the image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + return Image(self.__create_string()) + + # This inverts the brightness of each LED. + # ie: Pixel that is at brightness 4 would become brightness 5 + # and pixel that is at brightness 9 would become brightness 0. + def invert(self): + """ + Return a new image by inverting the brightness of the pixels in the + source image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + for y in range(self.height()): + for x in range(self.width()): + self.set_pixel(x, y, CONSTANTS.BRIGHTNESS_MAX - self.get_pixel(x, y)) + + # This fills all LEDs with same brightness. + def fill(self, value): + """ + Set the brightness of all the pixels in the image to the + ``value``, which has to be between 0 (dark) and 9 (bright). + + This method will raise an exception when called on any of the built-in + read-only images, like ``Image.HEART``. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + for y in range(self.height()): + for x in range(self.width()): + self.set_pixel(x, y, value) + + # This transposes a certain area (w x h) on src onto the current image. + def blit(self, src, x, y, w, h, xdest=0, ydest=0): + """ + Copy the rectangle defined by ``x``, ``y``, ``w``, ``h`` from the image ``src`` into + this image at ``xdest``, ``ydest``. + Areas in the source rectangle, but outside the source image are treated as having a value of 0. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + if not src.__valid_pos(x, y): + raise ValueError(CONSTANTS.INDEX_ERR) + + for count_y in range(h): + for count_x in range(w): + if self.__valid_pos(xdest + count_x, ydest + count_y): + if src.__valid_pos(x + count_x, y + count_y): + transfer_pixel = src.get_pixel(x + count_x, y + count_y) + else: + transfer_pixel = 0 + self.set_pixel(xdest + count_x, ydest + count_y, transfer_pixel) + + # This adds two images (if other object is not an image, throws error). + # The images must be the same size. + def __add__(self, other): + """ + Create a new image by adding the brightness values from the two images for each pixel. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + if not isinstance(other, Image): + raise TypeError( + CONSTANTS.UNSUPPORTED_ADD_TYPE + f"'{type(self)}', '{type(other)}'" + ) + elif not (other.height() == self.height() and other.width() == self.width()): + raise ValueError(CONSTANTS.SAME_SIZE_ERR) + else: + res = Image(self.width(), self.height()) + + for y in range(self.height()): + for x in range(self.width()): + sum_value = other.get_pixel(x, y) + self.get_pixel(x, y) + display_result = min(CONSTANTS.BRIGHTNESS_MAX, sum_value) + res.set_pixel(x, y, display_result) + + return res + + # This multiplies image by number (if other factor is not a number, it throws an error). + def __mul__(self, other): + """ + Create a new image by multiplying the brightness of each pixel by n. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + try: + float_val = float(other) + except TypeError: + raise TypeError(f"can't convert {type(other)} to float") + + res = Image(self.width(), self.height()) + + for y in range(self.height()): + for x in range(self.width()): + product = self.get_pixel(x, y) * float_val + res.set_pixel(x, y, min(CONSTANTS.BRIGHTNESS_MAX, product)) + + return res + + def __repr__(self): + """ + Get a compact string representation of the image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + ret_str = "Image('" + for index_y in range(self.height()): + ret_str += self.__row_to_str(index_y) + + ret_str += "')" + + return ret_str + + def __str__(self): + """ + Get a readable string representation of the image. + """ + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) + ret_str = "Image('\n" + for index_y in range(self.height()): + ret_str += "\t" + self.__row_to_str(index_y) + "\n" + + ret_str += "')" + + return ret_str + + # HELPER FUNCTIONS + + # This create 2D array of off LEDs with + # width w and height h + def __create_leds(self, w, h): + arr = [] + for _ in range(h): + sub_arr = [] + for _ in range(w): + sub_arr.append(0) + arr.append(sub_arr) + + return arr + + # This turns byte array to 2D array for LED field. + def __bytes_to_array(self, width, height, byte_arr): + bytes_translated = bytes(byte_arr) + + if not len(bytes_translated) == height * width: + raise ValueError(CONSTANTS.INCORR_IMAGE_SIZE) + + arr = [] + sub_arr = [] + + for index, elem in enumerate(bytes_translated): + if index % width == 0 and index != 0: + arr.append(sub_arr) + sub_arr = [] + + sub_arr.append(elem) + + arr.append(sub_arr) + return arr + + # This converts string (with different rows separated by ":") + # to 2d array arrangement. + def __string_to_square_array(self, pattern): + initial_array, max_subarray_len = self.__string_directly_to_array(pattern) + + # Fill in empty spaces in w x h matrix. + for arr_y in initial_array: + num_extra_spaces = max_subarray_len - len(arr_y) + for _ in range(num_extra_spaces): + arr_y.append(0) + + return initial_array + + def __string_directly_to_array(self, pattern): + # The result may have spaces in the 2D array + # and may uneven sub-array lengths + arr = [] + sub_arr = [] + + max_subarray_len = 0 + + for elem in pattern: + if elem == ":" or elem == "\n": + if len(sub_arr) > max_subarray_len: + max_subarray_len = len(sub_arr) + arr.append(sub_arr) + sub_arr = [] + else: + sub_arr.append(int(elem)) + + if ( + len(pattern) > 0 + and not str(pattern)[-1] == ":" + and not str(pattern)[-1] == "\n" + and len(sub_arr) != 0 + ): + if len(sub_arr) > max_subarray_len: + max_subarray_len = len(sub_arr) + arr.append(sub_arr) + + return arr, max_subarray_len + + def __valid_brightness(self, value): + return value >= CONSTANTS.BRIGHTNESS_MIN and value <= CONSTANTS.BRIGHTNESS_MAX + + def __valid_pos(self, x, y): + return x >= 0 and x < self.width() and y >= 0 and y < self.height() + + def __shift_vertical(self, n): + res = Image(self.width(), self.height()) + + if n > 0: + # down + res.blit(self, 0, 0, self.width(), self.height() - n, 0, n) + else: + # up + if self.__valid_pos(0, abs(n)): + res.blit(self, 0, abs(n), self.width(), self.height() - abs(n), 0, 0) + + return res + + def __shift_horizontal(self, n): + res = Image(self.width(), self.height()) + if n > 0: + # right + res.blit(self, 0, 0, self.width() - n, self.height(), n, 0) + else: + # left + if self.__valid_pos(abs(n), 0): + res.blit(self, abs(n), 0, self.width() - abs(n), self.height(), 0, 0) + + return res + + def __create_string(self): + ret_str = "" + for index_y in range(self.height()): + ret_str += self.__row_to_str(index_y) + return ret_str + + def __row_to_str(self, y): + new_str = "" + for x in range(self.width()): + new_str += str(self.get_pixel(x, y)) + + new_str += ":" + + return new_str + + @staticmethod + def __append_images(images): + width = 0 + height = 0 + for image in images: + width += image.width() + height = max(height, image.height()) + res = Image(width, height) + x_ind = 0 + for image in images: + res.blit(image, 0, 0, image.width(), image.height(), xdest=x_ind) + x_ind += image.width() + return res + + @staticmethod + def __same_image(i1, i2): + if i1.width() != i2.width() or i1.height() != i2.height(): + return False + for y in range(i1.height()): + for x in range(i1.width()): + if i1.get_pixel(x, y) != i2.get_pixel(x, y): + return False + return True + + +# This is for generating functions like Image.HEART +# that return a new read-only Image +def create_const_func(func_name): + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_STATIC) + + def func(*args): + const_instance = Image(CONSTANTS.IMAGE_PATTERNS[func_name]) + const_instance.read_only = True + return const_instance + + func.__name__ = func_name + return ProducerProperty(func) + + +# for attributes like Image.ALL_CLOCKS +# that return tuples +def create_const_list_func(func_name): + def func(*args): + collection_names = CONSTANTS.IMAGE_TUPLE_LOOKUP[func_name] + ret_list = [] + for image_name in collection_names: + const_instance = Image(CONSTANTS.IMAGE_PATTERNS[image_name]) + const_instance.read_only = True + ret_list.append(const_instance) + + return tuple(ret_list) + + func.__name__ = func_name + return ProducerProperty(func) + + +for name in CONSTANTS.IMAGE_PATTERNS.keys(): + setattr(Image, name, create_const_func(name)) + +for name in CONSTANTS.IMAGE_TUPLE_LOOKUP.keys(): + setattr(Image, name, create_const_list_func(name)) diff --git a/src/microbit/__model/microbit_model.py b/src/microbit/__model/microbit_model.py new file mode 100644 index 000000000..e1bbb8971 --- /dev/null +++ b/src/microbit/__model/microbit_model.py @@ -0,0 +1,78 @@ +import time + +from .accelerometer import Accelerometer +from .button import Button +from .display import Display +from . import constants as CONSTANTS + + +class MicrobitModel: + def __init__(self): + # State in the Python process + self.accelerometer = Accelerometer() + self.button_a = Button() + self.button_b = Button() + self.display = Display() + + self.__start_time = time.time() + self.__temperature = 0 + self.__microbit_button_dict = { + "button_a": self.button_a, + "button_b": self.button_b, + } + + def sleep(self, n): + time.sleep(n / 1000) + + def running_time(self): + print(f"time. time: {time.time()}") + return time.time() - self.__start_time + + def temperature(self): + return self.__temperature + + def __set_temperature(self, temperature): + if ( + temperature < CONSTANTS.MIN_TEMPERATURE + or temperature > CONSTANTS.MAX_TEMPERATURE + ): + raise ValueError(CONSTANTS.INVALID_TEMPERATURE_ERR) + else: + self.__temperature = temperature + + def update_state(self, new_state): + self.__update_buttons(new_state) + self.__update_motion(new_state) + self.__update_light(new_state) + self.__update_temp(new_state) + + # helpers + def __update_buttons(self, new_state): + # get button pushes + for button_name in CONSTANTS.EXPECTED_INPUT_BUTTONS: + button = self.__microbit_button_dict[button_name] + button._Button__update(new_state.get(button_name)) + + def __update_motion(self, new_state): + # set motion_x, motion_y, motion_z + for name, direction in CONSTANTS.EXPECTED_INPUT_ACCEL.items(): + self.accelerometer._Accelerometer__update(direction, new_state.get(name)) + + def __update_light(self, new_state): + # set light level + new_light_level = new_state.get(CONSTANTS.EXPECTED_INPUT_LIGHT) + self.display._Display__update_light_level(new_light_level) + + def __update_temp(self, new_state): + # set temperature + new_temp = new_state.get(CONSTANTS.EXPECTED_INPUT_TEMP) + if new_temp is not None: + previous_temp = self.temperature() + if new_temp != previous_temp: + self._MicrobitModel__set_temperature(new_temp) + + def __set_debug_mode(self, mode): + self.display._Display__debug_mode = mode + + +__mb = MicrobitModel() diff --git a/src/microbit/__model/producer_property.py b/src/microbit/__model/producer_property.py new file mode 100644 index 000000000..6a6ed593a --- /dev/null +++ b/src/microbit/__model/producer_property.py @@ -0,0 +1,3 @@ +class ProducerProperty(property): + def __get__(self, cls, owner): + return classmethod(self.fget).__get__(cls, owner)() diff --git a/src/microbit/test/__init__.py b/src/microbit/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/microbit/test/test_accelerometer.py b/src/microbit/test/test_accelerometer.py new file mode 100644 index 000000000..0e654727c --- /dev/null +++ b/src/microbit/test/test_accelerometer.py @@ -0,0 +1,104 @@ +import pytest +from unittest import mock + +from ..__model.accelerometer import Accelerometer +from ..__model import constants as CONSTANTS + + +class TestAccelerometer(object): + def setup_method(self): + self.accelerometer = Accelerometer() + + @pytest.mark.parametrize( + "accel", + [ + CONSTANTS.MIN_ACCELERATION, + CONSTANTS.MIN_ACCELERATION + 1, + 100, + CONSTANTS.MAX_ACCELERATION - 1, + CONSTANTS.MAX_ACCELERATION, + ], + ) + def test_x_y_z(self, accel): + self.accelerometer._Accelerometer__set_accel("x", accel) + assert accel == self.accelerometer.get_x() + self.accelerometer._Accelerometer__set_accel("y", accel) + assert accel == self.accelerometer.get_y() + self.accelerometer._Accelerometer__set_accel("z", accel) + assert accel == self.accelerometer.get_z() + + @pytest.mark.parametrize("axis", ["x", "y", "z"]) + def test_x_y_z_invalid_accel(self, axis): + with pytest.raises(ValueError): + self.accelerometer._Accelerometer__set_accel( + axis, CONSTANTS.MAX_ACCELERATION + 1 + ) + with pytest.raises(ValueError): + self.accelerometer._Accelerometer__set_accel( + axis, CONSTANTS.MIN_ACCELERATION - 1 + ) + + @pytest.mark.parametrize( + "accels", + [ + (23, 25, 26), + (204, 234, -534), + (CONSTANTS.MIN_ACCELERATION + 10, 234, CONSTANTS.MAX_ACCELERATION), + ], + ) + def test_get_values(self, accels): + self.accelerometer._Accelerometer__set_accel("x", accels[0]) + self.accelerometer._Accelerometer__set_accel("y", accels[1]) + self.accelerometer._Accelerometer__set_accel("z", accels[2]) + assert accels == self.accelerometer.get_values() + + @pytest.mark.parametrize("gesture", ["up", "face down", "freefall", "8g"]) + def test_current_gesture(self, gesture): + self.accelerometer._Accelerometer__set_gesture(gesture) + assert gesture == self.accelerometer.current_gesture() + + @pytest.mark.parametrize("gesture", ["up", "face down", "freefall", "8g"]) + def test_is_gesture(self, gesture): + self.accelerometer._Accelerometer__set_gesture(gesture) + assert self.accelerometer.is_gesture(gesture) + for g in CONSTANTS.GESTURES: + if g != gesture: + assert not self.accelerometer.is_gesture(g) + + def test_is_gesture_error(self): + with pytest.raises(ValueError): + self.accelerometer.is_gesture("sideways") + + def test_was_gesture(self): + mock_gesture_up = "up" + mock_gesture_down = "down" + + assert not self.accelerometer.was_gesture(mock_gesture_up) + self.accelerometer._Accelerometer__set_gesture(mock_gesture_up) + self.accelerometer.current_gesture() # Call is needed for gesture detection so it can be added to the lists. + self.accelerometer._Accelerometer__set_gesture("") + assert self.accelerometer.was_gesture(mock_gesture_up) + assert not self.accelerometer.was_gesture(mock_gesture_up) + + def test_was_gesture_error(self): + with pytest.raises(ValueError): + self.accelerometer.was_gesture("sideways") + + def test_get_gestures(self): + mock_gesture_up = "up" + mock_gesture_down = "down" + mock_gesture_freefall = "freefall" + + self.accelerometer._Accelerometer__set_gesture(mock_gesture_up) + self.accelerometer.current_gesture() # Call is needed for gesture detection so it can be added to the lists. + self.accelerometer._Accelerometer__set_gesture(mock_gesture_down) + self.accelerometer.current_gesture() + self.accelerometer._Accelerometer__set_gesture(mock_gesture_freefall) + self.accelerometer.current_gesture() + self.accelerometer._Accelerometer__set_gesture("") + assert ( + mock_gesture_up, + mock_gesture_down, + mock_gesture_freefall, + ) == self.accelerometer.get_gestures() + assert () == self.accelerometer.get_gestures() diff --git a/src/microbit/test/test_button.py b/src/microbit/test/test_button.py new file mode 100644 index 000000000..9e0b3cbcb --- /dev/null +++ b/src/microbit/test/test_button.py @@ -0,0 +1,46 @@ +import pytest +from ..__model.button import Button + + +class TestButton(object): + def setup_method(self): + self.button = Button() + + def test_press_down(self): + self.button._Button__press_down() + assert self.button._Button__presses == 1 + assert self.button._Button__pressed + assert self.button._Button__prev_pressed + self.button._Button__press_down() + assert self.button._Button__presses == 2 + assert self.button._Button__pressed + assert self.button._Button__prev_pressed + + def test_release(self): + self.button._Button__pressed = True + self.button._Button__prev_pressed = False + self.button._Button__release() + assert not self.button._Button__pressed + + def test_is_pressed(self): + assert not self.button.is_pressed() + self.button._Button__press_down() + assert self.button.is_pressed() + + def test_was_pressed(self): + assert not self.button.was_pressed() + self.button._Button__press_down() + self.button._Button__release() + assert self.button.was_pressed() + # Button resets __prev_pressed after was_pressed() is called. + assert not self.button.was_pressed() + + @pytest.mark.parametrize("presses", [1, 2, 4]) + def test_get_presses(self, presses): + assert 0 == self.button.get_presses() + for i in range(presses): + self.button._Button__press_down() + self.button._Button__release() + assert presses == self.button.get_presses() + # Presses is reset to 0 after get_presses() is called. + assert 0 == self.button.get_presses() diff --git a/src/microbit/test/test_display.py b/src/microbit/test/test_display.py new file mode 100644 index 000000000..06cc6609e --- /dev/null +++ b/src/microbit/test/test_display.py @@ -0,0 +1,185 @@ +import pytest +import threading +from unittest import mock +from common import utils + +from ..__model import constants as CONSTANTS +from ..__model.display import Display +from ..__model.image import Image + + +STR_A = "09900:90090:99990:90090:90090" +STR_QUESTION_MARK = "09990:90009:00990:00000:00900" +STR_EXCLAMATION_MARK = "09000:09000:09000:00000:09000:" +STR_SIX = "00090:00900:09990:90009:09990" + + +class TestDisplay(object): + def setup_method(self): + self.display = Display() + utils.send_to_simulator = mock.Mock() + + @pytest.mark.parametrize("x, y, brightness", [(1, 1, 4), (2, 3, 6), (4, 4, 9)]) + def test_set_and_get_pixel(self, x, y, brightness): + self.display.set_pixel(x, y, brightness) + assert brightness == self.display.get_pixel(x, y) + + @pytest.mark.parametrize("x, y", [(5, 0), (0, -1), (0, 5)]) + def test_get_pixel_error(self, x, y): + with pytest.raises(ValueError, match=CONSTANTS.INDEX_ERR): + self.display.get_pixel(x, y) + + @pytest.mark.parametrize( + "x, y, brightness, err_msg", + [ + (5, 0, 0, CONSTANTS.INDEX_ERR), + (0, -1, 0, CONSTANTS.INDEX_ERR), + (0, 0, -1, CONSTANTS.BRIGHTNESS_ERR), + ], + ) + def test_set_pixel_error(self, x, y, brightness, err_msg): + with pytest.raises(ValueError, match=err_msg): + self.display.set_pixel(x, y, brightness) + + def test_clear(self): + self.display.set_pixel(2, 3, 7) + self.display.set_pixel(3, 4, 6) + self.display.set_pixel(4, 4, 9) + assert not self.__is_clear() + self.display.clear() + assert self.__is_clear() + + def test_on_off(self): + self.display.on() + assert self.display.is_on() + self.display.off() + assert not self.display.is_on() + + def test_show_one_image(self): + img = Image() + img.set_pixel(0, 0, 8) + img.set_pixel(0, 1, 9) + img.set_pixel(0, 2, 7) + img.set_pixel(2, 2, 6) + self.display.show(img, delay=0) + assert Image._Image__same_image(img, self.display._Display__image) + + def test_show_different_size_image(self): + img = Image(3, 7) + img.set_pixel(1, 1, 9) + img.set_pixel(2, 6, 9) # Will not be on display + expected = Image(5, 5) + expected.set_pixel(1, 1, 9) + self.display.show(img, delay=0) + assert Image._Image__same_image(expected, self.display._Display__image) + + def test_show_smaller_image(self): + img = Image(2, 2) + img.set_pixel(1, 1, 9) + expected = Image(5, 5) + expected.set_pixel(1, 1, 9) + self.display.show(img, delay=0) + assert Image._Image__same_image(expected, self.display._Display__image) + + @pytest.mark.parametrize( + "value, expected_str", + [ + ("!", STR_EXCLAMATION_MARK), + ("A", STR_A), + (" ", CONSTANTS.BLANK_5X5), + (6, STR_SIX), + ("\x7F", STR_QUESTION_MARK), # Character is out of our ASCII range + ], + ) + def test_show_char(self, value, expected_str): + expected = Image(expected_str) + self.display.show(value, delay=0) + assert Image._Image__same_image(expected, self.display._Display__image) + + def test_show_char_with_clear(self): + image = Image(STR_EXCLAMATION_MARK) + self.display.show(image, delay=0, clear=True) + assert self.__is_clear() + + def test_show_iterable(self): + expected = Image(STR_A) + value = [Image(STR_EXCLAMATION_MARK), "A", "ab"] + self.display.show(value, delay=0) + assert Image._Image__same_image(expected, self.display._Display__image) + + def test_show_non_iterable(self): + with pytest.raises(TypeError): + self.display.show(TestDisplay()) + + def test_scroll(self): + self.display.scroll("a b") + self.__is_clear() + + def test_scroll_type_error(self): + with pytest.raises(TypeError): + self.display.scroll(["a", 1]) + + # Should change these threaded tests to test behaviour in the future + def test_show_threaded(self): + threading.Thread = mock.Mock() + self.display.show("a", delay=0, wait=False) + threading.Thread.assert_called_once() + + def test_scroll_threaded(self): + threading.Thread = mock.Mock() + self.display.scroll("test", delay=0, wait=False) + threading.Thread.assert_called_once() + + def test_get_array(self): + self.display.set_pixel(3, 3, 3) + self.display.off() + assert self.display._Display__get_array() == [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + ] + + self.display.on() + assert self.display._Display__get_array() == [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 3, 0], + [0, 0, 0, 0, 0], + ] + + # The second show call should immedaitely stop the first show call. + # Therefore the final result of display should be 6. + def test_async_tests(self): + self.display.show("MMMMMMMMMMMMMM", delay=100, wait=False) + self.display.show("6", delay=0) + assert Image._Image__same_image(Image(STR_SIX), self.display._Display__image) + + @pytest.mark.parametrize( + "light_level", + [ + CONSTANTS.MIN_LIGHT_LEVEL, + CONSTANTS.MIN_LIGHT_LEVEL + 1, + 100, + CONSTANTS.MAX_LIGHT_LEVEL - 1, + CONSTANTS.MAX_LIGHT_LEVEL, + ], + ) + def test_light_level(self, light_level): + self.display._Display__set_light_level(light_level) + assert light_level == self.display.read_light_level() + + @pytest.mark.parametrize( + "invalid_light_level", + [CONSTANTS.MIN_LIGHT_LEVEL - 1, CONSTANTS.MAX_LIGHT_LEVEL + 1], + ) + def test_invalid_light_level(self, invalid_light_level): + with pytest.raises(ValueError): + self.display._Display__set_light_level(invalid_light_level) + + # Helpers + def __is_clear(self): + i = Image(CONSTANTS.BLANK_5X5) + return Image._Image__same_image(i, self.display._Display__image) diff --git a/src/microbit/test/test_image.py b/src/microbit/test/test_image.py new file mode 100644 index 000000000..c4d2731d6 --- /dev/null +++ b/src/microbit/test/test_image.py @@ -0,0 +1,283 @@ +import pytest +from ..__model.image import Image + +from ..__model import constants as CONSTANTS + + +class TestImage(object): + def setup_method(self): + self.image = Image() + self.image_heart = Image(CONSTANTS.IMAGE_PATTERNS["HEART"]) + + @pytest.mark.parametrize("x, y, brightness", [(1, 1, 4), (2, 3, 6), (4, 4, 9)]) + def test_get_set_pixel(self, x, y, brightness): + self.image.set_pixel(x, y, brightness) + assert brightness == self.image.get_pixel(x, y) + + @pytest.mark.parametrize("x, y", [(5, 0), (0, -1), (0, 5)]) + def test_get_pixel_error(self, x, y): + with pytest.raises(ValueError, match=CONSTANTS.INDEX_ERR): + self.image.get_pixel(x, y) + + @pytest.mark.parametrize( + "x, y, brightness, err_msg", + [ + (5, 0, 0, CONSTANTS.INDEX_ERR), + (0, -1, 0, CONSTANTS.INDEX_ERR), + (0, 0, -1, CONSTANTS.BRIGHTNESS_ERR), + ], + ) + def test_set_pixel_error(self, x, y, brightness, err_msg): + with pytest.raises(ValueError, match=err_msg): + self.image.set_pixel(x, y, brightness) + + @pytest.mark.parametrize( + "image, height, width", + [ + (Image(), 5, 5), + (Image(3, 3), 3, 3), + (Image(""), 0, 0), + (Image("00:00000"), 2, 5), + (Image("0000:0000"), 2, 4), + ], + ) + def test_width_and_height(self, image, height, width): + print(str(image)) + assert image.height() == height + assert image.width() == width + + @pytest.mark.parametrize( + "x, y, w, h, x_dest, y_dest, actual", + [ + (0, 0, 3, 2, 2, 1, Image("00000:00090:00999:00000:00000:")), + (0, 0, 3, 3, 8, 8, Image("00000:00000:00000:00000:00000:")), + (3, 0, 3, 3, 0, 0, Image("90000:99000:99000:00000:00000:")), + (3, 0, 7, 7, 0, 0, Image("90000:99000:99000:90000:00000:")), + ], + ) + def test_blit_heart(self, x, y, w, h, x_dest, y_dest, actual): + result = Image() + result.blit(self.image_heart, x, y, w, h, x_dest, y_dest) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "x, y, w, h, x_dest, y_dest, actual", + [ + (1, 1, 2, 4, 3, 3, Image("09090:99999:99999:09999:00999:")), + (0, 0, 3, 3, 8, 8, Image(CONSTANTS.IMAGE_PATTERNS["HEART"])), + (0, 0, 7, 7, 0, 0, Image(CONSTANTS.IMAGE_PATTERNS["HEART"])), + (3, 0, 7, 7, 0, 0, Image("90000:99000:99000:90000:00000:")), + ], + ) + def test_blit_heart_nonblank(self, x, y, w, h, x_dest, y_dest, actual): + result = Image(CONSTANTS.IMAGE_PATTERNS["HEART"]) + src = Image(CONSTANTS.IMAGE_PATTERNS["HEART"]) + result.blit(src, x, y, w, h, x_dest, y_dest) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "x, y, w, h, x_dest, y_dest", [(5, 6, 2, 4, 3, 3), (5, 0, 3, 3, 8, 8)] + ) + def test_blit_heart_valueerror(self, x, y, w, h, x_dest, y_dest): + result = Image(CONSTANTS.IMAGE_PATTERNS["HEART"]) + with pytest.raises(ValueError, match=CONSTANTS.INDEX_ERR): + result.blit(self.image_heart, x, y, w, h, x_dest, y_dest) + + @pytest.mark.parametrize( + "image1, image2", [(Image(2, 2, bytearray([4, 4, 4, 4])), Image("44:44"))] + ) + def test_constructor_bytearray(self, image1, image2): + assert image1._Image__LED == image2._Image__LED + + @pytest.mark.parametrize( + "x, y, w, h, actual", [(1, 1, 2, 4, Image("99:99:99:09:"))] + ) + def test_crop_heart(self, x, y, w, h, actual): + result = self.image_heart.crop(1, 1, 2, 4) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, actual", [(Image("99:99:99:00:"), Image("22:22:22:22:"))] + ) + def test_fill(self, target, actual): + target.fill(2) + assert target._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, actual", [(Image("012:345:678:900:"), Image("987:654:321:099:"))] + ) + def test_invert(self, target, actual): + target.invert() + assert target._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, value, actual", + [ + (Image("012:345:678:900:"), 1, Image("001:034:067:090:")), + (Image("012:345:678:900:"), 6, Image("000:000:000:000:")), + (Image("012:345:678:900:"), -1, Image("120:450:780:000:")), + ], + ) + def test_shift_right(self, target, value, actual): + result = target.shift_right(value) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, value, actual", + [ + (Image("012:345:678:900:"), 2, Image("200:500:800:000:")), + (Image("012:345:678:900:"), 6, Image("000:000:000:000:")), + (Image("012:345:678:900:"), -2, Image("000:003:006:009:")), + ], + ) + def test_shift_left(self, target, value, actual): + result = target.shift_left(value) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, value, actual", + [ + (Image("012:345:678:900:"), 2, Image("678:900:000:000:")), + (Image("012:345:678:900:"), 6, Image("000:000:000:000:")), + (Image("012:345:678:900:"), -2, Image("000:000:012:345:")), + ], + ) + def test_shift_up(self, target, value, actual): + result = target.shift_up(value) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, value, actual", + [ + (Image("012:345:678:900:"), 1, Image("000:012:345:678")), + (Image("012:345:678:900:"), 6, Image("000:000:000:000:")), + (Image("012:345:678:900:"), -1, Image("345:678:900:000:")), + ], + ) + def test_shift_down(self, target, value, actual): + result = target.shift_down(value) + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize("target", [(Image("012:345:678:900:"))]) + def test_copy(self, target): + result = target.copy() + assert result._Image__LED == target._Image__LED + + @pytest.mark.parametrize( + "target, multiplier, actual", + [ + (Image("012:345:678:900:"), 2, Image("024:689:999:900:")), + (Image("012:345:678:900:"), 0, Image("000:000:000:000:")), + ], + ) + def test_multiply(self, target, multiplier, actual): + result = target * multiplier + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, multiplier", + [ + (Image("012:345:678:900:"), []), + (Image("012:345:678:900:"), Image("000:000:000:000:")), + ], + ) + def test_multiply_error(self, target, multiplier): + + with pytest.raises( + TypeError, match=f"can't convert {type(multiplier)} to float" + ): + target * multiplier + + @pytest.mark.parametrize( + "target, value, actual", + [ + ( + Image("012:345:678:900:"), + Image("024:689:999:900:"), + Image("036:999:999:900:"), + ), + ( + Image("999:999:999:000:"), + Image("999:999:999:000:"), + Image("999:999:999:000:"), + ), + ], + ) + def test_add(self, target, value, actual): + result = target + value + assert result._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "target, value, err_message", + [ + ( + Image("012:345:678:900:"), + 2, + CONSTANTS.UNSUPPORTED_ADD_TYPE + f"'{type(Image())}', '{type(2)}'", + ), + ( + Image("012:345:678:900:"), + [], + CONSTANTS.UNSUPPORTED_ADD_TYPE + f"'{type(Image())}', '{type([])}'", + ), + ], + ) + def test_add_typeerror(self, target, value, err_message): + with pytest.raises(TypeError, match=err_message): + target + value + + @pytest.mark.parametrize( + "target, value", [(Image(2, 3), Image(3, 3)), (Image(2, 1), Image(0, 0))] + ) + def test_add_valueerror(self, target, value): + with pytest.raises(ValueError, match=CONSTANTS.SAME_SIZE_ERR): + target + value + + @pytest.mark.parametrize( + "initial, actual", + [ + (Image("0:000:00:0000:"), Image("0000:0000:0000:0000:")), + (Image("12125:1212:12:1:"), Image("12125:12120:12000:10000:")), + ], + ) + def test_uneven_strings(self, initial, actual): + assert initial._Image__LED == actual._Image__LED + + @pytest.mark.parametrize( + "image, repr_actual, str_actual", + [ + ( + Image("05150:05050:05050:99999:09990:"), + "Image('05150:05050:05050:99999:09990:')", + "Image('\n 05150:\n 05050:\n 05050:\n 99999:\n 09990:\n')", + ), + (Image(""), "Image('')", "Image('\n')"), + ( + Image("00000:00000:00000:00000:00000:"), + "Image('00000:00000:00000:00000:00000:')", + "Image('\n 00000:\n 00000:\n 00000:\n 00000:\n 00000:\n')", + ), + ( + Image("00:00:00:00:"), + "Image('00:00:00:00:')", + "Image('\n 00:\n 00:\n 00:\n 00:\n')", + ), + ], + ) + def test_str(self, image, repr_actual, str_actual): + repr_output = repr(image) + str_output = str(image) + assert repr_actual == repr_output + assert str_actual == str_output + + @pytest.mark.parametrize( + "const, actual", + [ + (Image.SNAKE, Image(CONSTANTS.IMAGE_PATTERNS["SNAKE"])), + (Image.PITCHFORK, Image(CONSTANTS.IMAGE_PATTERNS["PITCHFORK"])), + ], + ) + def test_image_constants(self, const, actual): + assert const._Image__LED == actual._Image__LED + with pytest.raises(TypeError, match=CONSTANTS.COPY_ERR_MESSAGE): + const.set_pixel(0, 0, 5) diff --git a/src/microbit/test/test_init.py b/src/microbit/test/test_init.py new file mode 100644 index 000000000..c6882ac75 --- /dev/null +++ b/src/microbit/test/test_init.py @@ -0,0 +1,45 @@ +import time + +import pytest +from unittest import mock + +from .. import * +from ..__model.microbit_model import MicrobitModel + +# tests methods in __init__.py + + +class TestShim(object): + def test_sleep(self): + # Save pointer to function about to be mocked + real_function = MicrobitModel.sleep + + milliseconds = 100 + MicrobitModel.sleep = mock.Mock() + sleep(milliseconds) + MicrobitModel.sleep.assert_called_with(milliseconds) + + # Restore original function + MicrobitModel.sleep = real_function + + def test_running_time(self): + # Save pointer to function about to be mocked + real_function = MicrobitModel.running_time + + MicrobitModel.running_time = mock.Mock() + running_time() + MicrobitModel.running_time.assert_called_once() + + # Restore original function + MicrobitModel.running_time = real_function + + def test_temperature(self): + # Save pointer to function about to be mocked + real_function = MicrobitModel.temperature + + MicrobitModel.temperature = mock.Mock() + temperature() + MicrobitModel.temperature.asser_called_once() + + # Restore original function + MicrobitModel.temperature = real_function diff --git a/src/microbit/test/test_microbit_model.py b/src/microbit/test/test_microbit_model.py new file mode 100644 index 000000000..1577bf24a --- /dev/null +++ b/src/microbit/test/test_microbit_model.py @@ -0,0 +1,48 @@ +import time + +import pytest +from unittest import mock +from ..__model import constants as CONSTANTS +from ..__model.microbit_model import MicrobitModel + + +class TestMicrobitModel(object): + def setup_method(self): + self.__mb = MicrobitModel() + + @pytest.mark.parametrize("value", [9, 30, 1999]) + def test_sleep(self, value): + time.sleep = mock.Mock() + self.__mb.sleep(value) + time.sleep.assert_called_with(value / 1000) + + def test_running_time(self): + mock_start_time = 10 + mock_end_time = 300 + self.__mb._MicrobitModel__start_time = mock_start_time + time.time = mock.MagicMock(return_value=mock_end_time) + assert mock_end_time - mock_start_time == pytest.approx( + self.__mb.running_time() + ) + + @pytest.mark.parametrize( + "temperature", + [ + CONSTANTS.MIN_TEMPERATURE, + CONSTANTS.MIN_TEMPERATURE + 1, + 0, + CONSTANTS.MAX_TEMPERATURE - 1, + CONSTANTS.MAX_TEMPERATURE, + ], + ) + def test_temperature(self, temperature): + self.__mb._MicrobitModel__set_temperature(temperature) + assert temperature == self.__mb.temperature() + + @pytest.mark.parametrize( + "invalid_temperature", + [CONSTANTS.MIN_TEMPERATURE - 1, CONSTANTS.MAX_TEMPERATURE + 1], + ) + def test_invalid_temperature(self, invalid_temperature): + with pytest.raises(ValueError): + self.__mb._MicrobitModel__set_temperature(invalid_temperature) diff --git a/src/process_user_code.py b/src/process_user_code.py index 1991f9816..3349ce0a5 100644 --- a/src/process_user_code.py +++ b/src/process_user_code.py @@ -10,11 +10,10 @@ import traceback import python_constants as CONSTANTS from pathlib import Path +import check_python_dependencies -# Insert absolute path to python libraries into sys.path -abs_path_to_parent_dir = os.path.dirname(os.path.abspath(__file__)) -abs_path_to_lib = os.path.join(abs_path_to_parent_dir, CONSTANTS.PYTHON_LIBS_DIR) -sys.path.insert(0, abs_path_to_lib) +# will propagate errors if dependencies aren't sufficient +check_python_dependencies.check_for_dependencies() read_val = "" threads = [] @@ -28,8 +27,13 @@ sys.path.insert(0, abs_path_to_lib) # This import must happen after the sys.path is modified +from common.telemetry import telemetry_py + from adafruit_circuitplayground.express import cpx -from adafruit_circuitplayground.telemetry import telemetry_py +from adafruit_circuitplayground.constants import CPX + +from microbit.__model.microbit_model import __mb as mb +from microbit.__model.constants import MICROBIT # Handle User Inputs Thread @@ -38,15 +42,18 @@ def __init__(self): threading.Thread.__init__(self) def run(self): + device_dict = {CPX: cpx, MICROBIT: mb} while True: read_val = sys.stdin.readline() sys.stdin.flush() try: - new_state = json.loads(read_val) - for event in CONSTANTS.EXPECTED_INPUT_EVENTS: - cpx._Express__state[event] = new_state.get( - event, cpx._Express__state[event] - ) + new_state_message = json.loads(read_val) + device = new_state_message.get(CONSTANTS.ACTIVE_DEVICE_FIELD) + new_state = new_state_message.get(CONSTANTS.STATE_FIELD, {}) + if device in device_dict: + device_dict[device].update_state(new_state) + else: + raise Exception(CONSTANTS.DEVICE_NOT_IMPLEMENTED_ERROR) except Exception as e: print(CONSTANTS.ERROR_SENDING_EVENT, e, file=sys.stderr, flush=True) @@ -95,6 +102,7 @@ def execute_user_code(abs_path_to_code_file): user_code = threading.Thread(args=(sys.argv[1],), target=execute_user_code) telemetry_state = json.loads(sys.argv[2]) + telemetry_py._Telemetry__enable_telemetry = telemetry_state.get( CONSTANTS.ENABLE_TELEMETRY, True ) diff --git a/src/python_constants.py b/src/python_constants.py index a700a3143..1e8442d38 100644 --- a/src/python_constants.py +++ b/src/python_constants.py @@ -1,21 +1,15 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. +ACTIVE_DEVICE_FIELD = "active_device" + CPX_DRIVE_NAME = "CIRCUITPY" +DEPEND_ERR = 'The required dependencies aren\'t downloaded. Please use CTRL+SHIFT+P to open the command palette and select "Device Simulator Express: Install Extension Dependencies".' + +DEVICE_NOT_IMPLEMENTED_ERROR = "Device not implemented." + ENABLE_TELEMETRY = "enable_telemetry" -EXPECTED_INPUT_EVENTS = [ - "button_a", - "button_b", - "switch", - "temperature", - "light", - "shake", - "motion_x", - "motion_y", - "motion_z", - "touch", -] EXEC_COMMAND = "exec" ERROR_SENDING_EVENT = "Error trying to send event to the process : " @@ -35,10 +29,14 @@ NOT_SUPPORTED_OS = 'The OS "{}" not supported.' NOT_IMPLEMENTED_ERROR = "This method is not implemented by the simulator" -PYTHON_LIBS_DIR = "python_libs" +STATE_FIELD = "state" UTF_FORMAT = "utf-8" WINDOWS_OS = "win32" DEFAULT_PORT = "5577" + +CPX = "CPX" + +MICROBIT = "micro:bit" diff --git a/src/serialMonitor.ts b/src/serialMonitor.ts index 630154859..2fd01588f 100644 --- a/src/serialMonitor.ts +++ b/src/serialMonitor.ts @@ -77,7 +77,7 @@ export class SerialMonitor implements vscode.Disposable { STATUS_BAR_PRIORITY.PORT ); this._portsStatusBar.command = - "deviceSimulatorExpress.selectSerialPort"; + "deviceSimulatorExpress.cpx.selectSerialPort"; this._portsStatusBar.tooltip = "Select Serial Port"; this._portsStatusBar.show(); @@ -86,7 +86,7 @@ export class SerialMonitor implements vscode.Disposable { STATUS_BAR_PRIORITY.OPEN_PORT ); this._openPortStatusBar.command = - "deviceSimulatorExpress.openSerialMonitor"; + "deviceSimulatorExpress.cpx.openSerialMonitor"; this._openPortStatusBar.text = `$(plug)`; this._openPortStatusBar.tooltip = "Open Serial Monitor"; this._openPortStatusBar.show(); @@ -96,7 +96,7 @@ export class SerialMonitor implements vscode.Disposable { STATUS_BAR_PRIORITY.BAUD_RATE ); this._baudRateStatusBar.command = - "deviceSimulatorExpress.changeBaudRate"; + "deviceSimulatorExpress.cpx.changeBaudRate"; this._baudRateStatusBar.tooltip = "Baud Rate"; this._baudRateStatusBar.text = defaultBaudRate.toString(); this.updatePortListStatus(null); @@ -281,13 +281,13 @@ export class SerialMonitor implements vscode.Disposable { private updatePortStatus(isOpened: boolean) { if (isOpened) { this._openPortStatusBar.command = - "deviceSimulatorExpress.closeSerialMonitor"; + "deviceSimulatorExpress.cpx.closeSerialMonitor"; this._openPortStatusBar.text = `$(x)`; this._openPortStatusBar.tooltip = "Close Serial Monitor"; this._baudRateStatusBar.show(); } else { this._openPortStatusBar.command = - "deviceSimulatorExpress.openSerialMonitor"; + "deviceSimulatorExpress.cpx.openSerialMonitor"; this._openPortStatusBar.text = `$(plug)`; this._openPortStatusBar.tooltip = "Open Serial Monitor"; this._baudRateStatusBar.hide(); diff --git a/src/service/PopupService.ts b/src/service/PopupService.ts new file mode 100644 index 000000000..9bff8ba5b --- /dev/null +++ b/src/service/PopupService.ts @@ -0,0 +1,16 @@ +// import { Webview } from "vscode"; +import * as vscode from "vscode"; +import { LATEST_RELEASE_NOTE } from "../latest_release_note"; + +export class PopupService { + public static openReleaseNote() { + const panel = vscode.window.createWebviewPanel( + "releaseNote", + "Release Note", + vscode.ViewColumn.One, + {} + ); + + panel.webview.html = LATEST_RELEASE_NOTE; + } +} diff --git a/src/service/debuggerCommunicationService.ts b/src/service/debuggerCommunicationService.ts new file mode 100644 index 000000000..9a8c1d6f0 --- /dev/null +++ b/src/service/debuggerCommunicationService.ts @@ -0,0 +1,27 @@ +import { DebuggerCommunicationServer } from "../debuggerCommunicationServer"; + +export class DebuggerCommunicationService { + private currentDebuggerServer?: DebuggerCommunicationServer; + private previousDebuggerServerToDisconnect?: DebuggerCommunicationServer; + + public setCurrentDebuggerServer(debugServer: DebuggerCommunicationServer) { + this.currentDebuggerServer = debugServer; + } + // Used for restart and stop event + public resetCurrentDebuggerServer() { + if (this.currentDebuggerServer) { + this.currentDebuggerServer.closeConnection(); + } + this.previousDebuggerServerToDisconnect = this.currentDebuggerServer; + this.currentDebuggerServer = undefined; + } + public getCurrentDebuggerServer() { + return this.currentDebuggerServer; + } + // Only used for stop event + public handleStopEvent() { + if (this.previousDebuggerServerToDisconnect) { + this.previousDebuggerServerToDisconnect.disconnectFromPort(); + } + } +} diff --git a/src/service/messagingService.ts b/src/service/messagingService.ts new file mode 100644 index 000000000..9e37f20a8 --- /dev/null +++ b/src/service/messagingService.ts @@ -0,0 +1,26 @@ +import { Webview } from "vscode"; +import { VSCODE_MESSAGES_TO_WEBVIEW } from "../view/constants"; +export class MessagingService { + private currentWebviewTarget: Webview | undefined; + + public setWebview(webview: Webview) { + this.currentWebviewTarget = webview; + } + + // Send a message to webview if it exists + public sendMessageToWebview(debugCommand: string, state: Object) { + if (this.currentWebviewTarget) { + this.currentWebviewTarget.postMessage({ command: debugCommand }); + } + } + public sendStartMessage() { + this.currentWebviewTarget.postMessage({ + command: VSCODE_MESSAGES_TO_WEBVIEW.RUN_DEVICE, + }); + } + public sendPauseMessage() { + this.currentWebviewTarget.postMessage({ + command: VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE, + }); + } +} diff --git a/src/template.py b/src/templates/cpx_template.py similarity index 81% rename from src/template.py rename to src/templates/cpx_template.py index b32caaae0..3c118c7e9 100644 --- a/src/template.py +++ b/src/templates/cpx_template.py @@ -1,15 +1,16 @@ -"""Save your file as "code.py" or "main.py" to run on the actual device. - -Getting started with CPX and CircuitPython intro on: -https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library - -Find example code for CPX on: -https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples -""" - -# import CPX library -from adafruit_circuitplayground import cp - -while True: - # start your code here - pass +""" +Save your file as "code.py" or "main.py" to run on the actual device. + +Getting started with CPX and CircuitPython intro on: +https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library + +Find example code for CPX on: +https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples +""" + +# import CPX library +from adafruit_circuitplayground import cp + +while True: + # start your code here + pass diff --git a/src/templates/microbit_template.py b/src/templates/microbit_template.py new file mode 100644 index 000000000..3fe2da077 --- /dev/null +++ b/src/templates/microbit_template.py @@ -0,0 +1,9 @@ +""" +Get started with micro:bit and MicroPython on: +https://microbit-micropython.readthedocs.io/en/latest/. +""" + +from microbit import * + +while True: + display.scroll("Hello World!") diff --git a/src/view/App.spec.tsx b/src/view/App.spec.tsx new file mode 100644 index 000000000..66d6fc9d5 --- /dev/null +++ b/src/view/App.spec.tsx @@ -0,0 +1,28 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { IntlProvider } from "react-intl"; +import * as testRenderer from "react-test-renderer"; +import App from "./App"; + +describe("App component ", () => { + it("should render correctly", () => { + const component = testRenderer + .create( + + + + ) + .toJSON(); + expect(component).toMatchSnapshot(); + }); + it("should render without crashing", () => { + const div = document.createElement("div"); + ReactDOM.render( + + + , + div + ); + ReactDOM.unmountComponentAtNode(div); + }); +}); diff --git a/src/view/App.test.tsx b/src/view/App.test.tsx deleted file mode 100644 index 3822593f7..000000000 --- a/src/view/App.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; -import { IntlProvider } from "react-intl"; -import App from "./App"; - -it("renders without crashing", () => { - const div = document.createElement("div"); - ReactDOM.render( - - - , - div - ); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/src/view/App.tsx b/src/view/App.tsx index b52993907..eb9da7b02 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -1,21 +1,78 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -"use strict"; import * as React from "react"; import "./App.css"; -import Device from "./container/device/Device"; +import { + DEVICE_LIST_KEY, + VIEW_STATE, + VSCODE_MESSAGES_TO_WEBVIEW, +} from "./constants"; +import { Device } from "./container/device/Device"; +import { ViewStateContext } from "./context"; + +interface IState { + currentDevice: string; + viewState: VIEW_STATE; +} + +const defaultState = { + currentDevice: DEVICE_LIST_KEY.CPX, + viewState: VIEW_STATE.RUNNING, +}; + +class App extends React.Component<{}, IState> { + constructor() { + super({}); + this.state = defaultState; + } + componentDidMount() { + if (document.currentScript) { + const initialDevice = document.currentScript.getAttribute( + "initialDevice" + ); + + if (initialDevice) { + this.setState({ currentDevice: initialDevice }); + } + } + window.addEventListener("message", this.handleMessage); + } + componentWillUnmount() { + window.removeEventListener("message", this.handleMessage); + } -class App extends React.Component { render() { return (
- + + +
); } + + handleMessage = (event: any): void => { + const message = event.data; + + switch (message.command) { + case VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE: + if (message.active_device !== this.state.currentDevice) { + this.setState({ currentDevice: message.active_device }); + } + break; + case VSCODE_MESSAGES_TO_WEBVIEW.RUN_DEVICE: + this.setState({ viewState: VIEW_STATE.RUNNING }); + break; + case VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE: + this.setState({ viewState: VIEW_STATE.PAUSE }); + break; + } + }; } export default App; diff --git a/src/view/__snapshots__/App.spec.tsx.snap b/src/view/__snapshots__/App.spec.tsx.snap new file mode 100644 index 000000000..ac3521338 --- /dev/null +++ b/src/view/__snapshots__/App.spec.tsx.snap @@ -0,0 +1,4720 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`App component should render correctly 1`] = ` +
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+`; diff --git a/src/view/components/cpx/Cpx.spec.tsx b/src/view/components/cpx/Cpx.spec.tsx new file mode 100644 index 000000000..deb6da57d --- /dev/null +++ b/src/view/components/cpx/Cpx.spec.tsx @@ -0,0 +1,29 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { IntlProvider } from "react-intl"; +import * as testRenderer from "react-test-renderer"; +import { Cpx } from "./Cpx"; + +describe("Device component", () => { + it("should render correctly", () => { + const component = testRenderer + .create( + + + + ) + .toJSON(); + expect(component).toMatchSnapshot(); + }); + + it("should render without crashing", () => { + const div = document.createElement("div"); + ReactDOM.render( + + + , + div + ); + ReactDOM.unmountComponentAtNode(div); + }); +}); diff --git a/src/view/components/cpx/Cpx.tsx b/src/view/components/cpx/Cpx.tsx new file mode 100644 index 000000000..d91728fba --- /dev/null +++ b/src/view/components/cpx/Cpx.tsx @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import { CPX_TOOLBAR_ICON_ID } from "../../components/toolbar/SensorModalUtils"; +import ToolBar from "../../components/toolbar/ToolBar"; +import { SENSOR_LIST, VSCODE_MESSAGES_TO_WEBVIEW } from "../../constants"; +import * as TOOLBAR_SVG from "../../svgs/toolbar_svg"; +import Simulator from "./CpxSimulator"; + +// Component grouping the functionality for circuit playground express +const DEFAULT_STATE = { + sensors: { + [SENSOR_LIST.TEMPERATURE]: 0, + [SENSOR_LIST.LIGHT]: 0, + [SENSOR_LIST.MOTION_X]: 0, + [SENSOR_LIST.MOTION_Y]: 0, + [SENSOR_LIST.MOTION_Z]: 0, + }, +}; + +export class Cpx extends React.Component { + state = DEFAULT_STATE; + componentDidMount() { + window.addEventListener("message", this.handleMessage); + } + + componentWillUnmount() { + // Make sure to remove the DOM listener when the component is unmounted. + window.removeEventListener("message", this.handleMessage); + } + handleMessage = (event: any): void => { + const message = event.data; + + switch (message.command) { + case VSCODE_MESSAGES_TO_WEBVIEW.RESET: + this.setState({ ...DEFAULT_STATE }); + break; + } + }; + + render() { + return ( + + + + + ); + } + updateSensor = (sensor: SENSOR_LIST, value: number) => { + this.setState({ sensors: { ...this.state.sensors, [sensor]: value } }); + }; +} + +const CPX_TOOLBAR_BUTTONS: Array<{ label: any; image: any }> = [ + { + image: TOOLBAR_SVG.SLIDER_SWITCH_SVG, + label: CPX_TOOLBAR_ICON_ID.SWITCH, + }, + { + image: TOOLBAR_SVG.PUSH_BUTTON_SVG, + label: CPX_TOOLBAR_ICON_ID.PUSH_BUTTON, + }, + { + image: TOOLBAR_SVG.RED_LED_SVG, + label: CPX_TOOLBAR_ICON_ID.RED_LED, + }, + { + image: TOOLBAR_SVG.SOUND_SVG, + label: CPX_TOOLBAR_ICON_ID.SOUND, + }, + { + image: TOOLBAR_SVG.TEMPERATURE_SVG, + label: CPX_TOOLBAR_ICON_ID.TEMPERATURE, + }, + { + image: TOOLBAR_SVG.LIGHT_SVG, + label: CPX_TOOLBAR_ICON_ID.LIGHT, + }, + { + image: TOOLBAR_SVG.NEO_PIXEL_SVG, + label: CPX_TOOLBAR_ICON_ID.NEO_PIXEL, + }, + { + image: TOOLBAR_SVG.SPEAKER_SVG, + label: CPX_TOOLBAR_ICON_ID.SPEAKER, + }, + { + image: TOOLBAR_SVG.MOTION_SVG, + label: CPX_TOOLBAR_ICON_ID.MOTION, + }, + { + image: TOOLBAR_SVG.IR_SVG, + label: CPX_TOOLBAR_ICON_ID.IR, + }, + { + image: TOOLBAR_SVG.GPIO_SVG, + label: CPX_TOOLBAR_ICON_ID.GPIO, + }, +]; diff --git a/src/view/components/cpx/CpxImage.tsx b/src/view/components/cpx/CpxImage.tsx index 0c74dd936..ee3d02201 100644 --- a/src/view/components/cpx/CpxImage.tsx +++ b/src/view/components/cpx/CpxImage.tsx @@ -20,30 +20,59 @@ interface IProps { onMouseLeave: (button: HTMLElement, event: Event) => void; } -let firstTime = true; - -// Functional Component render -const CpxImage: React.FC = props => { - const svgElement = window.document.getElementById("cpx_svg"); - - if (svgElement) { - if (firstTime) { - initSvgStyle(svgElement, props.brightness); - setupButtons(props); - setupPins(props); - setupKeyPresses(props.onKeyEvent); - setupSwitch(props); - firstTime = false; +export class CpxImage extends React.Component { + componentDidMount() { + const svgElement = window.document.getElementById("cpx_svg"); + if (svgElement) { + initSvgStyle(svgElement, this.props.brightness); + setupButtons(this.props); + setupPins(this.props); + this.setupKeyPresses(this.props.onKeyEvent); + setupSwitch(this.props); + this.updateImage(); } - // Update Neopixels and red LED state - updateNeopixels(props); - updateRedLED(props.red_led); - updatePowerLED(props.on); - updateSwitch(props.switch); } + componentWillUnmount() { + window.document.removeEventListener("keydown", this.handleKeyDown); + window.document.removeEventListener("keyup", this.handleKeyUp); + } + componentDidUpdate() { + this.updateImage(); + } + setupKeyPresses = ( + onKeyEvent: (event: KeyboardEvent, active: boolean) => void + ) => { + window.document.addEventListener("keydown", this.handleKeyDown); + window.document.addEventListener("keyup", this.handleKeyUp); + }; - return CPX_SVG; -}; + handleKeyDown = (event: KeyboardEvent) => { + const keyEvents = [event.key, event.code]; + // Don't listen to keydown events for the switch, run button, restart button and enter key + if ( + !( + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.S) || + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) || + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.CAPITAL_R) || + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.ENTER) + ) + ) { + this.props.onKeyEvent(event, true); + } + }; + handleKeyUp = (event: KeyboardEvent) => { + this.props.onKeyEvent(event, false); + }; + render() { + return CPX_SVG; + } + private updateImage() { + updateNeopixels(this.props); + updateRedLED(this.props.red_led); + updatePowerLED(this.props.on); + updateSwitch(this.props.switch); + } +} const makeButton = ( g: SVGElement, @@ -308,32 +337,18 @@ const setupButton = (button: HTMLElement, className: string, props: IProps) => { } svgButton.onmousedown = e => props.onMouseDown(button, e); svgButton.onmouseup = e => props.onMouseUp(button, e); - svgButton.onkeydown = e => props.onKeyEvent(e, true); + svgButton.onkeydown = e => { + // ensure that the keydown is enter. + // Or else, if the key is a shortcut instead, + // it may register shortcuts twice + if (e.key === CONSTANTS.KEYBOARD_KEYS.ENTER) { + props.onKeyEvent(e, true); + } + }; svgButton.onkeyup = e => props.onKeyEvent(e, false); svgButton.onmouseleave = e => props.onMouseLeave(button, e); }; -const setupKeyPresses = ( - onKeyEvent: (event: KeyboardEvent, active: boolean) => void -) => { - window.document.addEventListener("keydown", event => { - const keyEvents = [event.key, event.code]; - // Don't listen to keydown events for the switch, run button and enter key - if ( - !( - keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.S) || - keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) || - keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.ENTER) - ) - ) { - onKeyEvent(event, true); - } - }); - window.document.addEventListener("keyup", event => - onKeyEvent(event, false) - ); -}; - const setupSwitch = (props: IProps): void => { const switchElement = window.document.getElementById("SWITCH"); const swInnerElement = window.document.getElementById("SWITCH_INNER"); diff --git a/src/view/components/Simulator.tsx b/src/view/components/cpx/CpxSimulator.tsx similarity index 91% rename from src/view/components/Simulator.tsx rename to src/view/components/cpx/CpxSimulator.tsx index a1ddee6b6..21a13524a 100644 --- a/src/view/components/Simulator.tsx +++ b/src/view/components/cpx/CpxSimulator.tsx @@ -2,14 +2,16 @@ // Licensed under the MIT license. import * as React from "react"; -import { CONSTANTS } from "../constants"; -import "../styles/Simulator.css"; -import PlayLogo from "../svgs/play_svg"; -import StopLogo from "../svgs/stop_svg"; -import { BUTTON_NEUTRAL, BUTTON_PRESSED } from "./cpx/Cpx_svg_style"; -import CpxImage, { updatePinTouch, updateSwitch } from "./cpx/CpxImage"; -import Dropdown from "./Dropdown"; -import ActionBar from "./simulator/ActionBar"; +import { CONSTANTS, DEVICE_LIST_KEY, WEBVIEW_MESSAGES } from "../../constants"; +import { sendMessage } from "../../utils/MessageUtils"; + +import "../../styles/Simulator.css"; +import PlayLogo from "../../svgs/play_svg"; +import StopLogo from "../../svgs/stop_svg"; +import Dropdown from "../Dropdown"; +import ActionBar from "../simulator/ActionBar"; +import { BUTTON_NEUTRAL, BUTTON_PRESSED } from "./Cpx_svg_style"; +import { CpxImage, updatePinTouch, updateSwitch } from "./CpxImage"; interface ICpxState { pixels: number[][]; @@ -29,9 +31,6 @@ interface IState { cpx: ICpxState; play_button: boolean; } -interface IMyProps { - children?: any; -} const DEFAULT_CPX_STATE: ICpxState = { brightness: 1.0, @@ -55,18 +54,8 @@ const DEFAULT_CPX_STATE: ICpxState = { shake: false, }; -interface vscode { - postMessage(message: any): void; -} - -declare const vscode: vscode; - -const sendMessage = (type: string, state: any) => { - vscode.postMessage({ command: type, text: state }); -}; - -class Simulator extends React.Component { - constructor(props: IMyProps) { +class Simulator extends React.Component<{}, IState> { + constructor(props: Readonly<{}>) { super(props); this.state = { active_editors: [], @@ -88,11 +77,13 @@ class Simulator extends React.Component { handleMessage = (event: any): void => { const message = event.data; // The JSON data our extension sent + if (message.active_device !== DEVICE_LIST_KEY.CPX) { + return; + } switch (message.command) { case "reset-state": console.log("Clearing the state"); this.setState({ - ...this.state, cpx: DEFAULT_CPX_STATE, play_button: false, }); @@ -102,14 +93,12 @@ class Simulator extends React.Component { "Setting the state: " + JSON.stringify(message.state) ); this.setState({ - ...this.state, cpx: message.state, play_button: true, }); break; case "activate-play": this.setState({ - ...this.state, play_button: !this.state.play_button, }); break; @@ -119,21 +108,15 @@ class Simulator extends React.Component { message.state.activePythonEditors ); this.setState({ - ...this.state, active_editors: message.state.activePythonEditors, }); break; case "current-file": console.log("Setting current file", message.state.running_file); this.setState({ - ...this.state, running_file: message.state.running_file, }); break; - default: - console.log("Invalid message received from the extension."); - this.setState({ ...this.state, cpx: DEFAULT_CPX_STATE }); - break; } }; @@ -149,6 +132,7 @@ class Simulator extends React.Component { render() { const playStopImage = this.state.play_button ? StopLogo : PlayLogo; + const playStopLabel = this.state.play_button ? "stop" : "play"; return (
@@ -178,37 +162,37 @@ class Simulator extends React.Component { onTogglePlay={this.togglePlayClick} onToggleRefresh={this.refreshSimulatorClick} playStopImage={playStopImage} + playStopLabel={playStopLabel} />
); } protected togglePlayClick() { - sendMessage("play-simulator", { - selected_file: this.state.selected_file, - state: !this.state.play_button, - }); const button = window.document.getElementById(CONSTANTS.ID_NAME.PLAY_BUTTON) || window.document.getElementById(CONSTANTS.ID_NAME.STOP_BUTTON); if (button) { button.focus(); } + sendMessage(WEBVIEW_MESSAGES.TOGGLE_PLAY_STOP, { + selected_file: this.state.selected_file, + state: !this.state.play_button, + }); } protected refreshSimulatorClick() { - sendMessage("refresh-simulator", true); const button = window.document.getElementById( CONSTANTS.ID_NAME.REFRESH_BUTTON ); if (button) { button.focus(); } + sendMessage(WEBVIEW_MESSAGES.REFRESH_SIMULATOR, true); } protected onSelectBlur(event: React.FocusEvent) { this.setState({ - ...this.state, selected_file: event.currentTarget.value, }); } @@ -234,6 +218,12 @@ class Simulator extends React.Component { element = window.document.getElementById( CONSTANTS.ID_NAME.BUTTON_B ); + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.C) + ) { + element = window.document.getElementById( + CONSTANTS.ID_NAME.BUTTON_AB + ); } else if ( [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.S) ) { diff --git a/src/view/components/cpx/Svg_utils.tsx b/src/view/components/cpx/Svg_utils.tsx index b80e66165..f190bffae 100644 --- a/src/view/components/cpx/Svg_utils.tsx +++ b/src/view/components/cpx/Svg_utils.tsx @@ -3,35 +3,44 @@ // Adapted from : https://github.com/microsoft/pxt/blob/master/pxtsim/svg.ts +// tslint:disable-next-line: no-namespace namespace svg { export function addClass(el: SVGElement, cls: string) { - if (el.classList) el.classList.add(cls); - else if (el.className.baseVal.indexOf(cls) < 0) + if (el.classList) { + el.classList.add(cls); + } else if (el.className.baseVal.indexOf(cls) < 0) { el.className.baseVal += " " + cls; + } } export function removeClass(el: SVGElement, cls: string) { - if (el.classList) el.classList.remove(cls); - else + if (el.classList) { + el.classList.remove(cls); + } else { el.className.baseVal = el.className.baseVal .replace(cls, "") .replace(/\s{2,}/, " "); + } } export function hydrate(el: SVGElement, props: any) { - for (let k in props) { + for (const k in props) { if (k == "title") { svg.title(el, props[k]); - } else el.setAttributeNS(null, k, props[k]); + } else { + el.setAttributeNS(null, k, props[k]); + } } } export function createElement(name: string, props?: any): SVGElement { - let newElement = document.createElementNS( + const newElement = document.createElementNS( "http://www.w3.org/2000/svg", name ); - if (props) svg.hydrate(newElement, props); + if (props) { + svg.hydrate(newElement, props); + } return newElement; } @@ -40,7 +49,7 @@ namespace svg { name: string, props?: any ): SVGElement { - let childElement = svg.createElement(name, props); + const childElement = svg.createElement(name, props); parent.appendChild(childElement); return childElement; } @@ -58,13 +67,13 @@ namespace svg { } export function mkTitle(txt: string): SVGTitleElement { - let t = svg.createElement("title") as SVGTitleElement; + const t = svg.createElement("title") as SVGTitleElement; t.textContent = txt; return t; } export function title(el: SVGElement, txt: string): SVGTitleElement { - let t = mkTitle(txt); + const t = mkTitle(txt); el.appendChild(t); return t; } diff --git a/src/view/components/cpx/__snapshots__/Cpx.spec.tsx.snap b/src/view/components/cpx/__snapshots__/Cpx.spec.tsx.snap new file mode 100644 index 000000000..2d51b191f --- /dev/null +++ b/src/view/components/cpx/__snapshots__/Cpx.spec.tsx.snap @@ -0,0 +1,4710 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Device component should render correctly 1`] = ` +Array [ +
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
, +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
, +] +`; diff --git a/src/view/components/microbit/Microbit.tsx b/src/view/components/microbit/Microbit.tsx new file mode 100644 index 000000000..03f11fed9 --- /dev/null +++ b/src/view/components/microbit/Microbit.tsx @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import { MICROBIT_TOOLBAR_ID } from "../../components/toolbar/SensorModalUtils"; +import { SENSOR_LIST, VSCODE_MESSAGES_TO_WEBVIEW } from "../../constants"; +import "../../styles/Simulator.css"; +import * as TOOLBAR_SVG from "../../svgs/toolbar_svg"; +import ToolBar from "../toolbar/ToolBar"; +import { MicrobitSimulator } from "./MicrobitSimulator"; + +// Component grouping the functionality for micro:bit functionalities +interface IState { + sensors: { [key: string]: number }; +} +const DEFAULT_STATE = { + sensors: { + [SENSOR_LIST.TEMPERATURE]: 0, + [SENSOR_LIST.LIGHT]: 0, + [SENSOR_LIST.MOTION_X]: 0, + [SENSOR_LIST.MOTION_Y]: 0, + [SENSOR_LIST.MOTION_Z]: 0, + }, +}; + +export class Microbit extends React.Component<{}, IState> { + state = DEFAULT_STATE; + + componentDidMount() { + window.addEventListener("message", this.handleMessage); + } + + componentWillUnmount() { + // Make sure to remove the DOM listener when the component is unmounted. + window.removeEventListener("message", this.handleMessage); + } + handleMessage = (event: any): void => { + const message = event.data; + + switch (message.command) { + case VSCODE_MESSAGES_TO_WEBVIEW.RESET: + this.setState({ ...DEFAULT_STATE }); + break; + } + }; + render() { + return ( + + + + + ); + } + updateSensor = (sensor: SENSOR_LIST, value: number) => { + this.setState({ sensors: { ...this.state.sensors, [sensor]: value } }); + }; +} + +const MICROBIT_TOOLBAR_BUTTONS: Array<{ label: string; image: JSX.Element }> = [ + { + image: TOOLBAR_SVG.PUSH_BUTTON_SVG, + label: MICROBIT_TOOLBAR_ID.PUSH_BUTTON, + }, + { + image: TOOLBAR_SVG.RED_LED_SVG, + label: MICROBIT_TOOLBAR_ID.LEDS, + }, + { + image: TOOLBAR_SVG.TEMPERATURE_SVG, + label: MICROBIT_TOOLBAR_ID.TEMPERATURE, + }, + { + image: TOOLBAR_SVG.LIGHT_SVG, + label: MICROBIT_TOOLBAR_ID.LIGHT, + }, + { + image: TOOLBAR_SVG.MOTION_SVG, + label: MICROBIT_TOOLBAR_ID.ACCELEROMETER, + }, +]; diff --git a/src/view/components/microbit/MicrobitImage.tsx b/src/view/components/microbit/MicrobitImage.tsx new file mode 100644 index 000000000..326d0a611 --- /dev/null +++ b/src/view/components/microbit/MicrobitImage.tsx @@ -0,0 +1,176 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import { VIEW_STATE } from "../../constants"; +import { ViewStateContext } from "../../context"; +import CONSTANTS, { MICROBIT_BUTTON_STYLING_CLASSES } from "../../constants"; +import "../../styles/Microbit.css"; +import { IRefObject, MicrobitSvg } from "./Microbit_svg"; + +interface EventTriggers { + onMouseUp: (event: Event, buttonKey: string) => void; + onMouseDown: (event: Event, buttonKey: string) => void; + onMouseLeave: (event: Event, buttonKey: string) => void; + onKeyEvent: (event: KeyboardEvent, active: boolean, key: string) => void; +} +interface IProps { + eventTriggers: EventTriggers; + leds: number[][]; +} + +const BUTTON_CLASSNAME = { + ACTIVE: "sim-button-outer", + DEACTIVATED: "sim-button-deactivated", +}; + +export enum BUTTONS_KEYS { + BTN_A = "BTN_A", + BTN_B = "BTN_B", + BTN_AB = "BTN_AB", +} +// Displays the SVG and call necessary svg modification. +export class MicrobitImage extends React.Component { + private svgRef: React.RefObject = React.createRef(); + constructor(props: IProps) { + super(props); + } + componentDidMount() { + const svgElement = this.svgRef.current; + if (svgElement) { + updateAllLeds(this.props.leds, svgElement.getLeds()); + setupAllButtons(this.props.eventTriggers, svgElement.getButtons()); + this.setupKeyPresses(this.props.eventTriggers.onKeyEvent); + } + } + componentDidUpdate() { + if (this.svgRef.current) { + updateAllLeds(this.props.leds, this.svgRef.current.getLeds()); + if (this.context === VIEW_STATE.PAUSE) { + disableAllButtons(this.svgRef.current.getButtons()); + } else if (this.context === VIEW_STATE.RUNNING) { + setupAllButtons( + this.props.eventTriggers, + this.svgRef.current.getButtons() + ); + } + } + } + componentWillUnmount() { + window.document.removeEventListener("keydown", this.handleKeyDown); + window.document.removeEventListener("keyup", this.handleKeyUp); + } + setupKeyPresses = ( + onKeyEvent: (event: KeyboardEvent, active: boolean, key: string) => void + ) => { + window.document.addEventListener("keydown", this.handleKeyDown); + window.document.addEventListener("keyup", this.handleKeyUp); + }; + handleKeyDown = (event: KeyboardEvent) => { + const keyEvents = [event.key, event.code]; + // Don't listen to keydown events for the run button, restart button and enter key + if ( + !( + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) || + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.CAPITAL_R) || + keyEvents.includes(CONSTANTS.KEYBOARD_KEYS.ENTER) + ) + ) { + this.props.eventTriggers.onKeyEvent(event, true, event.key); + } + }; + handleKeyUp = (event: KeyboardEvent) => { + this.props.eventTriggers.onKeyEvent(event, false, event.key); + }; + render() { + return ; + } + public updateButtonAttributes(key: BUTTONS_KEYS, isActive: boolean) { + if (this.svgRef.current) { + const button = this.svgRef.current.getButtons()[key].current; + if (button) { + button.focus(); + if (isActive) { + button.children[0].setAttribute( + "class", + MICROBIT_BUTTON_STYLING_CLASSES.KEYPRESSED + ); + } else { + button.children[0].setAttribute( + "class", + MICROBIT_BUTTON_STYLING_CLASSES.DEFAULT + ); + } + button.setAttribute("pressed", `${isActive}`); + button.setAttribute("aria-pressed", `${isActive}`); + } + } + } +} + +MicrobitImage.contextType = ViewStateContext; +const setupButton = ( + buttonElement: SVGRectElement, + eventTriggers: EventTriggers, + key: string +) => { + buttonElement.onmousedown = e => { + buttonElement.focus(); + eventTriggers.onMouseDown(e, key); + }; + buttonElement.onmouseup = e => { + eventTriggers.onMouseUp(e, key); + }; + buttonElement.onmouseleave = e => { + eventTriggers.onMouseLeave(e, key); + }; + buttonElement.onkeydown = e => { + // ensure that the keydown is enter, + // or else it may register shortcuts twice + if (e.key === CONSTANTS.KEYBOARD_KEYS.ENTER) { + eventTriggers.onKeyEvent(e, true, key); + } + }; + buttonElement.onkeyup = e => { + eventTriggers.onKeyEvent(e, false, key); + }; +}; +const setupAllButtons = ( + eventTriggers: EventTriggers, + buttonRefs: IRefObject +) => { + for (const [key, ref] of Object.entries(buttonRefs)) { + if (ref.current) { + setupButton(ref.current, eventTriggers, key); + } + } +}; +const disableAllButtons = (buttonRefs: IRefObject) => { + for (const [, ref] of Object.entries(buttonRefs)) { + if (ref.current) { + // to implement + ref.current.onmousedown = null; + ref.current.onmouseup = null; + ref.current.onmouseleave = null; + ref.current.onkeydown = null; + ref.current.onkeyup = null; + ref.current.setAttribute("class", BUTTON_CLASSNAME.DEACTIVATED); + } + } +}; +const updateAllLeds = ( + leds: number[][], + ledRefs: Array>> +) => { + for (let j = 0; j < leds.length; j++) { + for (let i = 0; i < leds[0].length; i++) { + const ledElement = ledRefs[j][i].current; + if (ledElement) { + setupLed(ledElement, leds[i][j]); + } + } + } +}; +const setupLed = (ledElement: SVGRectElement, brightness: number) => { + ledElement.style.opacity = (brightness / 10).toString(); +}; diff --git a/src/view/components/microbit/MicrobitSimulator.tsx b/src/view/components/microbit/MicrobitSimulator.tsx new file mode 100644 index 000000000..c05611396 --- /dev/null +++ b/src/view/components/microbit/MicrobitSimulator.tsx @@ -0,0 +1,253 @@ +import * as React from "react"; +import { + CONSTANTS, + DEVICE_LIST_KEY, + MICROBIT_BUTTONS_KEYS, + WEBVIEW_MESSAGES, +} from "../../constants"; +import PlayLogo from "../../svgs/play_svg"; +import StopLogo from "../../svgs/stop_svg"; +import { sendMessage } from "../../utils/MessageUtils"; +import Dropdown from "../Dropdown"; +import ActionBar from "../simulator/ActionBar"; +import { MicrobitImage, BUTTONS_KEYS } from "./MicrobitImage"; + +const DEFAULT_MICROBIT_STATE: IMicrobitState = { + leds: [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + ], + buttons: { button_a: false, button_b: false }, +}; + +interface IState { + active_editors: string[]; + running_file: string; + play_button: boolean; + selected_file: string; + microbit: IMicrobitState; +} + +interface IMicrobitState { + leds: number[][]; + buttons: { button_a: boolean; button_b: boolean }; +} +export class MicrobitSimulator extends React.Component { + private imageRef: React.RefObject = React.createRef(); + constructor() { + super({}); + this.state = { + microbit: DEFAULT_MICROBIT_STATE, + play_button: false, + selected_file: "", + active_editors: [], + running_file: "", + }; + this.onKeyEvent = this.onKeyEvent.bind(this); + } + handleMessage = (event: any): void => { + const message = event.data; + + if (message.active_device !== DEVICE_LIST_KEY.MICROBIT) { + return; + } + + switch (message.command) { + case "reset-state": + this.setState({ + microbit: DEFAULT_MICROBIT_STATE, + play_button: false, + }); + break; + case "set-state": + this.setState({ + microbit: { + ...this.state.microbit, + leds: message.state.leds, + }, + }); + break; + case "activate-play": + this.setState({ + play_button: !this.state.play_button, + }); + break; + case "visible-editors": + this.setState({ + active_editors: message.state.activePythonEditors, + }); + break; + case "current-file": + this.setState({ + running_file: message.state.running_file, + }); + break; + } + }; + componentDidMount() { + window.addEventListener("message", this.handleMessage); + } + componentWillUnmount() { + window.removeEventListener("message", this.handleMessage); + } + + render() { + const playStopImage = this.state.play_button ? StopLogo : PlayLogo; + const playStopLabel = this.state.play_button ? "stop" : "play"; + return ( +
+
+ +
+
+ +
+ +
+ ); + } + protected togglePlayClick = () => { + const button = + window.document.getElementById(CONSTANTS.ID_NAME.PLAY_BUTTON) || + window.document.getElementById(CONSTANTS.ID_NAME.STOP_BUTTON); + if (button) { + button.focus(); + } + sendMessage(WEBVIEW_MESSAGES.TOGGLE_PLAY_STOP, { + selected_file: this.state.selected_file, + state: !this.state.play_button, + }); + }; + protected onSelectFile(event: React.FocusEvent) { + this.setState({ + selected_file: event.currentTarget.value, + }); + } + protected refreshSimulatorClick = () => { + const button = window.document.getElementById( + CONSTANTS.ID_NAME.REFRESH_BUTTON + ); + if (button) { + button.focus(); + } + sendMessage(WEBVIEW_MESSAGES.REFRESH_SIMULATOR, true); + }; + protected handleButtonClick = (key: string, isActive: boolean) => { + let newButtonState = this.state.microbit.buttons; + switch (key) { + case MICROBIT_BUTTONS_KEYS.BTN_A: + newButtonState.button_a = isActive; + break; + case MICROBIT_BUTTONS_KEYS.BTN_B: + newButtonState.button_b = isActive; + break; + case MICROBIT_BUTTONS_KEYS.BTN_AB: + newButtonState = { + button_a: isActive, + button_b: isActive, + }; + break; + } + sendMessage(WEBVIEW_MESSAGES.BUTTON_PRESS, newButtonState); + this.setState({ + microbit: { + ...this.state.microbit, + buttons: newButtonState, + }, + }); + }; + protected onMouseUp = (event: Event, key: string) => { + event.preventDefault(); + this.handleButtonClick(key, false); + }; + protected onMouseDown = (event: Event, key: string) => { + event.preventDefault(); + this.handleButtonClick(key, true); + }; + protected onMouseLeave = (event: Event, key: string) => { + event.preventDefault(); + console.log(`To implement onMouseLeave ${key}`); + }; + protected onKeyEvent(event: KeyboardEvent, active: boolean, key: string) { + event.stopPropagation(); + if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.ENTER)) { + this.handleButtonClick(key, active); + if (this.imageRef.current) { + if (key === BUTTONS_KEYS.BTN_A) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_A, + active + ); + } else if (key === BUTTONS_KEYS.BTN_B) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_B, + active + ); + } else if (key === BUTTONS_KEYS.BTN_AB) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_AB, + active + ); + } + } + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.A) + ) { + this.handleButtonClick(BUTTONS_KEYS.BTN_A, active); + if (this.imageRef.current) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_A, + active + ); + } + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.B) + ) { + this.handleButtonClick(BUTTONS_KEYS.BTN_B, active); + if (this.imageRef.current) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_B, + active + ); + } + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.C) + ) { + this.handleButtonClick(BUTTONS_KEYS.BTN_AB, active); + if (this.imageRef.current) { + this.imageRef.current.updateButtonAttributes( + BUTTONS_KEYS.BTN_AB, + active + ); + } + } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) { + this.togglePlayClick(); + } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_R) { + this.refreshSimulatorClick(); + } + } +} diff --git a/src/view/components/microbit/Microbit_svg.tsx b/src/view/components/microbit/Microbit_svg.tsx new file mode 100644 index 000000000..e2e147412 --- /dev/null +++ b/src/view/components/microbit/Microbit_svg.tsx @@ -0,0 +1,1888 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Adapted from : https://makecode.microbit.org/#editor + +import * as React from "react"; +export interface IRefObject { + [key: string]: React.RefObject; +} +/* tslint:disable */ + +const N_LED_COLUMN = 5; +const N_LED_ROW = 5; +export class MicrobitSvg extends React.Component { + constructor(props: Readonly<{}>) { + super(props); + for (let j = 0; j < N_LED_ROW; j++) { + const led_row: React.RefObject[] = []; + for (let i = 0; i < N_LED_COLUMN; i++) { + led_row.push(React.createRef()); + } + this.ledRefs.push(led_row); + } + } + private svgRef: React.RefObject = React.createRef(); + + private buttonRefs: IRefObject = { + BTN_A: React.createRef(), + BTN_B: React.createRef(), + BTN_AB: React.createRef(), + }; + + private ledRefs: React.RefObject[][] = []; + public getSvgRef(): React.RefObject { + return this.svgRef; + } + public getButtons(): IRefObject { + return this.buttonRefs; + } + public getLeds(): React.RefObject[][] { + return this.ledRefs; + } + + render() { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (0,0) + + + + (1,0) + + + + (2,0) + + + + (3,0) + + + + (4,0) + + + + (0,1) + + + + (1,1) + + + + (2,1) + + + + (3,1) + + + + (4,1) + + + + (0,2) + + + + (1,2) + + + + (2,2) + + + + (3,2) + + + + (4,2) + + + + (0,3) + + + + (1,3) + + + + (2,3) + + + + (3,3) + + + + (4,3) + + + + (0,4) + + + + (1,4) + + + + (2,4) + + + + (3,4) + + + + (4,4) + + + + + + + + + + P0, ANALOG IN + + + P1, ANALOG IN + + + P2, ANALOG IN + + + P3, ANALOG IN, LED Col 1 + + + P4, ANALOG IN, LED Col 2 + + + P5, BUTTON A + + + P6, LED Col 9 + + + P7, LED Col 8 + + + P8 + + + P9, LED Col 7 + + + P10, ANALOG IN, LED Col 3 + + + P11, BUTTON B + + + P12, RESERVED ACCESSIBILITY + + + P13, SPI - SCK + + + P14, SPI - MISO + + + P15, SPI - MOSI + + + P16, SPI - Chip Select + + + P17, +3v3 + + + P18, +3v3 + + + P19, I2C - SCL + + + P20, I2C - SDA + + + GND + + + GND + + + +3v3 + + + GND + + + + + + + + + + + + + + + + + + + + + + A+B + + + + + + + + + + + + + + + + + + + + + + + +
+ ); + } +} diff --git a/src/view/components/simulator/ActionBar.tsx b/src/view/components/simulator/ActionBar.tsx index 2188555b2..b760817b8 100644 --- a/src/view/components/simulator/ActionBar.tsx +++ b/src/view/components/simulator/ActionBar.tsx @@ -10,13 +10,19 @@ interface IProps { onTogglePlay: (event: React.MouseEvent) => void; onToggleRefresh: (event: React.MouseEvent) => void; playStopImage: JSX.Element; + playStopLabel: string; } // Component including the actions done on the Simulator (play/stop, refresh) class ActionBar extends React.Component { public render() { - const { onTogglePlay, onToggleRefresh, playStopImage } = this.props; + const { + onTogglePlay, + onToggleRefresh, + playStopImage, + playStopLabel, + } = this.props; return (
); diff --git a/src/view/components/toolbar/ToolBar.tsx b/src/view/components/toolbar/ToolBar.tsx index 88b064261..c604cbc3b 100644 --- a/src/view/components/toolbar/ToolBar.tsx +++ b/src/view/components/toolbar/ToolBar.tsx @@ -1,17 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { TooltipHost } from "office-ui-fabric-react"; import * as React from "react"; import { FormattedMessage, injectIntl, WrappedComponentProps, } from "react-intl"; +import { SENSOR_LIST } from "../../constants"; import "../../styles/ToolBar.css"; import Button from "../Button"; import { DEFAULT_MODAL_CONTENT, + getModalContent, IModalContent, - LABEL_TO_MODAL_CONTENT, } from "./SensorModalUtils"; interface IToolbarState { @@ -24,6 +26,8 @@ interface IProps extends WrappedComponentProps { label: any; image: any; }>; + onUpdateSensor: (sensor: SENSOR_LIST, value: number) => void; + sensorValues: { [key: string]: number }; } class ToolBar extends React.Component { @@ -46,22 +50,33 @@ class ToolBar extends React.Component { {buttonList.map( (currrentButton: any, index: number) => { return ( - + +
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +`; diff --git a/src/view/context.ts b/src/view/context.ts new file mode 100644 index 000000000..24fafc556 --- /dev/null +++ b/src/view/context.ts @@ -0,0 +1,6 @@ +import * as React from "react"; +import { VIEW_STATE } from "./constants"; + +// View is running by default + +export const ViewStateContext = React.createContext(VIEW_STATE.RUNNING); diff --git a/src/view/index.tsx b/src/view/index.tsx index 9b0fc44a2..32e7400b1 100644 --- a/src/view/index.tsx +++ b/src/view/index.tsx @@ -14,7 +14,6 @@ const locale = "en"; const message = { en: messageEn, }; - ReactDOM.render( diff --git a/src/view/styles/Microbit.css b/src/view/styles/Microbit.css new file mode 100644 index 000000000..b8a741988 --- /dev/null +++ b/src/view/styles/Microbit.css @@ -0,0 +1,173 @@ +.microbit-svg { + padding: 0 0 0 10px; +} +svg.sim { + box-sizing: border-box; + width: 100%; + height: 100%; + display: block; +} +svg.sim.grayscale { + -moz-filter: grayscale(1); + -webkit-filter: grayscale(1); + filter: grayscale(1); +} +.sim-button-group { + cursor: pointer; +} +.sim-button { + pointer-events: none; + fill: "rgb(17, 17, 17)"; +} +.sim-button:active { + fill: orange; +} + +.sim-board, +.sim-display, +sim-button { + fill: #111; +} +.sim-button-outer:hover { + stroke: orange; + stroke-width: 4px; +} +.sim-button-outer:active { + fill: orange; +} + +.sim-button-key-press { + fill: orange; +} + +.sim-button-nut { + fill: #704a4a; + pointer-events: none; +} + +/* +.sim-button-nut:hover { + stroke: 1px solid #704a4a; +} +.sim-pin:hover { + stroke: #d4af37; + stroke-width: 2px; +} +.sim-pin-touch.touched:hover { + stroke: darkorange; +} +.sim-led-back:hover { + stroke: #a0a0a0; + stroke-width: 3px; +} +.sim-led:hover { + stroke: #ff7f7f; + stroke-width: 3px; +} */ +.sim-systemled { + fill: #333; + stroke: #555; + stroke-width: 1px; +} +.sim-light-level-button { + stroke: #fff; + stroke-width: 3px; +} +.sim-antenna { + stroke: #555; + stroke-width: 2px; +} +.sim-text { + font-family: "Lucida Console", Monaco, monospace; + font-size: 25px; + fill: #fff; + pointer-events: none; +} +.sim-text-pin { + font-family: "Lucida Console", Monaco, monospace; + font-size: 20px; + fill: #fff; + pointer-events: none; +} +.sim-thermometer { + stroke: #aaa; + stroke-width: 3px; +} +/* animations */ +.sim-flash { + animation-name: sim-flash-animation; + animation-duration: 0.1s; +} +@keyframes sim-flash-animation { + from { + fill: yellow; + } + to { + fill: default; + } +} +.sim-flash-stroke { + animation-name: sim-flash-stroke-animation; + animation-duration: 0.4s; + animation-timing-function: ease-in; +} +@keyframes sim-flash-stroke-animation { + from { + stroke: yellow; + } + to { + stroke: default; + } +} +/* wireframe */ +.sim-wireframe * { + fill: none; + stroke: black; +} +.sim-wireframe .sim-display, +.sim-wireframe .sim-led, +.sim-wireframe .sim-led-back, +.sim-wireframe .sim-head, +.sim-wireframe .sim-theme, +.sim-wireframe .sim-button-group, +.sim-wireframe .sim-button-label, +.sim-wireframe .sim-button, +.sim-wireframe .sim-text-pin { + visibility: hidden; +} +.sim-wireframe .sim-label { + stroke: none; + fill: #777; +} +.sim-label, +.sim-button-label { + fill: #000; +} +.sim-wireframe .sim-board { + stroke-width: 2px; +} +*:focus { + outline: none; +} +.sim-button-group:focus { + stroke: #4d90fe; + stroke-width: 4px; +} +.sim-button-group:focus { + stroke: #4d90fe; + stroke-width: 4px; +} +*:focus .sim-button-outer, +.sim-pin:focus, +.sim-thermometer:focus, +.sim-shake:focus, +.no-drag, +.sim-text, +.sim-text-pin { + user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; +} diff --git a/src/view/styles/Simulator.css b/src/view/styles/Simulator.css index 62a2f3547..99f14ee48 100644 --- a/src/view/styles/Simulator.css +++ b/src/view/styles/Simulator.css @@ -2,6 +2,7 @@ display: flex; flex-direction: column; justify-content: center; + align-items: center; max-width: 700px; max-height: 700px; margin-left: auto; @@ -63,12 +64,10 @@ } } -.simulator { - display: flex; - flex-direction: column; - justify-content: center; - max-width: 700px; - max-height: 700px; - margin-left: auto; - margin-right: auto; +.microbit-container { + max-width: 350px; + padding: 20px; +} +.cpx-container { + width: 100%; } diff --git a/src/view/translations/en.json b/src/view/translations/en.json index 0cd7f7f98..03ba3349c 100644 --- a/src/view/translations/en.json +++ b/src/view/translations/en.json @@ -1,36 +1,45 @@ -{ - "toolbar-gpio.description": "8 GPIOs on the device! Pin A1 - A7 can also be used as capacitive touch sensors, and A0 is a true analog output pin.", - "toolbar-gpio.title": "GPIO", - "toolbar-gpio.tryItDescription": "Use your mouse to interact with the pin A1 - A7 or use your keyboard SHIFT+”1” - “7”", - "toolbar-ir-sensor.description": "Allows you to send commands to the device with a remote control, or even send messages between multiple devices! You can also do very simple proximity sensing since it reads the reflected light.", - "toolbar-ir-sensor.title": "IR Transmit & Receiver", - "toolbar-ir-sensor.tryItDescription": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", - "toolbar-ir-sensor.tryItTitle": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", - "toolbar-light-sensor.description": "An analog light sensor can be used to detect ambient light, with similar spectral response to the human eye.", - "toolbar-light-sensor.title": "Light Sensor", - "toolbar-light-sensor.tryItDescription": "Change the brightness from 0 - 255 here!", - "toolbar-motion-sensor.description": "Detects acceleration in XYZ orientations. And can also detect 'tap' and 'double tap' strikes on the board and when the board is shaken.", - "toolbar-motion-sensor.title": "Motion Sensor", - "toolbar-motion-sensor.tryItDescription": "Change the acceleration here and click or click on the button to simulate a shake.The tap feature is not supported by the Device Simulator Express. You can try it on MakeCode!", - "toolbar-neo-pixels.description": "The 10 full color RGB LEDs surrounding the outer edge of the boards can be set to any color. Great for beautiful lighting effects!", - "toolbar-neo-pixels.title": "NeoPixels", - "toolbar-neo-pixels.tryItDescription": "Run your code and see the cool effects on the simulator!", - "toolbar-push-button.description": "Two push buttons A and B are connected to digital pin #4 (Left) and #5 (Right) each.", - "toolbar-push-button.title": "Push Buttons", - "toolbar-push-button.tryItDescription": "Click them with your mouse or by pressing “A” “B” on your keyboard!", - "toolbar-red-led.description": "This Red LED is connected to the digital #13 GPIO pin. It can be very handy when you want an indicator LED.", - "toolbar-red-led.title": "Red LED", - "toolbar-red-led.tryItDescription": "Run your code and see the cool effects on the simulator!", - "toolbar-sound-sensor.description": "A digital microphone can detect audio volume and even perform basic FFT functions but cannot read it like an analog voltage.", - "toolbar-sound-sensor.title": "Sound Sensor", - "toolbar-sound-sensor.tryItDescription": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", - "toolbar-slider-switch.description": "This slide switch returns True or False depending on whether it's ON or OFF and can be used as a toggle switch in your code!", - "toolbar-slider-switch.title": "Slider Switch", - "toolbar-slider-switch.tryItDescription": "Click it with your mouse or press 'S' on your keyboard to switch it ON and OFF!", - "toolbar-speaker.description": "This speaker can play .wav file and different tones and also has a class D amplifier that is connected to an output A0 pin built in! You can turn it off using the shutdown control on pin #11 on the physical device.", - "toolbar-speaker.title": "Speaker", - "toolbar-speaker.tryItDescription": "Right now the tones are not supported yet on the simulator, but you can play it on your device!", - "toolbar-temperature-sensor.description": "This sensor uses an NTC thermistor to sense temperature an calculate it with the analog voltage on analog pin #A9.", - "toolbar-temperature-sensor.title": "Temperature Sensor", - "toolbar-temperature-sensor.tryItDescription": "You can set the temperature range from your code!" -} +{ + "toolbar-gpio.description": "8 GPIOs on the device! Pin A1 - A7 can also be used as capacitive touch sensors, and A0 is a true analog output pin.", + "toolbar-gpio.title": "GPIO", + "toolbar-gpio.tryItDescription": "Use your mouse to interact with the pin A1 - A7 or use your keyboard SHIFT+”1” - “7”.", + "toolbar-ir-sensor.description": "Allows you to send commands to the device with a remote control, or even send messages between multiple devices! You can also do very simple proximity sensing since it reads the reflected light.", + "toolbar-ir-sensor.title": "IR Transmit & Receiver", + "toolbar-ir-sensor.tryItDescription": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", + "toolbar-ir-sensor.tryItTitle": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", + "toolbar-light-sensor.description": "An analog light sensor can be used to detect ambient light, with similar spectral response to the human eye.", + "toolbar-light-sensor.title": "Light Sensor", + "toolbar-light-sensor.tryItDescription": "Change the brightness from 0 - 255 here!", + "toolbar-motion-sensor.description": "Detects acceleration in XYZ orientations. And can also detect 'tap' and 'double tap' strikes on the board and when the board is shaken.", + "toolbar-motion-sensor.title": "Motion Sensor", + "toolbar-motion-sensor.tryItDescription": "Change the acceleration here and click or click on the button to simulate a shake.The tap feature is not supported by the Device Simulator Express. You can try it on MakeCode!", + "toolbar-neo-pixels.description": "The 10 full color RGB LEDs surrounding the outer edge of the boards can be set to any color. Great for beautiful lighting effects!", + "toolbar-neo-pixels.title": "NeoPixels", + "toolbar-neo-pixels.tryItDescription": "Run your code and see the cool effects on the simulator!", + "toolbar-push-button.description": "Two push buttons A and B are connected to digital pin #4 (Left) and #5 (Right) each.", + "toolbar-push-button.title": "Push Buttons", + "toolbar-push-button.tryItDescription": "Click them with your mouse or by pressing “A” “B” on your keyboard!", + "toolbar-red-led.description": "This Red LED is connected to the digital #13 GPIO pin. It can be very handy when you want an indicator LED.", + "toolbar-red-led.title": "Red LED", + "toolbar-red-led.tryItDescription": "Run your code and see the cool effects on the simulator!", + "toolbar-sound-sensor.description": "A digital microphone can detect audio volume and even perform basic FFT functions but cannot read it like an analog voltage.", + "toolbar-sound-sensor.title": "Sound Sensor", + "toolbar-sound-sensor.tryItDescription": "We’re working hard to support this sensor on the simulator in the Device Simulator Express. You can try it on MakeCode!", + "toolbar-slider-switch.description": "This slide switch returns True or False depending on whether it's ON or OFF and can be used as a toggle switch in your code!", + "toolbar-slider-switch.title": "Slider Switch", + "toolbar-slider-switch.tryItDescription": "Click it with your mouse or press 'S' on your keyboard to switch it ON and OFF!", + "toolbar-speaker.description": "This speaker can play .wav file and different tones and also has a class D amplifier that is connected to an output A0 pin built in! You can turn it off using the shutdown control on pin #11 on the physical device.", + "toolbar-speaker.title": "Speaker", + "toolbar-speaker.tryItDescription": "Right now the tones are not supported yet on the simulator, but you can play it on your device!", + "toolbar-temperature-sensor.description": "This sensor uses an NTC thermistor to sense temperature an calculate it with the analog voltage on analog pin #A9.", + "toolbar-temperature-sensor.title": "Temperature Sensor", + "toolbar-temperature-sensor.tryItDescription": "You can set the temperature range from your code!", + "toolbar-accelerometer-sensor.title": "Accelerometer", + "toolbar-accelerometer-sensor.description": "An accelerometer measures the acceleration of your micro:bit; this component senses when the micro:bit is moved.", + "toolbar-accelerometer-sensor.tryItDescription": "Change the acceleration here.", + "toolbar-microbit-led.title": "LEDs", + "toolbar-microbit-led.description": "The microbit has 25 LEDs for you to play with. The LEDs have 9 levels of brightness.", + "toolbar-microbit-led.tryItDescription": "Run your code and see the LEDs light up!", + "toolbar-microbit-button.title": "Buttons", + "toolbar-microbit-button.description": "There are two buttons on the front of the micro:bit (labelled A and B). The third button is to trigger both A and B buttons. You can detect when these buttons are pressed, allowing you to trigger code on the device.", + "toolbar-microbit-button.tryItDescription": "Click them with your mouse. Pressing “A” “B” on your keyboard will be implemented soon!" +} \ No newline at end of file diff --git a/src/view/utils/MessageUtils.tsx b/src/view/utils/MessageUtils.tsx new file mode 100644 index 000000000..41e093455 --- /dev/null +++ b/src/view/utils/MessageUtils.tsx @@ -0,0 +1,12 @@ +interface vscode { + postMessage(message: any): void; +} + +declare const vscode: vscode; + +export const sendMessage = ( + type: string, + state: TState +) => { + vscode.postMessage({ command: type, text: state }); +}; diff --git a/src/view/viewUtils.tsx b/src/view/viewUtils.tsx index 7b6efed48..445b916b2 100644 --- a/src/view/viewUtils.tsx +++ b/src/view/viewUtils.tsx @@ -1,3 +1,5 @@ +import { SENSOR_LIST } from "./constants"; + // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. export interface ISliderProps { @@ -5,8 +7,10 @@ export interface ISliderProps { maxValue: number; maxLabel: string; minLabel: string; - type: string; + type: string | SENSOR_LIST; axisLabel: string; + value?: number; + onUpdateValue?: (sensor: SENSOR_LIST, value: number) => void; } export interface ISensorButtonProps { @@ -17,7 +21,6 @@ export interface ISensorButtonProps { onKeyUp: (event: React.KeyboardEvent) => void; onKeyDown: (event: React.KeyboardEvent) => void; } - export interface ISensorProps { LABEL: string; sliderProps: ISliderProps[]; diff --git a/tslint.json b/tslint.json index 4b199b36e..534279116 100644 --- a/tslint.json +++ b/tslint.json @@ -1,32 +1,34 @@ { - "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], - "extends": [ - "tslint:latest", - "tslint-react", - "tslint-config-prettier", - "tslint-react-hooks", - "tslint-microsoft-contrib/latest" - ], - "rules": { - "no-implicit-dependencies": [true, "dev"], - "no-string-throw": true, - "no-unused-expression": true, - "no-duplicate-variable": true, - "no-empty": false, - "no-relative-imports": false, - "max-func-body-length": false, - "curly": true, - "class-name": true, - "triple-equals": true, - "object-literal-sort-keys": true, - "react-hooks-nesting": "error", - "ordered-imports": true, - "import-name": false, - "member-access": false, - "no-console": false, - "jsx-boolean-value": false, - "no-unnecessary-semicolons": false, - "no-http-string": false - }, - "defaultSeverity": "warning" + "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], + "extends": [ + "tslint:latest", + "tslint-react", + "tslint-config-prettier", + "tslint-react-hooks", + "tslint-microsoft-contrib/latest" + ], + "rules": { + "no-implicit-dependencies": [true, "dev"], + "no-string-throw": true, + "no-unused-expression": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-relative-imports": false, + "max-func-body-length": false, + "curly": true, + "class-name": true, + "triple-equals": true, + "object-literal-sort-keys": true, + "react-hooks-nesting": "error", + "ordered-imports": true, + "import-name": false, + "member-access": false, + "no-console": false, + "jsx-boolean-value": false, + "no-unnecessary-semicolons": false, + "no-http-string": false, + "export-name": false, + "interface-name": false + }, + "defaultSeverity": "warning" } diff --git a/vendor/node-usb-native/.eslintrc b/vendor/node-usb-native/.eslintrc index 2b063c78c..3ade3b9dd 100644 --- a/vendor/node-usb-native/.eslintrc +++ b/vendor/node-usb-native/.eslintrc @@ -1,26 +1,26 @@ -{ - "extends": [ - "standard" - ], - "plugins": [ - "require-path-exists" - ], - "env": { - "node": true, - "mocha": true - }, - "rules": { - "arrow-parens": [2, "as-needed", {"requireForBlockBody": true }], - "no-unused-vars": [2, { "vars": "all", "args": "after-used" }], - "object-curly-spacing": [2, "always"], - "prefer-arrow-callback": 2, - "prefer-const": 2, - "prefer-template": 2, - "require-path-exists/exists": 2, - "require-path-exists/notEmpty": 2, - "require-path-exists/tooManyArguments": 2, - "semi": [2, "always", {"omitLastInOneLineBlock": true}], - "space-before-function-paren": [2, "never"], - "standard/object-curly-even-spacing": 0 - } +{ + "extends": [ + "standard" + ], + "plugins": [ + "require-path-exists" + ], + "env": { + "node": true, + "mocha": true + }, + "rules": { + "arrow-parens": [2, "as-needed", {"requireForBlockBody": true }], + "no-unused-vars": [2, { "vars": "all", "args": "after-used" }], + "object-curly-spacing": [2, "always"], + "prefer-arrow-callback": 2, + "prefer-const": 2, + "prefer-template": 2, + "require-path-exists/exists": 2, + "require-path-exists/notEmpty": 2, + "require-path-exists/tooManyArguments": 2, + "semi": [2, "always", {"omitLastInOneLineBlock": true}], + "space-before-function-paren": [2, "never"], + "standard/object-curly-even-spacing": 0 + } } \ No newline at end of file diff --git a/vendor/node-usb-native/.gitignore b/vendor/node-usb-native/.gitignore index 8d2b1ae24..41ace66fd 100644 --- a/vendor/node-usb-native/.gitignore +++ b/vendor/node-usb-native/.gitignore @@ -1,14 +1,14 @@ -$ cat .gitignore - -# Can ignore specific files -.settings.xml -.monitor -.DS_Store - -# Use wildcards as well -*~ -#*.swp - -# Can also ignore all directories and files in a directory. -node_modules/ -build/ +$ cat .gitignore + +# Can ignore specific files +.settings.xml +.monitor +.DS_Store + +# Use wildcards as well +*~ +#*.swp + +# Can also ignore all directories and files in a directory. +node_modules/ +build/ diff --git a/vendor/node-usb-native/.npmignore b/vendor/node-usb-native/.npmignore index b38db2f29..27b90ed90 100644 --- a/vendor/node-usb-native/.npmignore +++ b/vendor/node-usb-native/.npmignore @@ -1,2 +1,2 @@ -node_modules/ -build/ +node_modules/ +build/ diff --git a/vendor/node-usb-native/README.md b/vendor/node-usb-native/README.md index 5de5318a6..329164300 100644 --- a/vendor/node-usb-native/README.md +++ b/vendor/node-usb-native/README.md @@ -1,4 +1,4 @@ -This is a natvie package contains two modules: detector and serialport, detector provides the functionality of detecting usb changes and serialport provides the functionality of listing serial ports, openning serial ports and sending/receiving message to/from serial ports. - - require("../../../vendor/node-usb-native").SerialPort; - require("../../../vendor/node-usb-native").detector; +This is a natvie package contains two modules: detector and serialport, detector provides the functionality of detecting usb changes and serialport provides the functionality of listing serial ports, openning serial ports and sending/receiving message to/from serial ports. + + require("../../../vendor/node-usb-native").SerialPort; + require("../../../vendor/node-usb-native").detector; diff --git a/vendor/node-usb-native/binding.gyp b/vendor/node-usb-native/binding.gyp index c967103e1..10be49615 100644 --- a/vendor/node-usb-native/binding.gyp +++ b/vendor/node-usb-native/binding.gyp @@ -1,64 +1,64 @@ -{ - "targets": [ - { - "target_name": "usb-native", - "sources": [ - "src/detection.cpp", - "src/detection.h", - "src/deviceList.cpp", - "src/combined.cpp", - "src/serialport.cpp" - ], - "include_dirs": [ - " { - // Suss out the optional parameters - if (!pid && !callback) { - callback = vid; - vid = undefined; - } else if (!callback) { - callback = pid; - pid = undefined; - } - - return new Promise((resolve, reject) => { - // Assemble the optional args into something we can use with `apply` - var args = []; - if (vid) { - args = args.concat(vid); - } - if (pid) { - args = args.concat(pid); - } - - // Tack on our own callback that takes care of things - args = args.concat((err, devices) => { - // We call the callback if they passed one - if (callback) { - callback.call(callback, err, devices); - } - - // But also do the promise stuff - if (err) { - reject(err); - return; - } - resolve(devices); - }); - - // Fire off the `find` function that actually does all of the work - detection.find.apply(detection, args); - }); -}; -if (detection.registerAdded) { - detection.registerAdded((device) => { - detector.emit(`add:${device.vendorId}:${device.productId}`, device); - detector.emit(`insert:${device.vendorId}:${device.productId}`, device); - detector.emit(`add:${device.vendorId}`, device); - detector.emit(`insert:${device.vendorId}`, device); - detector.emit('add', device); - detector.emit('insert', device); - - detector.emit(`change:${device.vendorId}:${device.productId}`, device); - detector.emit(`change:${device.vendorId}`, device); - detector.emit('change', device); - }); - - detection.registerRemoved((device) => { - detector.emit(`remove:${device.vendorId}:${device.productId}`, device); - detector.emit(`remove:${device.vendorId}`, device); - detector.emit('remove', device); - - detector.emit(`change:${device.vendorId}:${device.productId}`, device); - detector.emit(`change:${device.vendorId}`, device); - detector.emit('change', device); - }); - - var started = true; - - detector.startMonitoring = () => { - if (started) { - return; - } - - started = true; - detection.startMonitoring(); - }; - - detector.stopMonitoring = () => { - if (!started) { - return; - } - - started = false; - detection.stopMonitoring(); - }; -} - -module.exports = detector; +var detection = require('./bindings'); +var EventEmitter2 = require('eventemitter2').EventEmitter2; + +var detector = new EventEmitter2({ + wildcard: true, + delimiter: ':', + maxListeners: 1000 // default would be 10! +}); + +// detector.find = detection.find; +detector.find = (vid, pid, callback) => { + // Suss out the optional parameters + if (!pid && !callback) { + callback = vid; + vid = undefined; + } else if (!callback) { + callback = pid; + pid = undefined; + } + + return new Promise((resolve, reject) => { + // Assemble the optional args into something we can use with `apply` + var args = []; + if (vid) { + args = args.concat(vid); + } + if (pid) { + args = args.concat(pid); + } + + // Tack on our own callback that takes care of things + args = args.concat((err, devices) => { + // We call the callback if they passed one + if (callback) { + callback.call(callback, err, devices); + } + + // But also do the promise stuff + if (err) { + reject(err); + return; + } + resolve(devices); + }); + + // Fire off the `find` function that actually does all of the work + detection.find.apply(detection, args); + }); +}; +if (detection.registerAdded) { + detection.registerAdded((device) => { + detector.emit(`add:${device.vendorId}:${device.productId}`, device); + detector.emit(`insert:${device.vendorId}:${device.productId}`, device); + detector.emit(`add:${device.vendorId}`, device); + detector.emit(`insert:${device.vendorId}`, device); + detector.emit('add', device); + detector.emit('insert', device); + + detector.emit(`change:${device.vendorId}:${device.productId}`, device); + detector.emit(`change:${device.vendorId}`, device); + detector.emit('change', device); + }); + + detection.registerRemoved((device) => { + detector.emit(`remove:${device.vendorId}:${device.productId}`, device); + detector.emit(`remove:${device.vendorId}`, device); + detector.emit('remove', device); + + detector.emit(`change:${device.vendorId}:${device.productId}`, device); + detector.emit(`change:${device.vendorId}`, device); + detector.emit('change', device); + }); + + var started = true; + + detector.startMonitoring = () => { + if (started) { + return; + } + + started = true; + detection.startMonitoring(); + }; + + detector.stopMonitoring = () => { + if (!started) { + return; + } + + started = false; + detection.stopMonitoring(); + }; +} + +module.exports = detector; diff --git a/vendor/node-usb-native/lib/index.js b/vendor/node-usb-native/lib/index.js index 3a5c973fe..09bfc7115 100644 --- a/vendor/node-usb-native/lib/index.js +++ b/vendor/node-usb-native/lib/index.js @@ -1,2 +1,2 @@ -exports.detector = require('./detector'); -exports.SerialPort = require('./serialport'); +exports.detector = require('./detector'); +exports.SerialPort = require('./serialport'); diff --git a/vendor/node-usb-native/lib/list-unix.js b/vendor/node-usb-native/lib/list-unix.js index e3b6de297..32e6719a9 100644 --- a/vendor/node-usb-native/lib/list-unix.js +++ b/vendor/node-usb-native/lib/list-unix.js @@ -1,109 +1,109 @@ -'use strict'; - -var childProcess = require('child_process'); -var fs = require('fs'); -var path = require('path'); - -function promisify(func) { - return (arg) => { - return new Promise((resolve, reject) => { - func(arg, (err, data) => { - if (err) { - return reject(err); - } - resolve(data); - }); - }); - }; -} - -function promisedFilter(func) { - return (data) => { - var shouldKeep = data.map(func); - return Promise.all(shouldKeep).then((keep) => { - return data.filter((path, index) => { - return keep[index]; - }); - }); - }; -} - -var statAsync = promisify(fs.stat); -var readdirAsync = promisify(fs.readdir); -var execAsync = promisify(childProcess.exec); - -function udevParser(output) { - var udevInfo = output.split('\n').reduce((info, line) => { - if (!line || line.trim() === '') { - return info; - } - var parts = line.split('=').map((part) => { - return part.trim(); - }); - - info[parts[0].toLowerCase()] = parts[1]; - - return info; - }, {}); - - var pnpId; - if (udevInfo.devlinks) { - udevInfo.devlinks.split(' ').forEach((path) => { - if (path.indexOf('/by-id/') === -1) { return } - pnpId = path.substring(path.lastIndexOf('/') + 1); - }); - } - - var vendorId = udevInfo.id_vendor_id; - if (vendorId && vendorId.substring(0, 2) !== '0x') { - vendorId = `0x${vendorId}`; - } - - var productId = udevInfo.id_model_id; - if (productId && productId.substring(0, 2) !== '0x') { - productId = `0x${productId}`; - } - - return { - comName: udevInfo.devname, - manufacturer: udevInfo.id_vendor, - serialNumber: udevInfo.id_serial, - pnpId: pnpId, - vendorId: vendorId, - productId: productId - }; -} - -function checkPathAndDevice(path) { - // get only serial port names - if (!(/(tty(S|ACM|USB|AMA|MFD)|rfcomm)/).test(path)) { - return false; - } - return statAsync(path).then((stats) => { - return stats.isCharacterDevice(); - }); -} - -function lookupPort(file) { - var udevadm = `udevadm info --query=property -p $(udevadm info -q path -n ${file})`; - return execAsync(udevadm).then(udevParser); -} - -function listUnix(callback) { - var dirName = '/dev'; - readdirAsync(dirName) - .catch((err) => { - // if this directory is not found we just pretend everything is OK - // TODO Depreciated this check? - if (err.errno === 34) { - return []; - } - throw err; - }) - .then((data) => { return data.map((file) => { return path.join(dirName, file) }) }) - .then(promisedFilter(checkPathAndDevice)) - .then((data) => { return Promise.all(data.map(lookupPort)) }) - .then((data) => { callback(null, data) }, (err) => { callback(err) }); -} - -module.exports = listUnix; +'use strict'; + +var childProcess = require('child_process'); +var fs = require('fs'); +var path = require('path'); + +function promisify(func) { + return (arg) => { + return new Promise((resolve, reject) => { + func(arg, (err, data) => { + if (err) { + return reject(err); + } + resolve(data); + }); + }); + }; +} + +function promisedFilter(func) { + return (data) => { + var shouldKeep = data.map(func); + return Promise.all(shouldKeep).then((keep) => { + return data.filter((path, index) => { + return keep[index]; + }); + }); + }; +} + +var statAsync = promisify(fs.stat); +var readdirAsync = promisify(fs.readdir); +var execAsync = promisify(childProcess.exec); + +function udevParser(output) { + var udevInfo = output.split('\n').reduce((info, line) => { + if (!line || line.trim() === '') { + return info; + } + var parts = line.split('=').map((part) => { + return part.trim(); + }); + + info[parts[0].toLowerCase()] = parts[1]; + + return info; + }, {}); + + var pnpId; + if (udevInfo.devlinks) { + udevInfo.devlinks.split(' ').forEach((path) => { + if (path.indexOf('/by-id/') === -1) { return } + pnpId = path.substring(path.lastIndexOf('/') + 1); + }); + } + + var vendorId = udevInfo.id_vendor_id; + if (vendorId && vendorId.substring(0, 2) !== '0x') { + vendorId = `0x${vendorId}`; + } + + var productId = udevInfo.id_model_id; + if (productId && productId.substring(0, 2) !== '0x') { + productId = `0x${productId}`; + } + + return { + comName: udevInfo.devname, + manufacturer: udevInfo.id_vendor, + serialNumber: udevInfo.id_serial, + pnpId: pnpId, + vendorId: vendorId, + productId: productId + }; +} + +function checkPathAndDevice(path) { + // get only serial port names + if (!(/(tty(S|ACM|USB|AMA|MFD)|rfcomm)/).test(path)) { + return false; + } + return statAsync(path).then((stats) => { + return stats.isCharacterDevice(); + }); +} + +function lookupPort(file) { + var udevadm = `udevadm info --query=property -p $(udevadm info -q path -n ${file})`; + return execAsync(udevadm).then(udevParser); +} + +function listUnix(callback) { + var dirName = '/dev'; + readdirAsync(dirName) + .catch((err) => { + // if this directory is not found we just pretend everything is OK + // TODO Depreciated this check? + if (err.errno === 34) { + return []; + } + throw err; + }) + .then((data) => { return data.map((file) => { return path.join(dirName, file) }) }) + .then(promisedFilter(checkPathAndDevice)) + .then((data) => { return Promise.all(data.map(lookupPort)) }) + .then((data) => { callback(null, data) }, (err) => { callback(err) }); +} + +module.exports = listUnix; diff --git a/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_ia32.node b/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_ia32.node new file mode 100644 index 000000000..83b71d780 Binary files /dev/null and b/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_ia32.node differ diff --git a/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_x64.node b/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_x64.node new file mode 100644 index 000000000..5e379cb9a Binary files /dev/null and b/vendor/node-usb-native/lib/native/usb-native_Ubuntu14.04_6.1.4_x64.node differ diff --git a/vendor/node-usb-native/lib/native/usb-native_darwin_6.1.4_x64.node b/vendor/node-usb-native/lib/native/usb-native_darwin_6.1.4_x64.node new file mode 100644 index 000000000..440a59200 Binary files /dev/null and b/vendor/node-usb-native/lib/native/usb-native_darwin_6.1.4_x64.node differ diff --git a/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_ia32.node b/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_ia32.node new file mode 100644 index 000000000..277de25a2 Binary files /dev/null and b/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_ia32.node differ diff --git a/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_x64.node b/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_x64.node new file mode 100644 index 000000000..f31e6a342 Binary files /dev/null and b/vendor/node-usb-native/lib/native/usb-native_win32_6.1.4_x64.node differ diff --git a/vendor/node-usb-native/lib/native_loader.js b/vendor/node-usb-native/lib/native_loader.js index 0f1fc2ebf..ce4e0ea22 100644 --- a/vendor/node-usb-native/lib/native_loader.js +++ b/vendor/node-usb-native/lib/native_loader.js @@ -1,24 +1,24 @@ -const glob = require('glob'); -const path = require('path'); -const loadLibrary = function(parentFolder, libraryName) { - const nodegypFiles = glob(path.join(__dirname, `../build/+(Release|Debug)/${libraryName}.node`), { - sync: true - }); - const nodepregypFiles = glob(`${parentFolder.replace(/\\/g, '/')}/${libraryName}*${process.arch}*.node`, { - sync: true - }); - var binding = null; - nodegypFiles.concat(nodepregypFiles).forEach((file) => { - try { - var _temp = require(file); - binding = _temp; - console.log('using', file); - } catch (e) { - } - }); - if (!binding) { - console.log('[Warn]', 'no library available after trying files', nodegypFiles.concat(nodepregypFiles)); - } - return binding; -}; -exports.load = loadLibrary; +const glob = require('glob'); +const path = require('path'); +const loadLibrary = function(parentFolder, libraryName) { + const nodegypFiles = glob(path.join(__dirname, `../build/+(Release|Debug)/${libraryName}.node`), { + sync: true + }); + const nodepregypFiles = glob(`${parentFolder.replace(/\\/g, '/')}/${libraryName}*${process.arch}*.node`, { + sync: true + }); + var binding = null; + nodegypFiles.concat(nodepregypFiles).forEach((file) => { + try { + var _temp = require(file); + binding = _temp; + console.log('using', file); + } catch (e) { + } + }); + if (!binding) { + console.log('[Warn]', 'no library available after trying files', nodegypFiles.concat(nodepregypFiles)); + } + return binding; +}; +exports.load = loadLibrary; diff --git a/vendor/node-usb-native/lib/parsers.js b/vendor/node-usb-native/lib/parsers.js index 2783c1425..303fba50d 100644 --- a/vendor/node-usb-native/lib/parsers.js +++ b/vendor/node-usb-native/lib/parsers.js @@ -1,64 +1,64 @@ -'use strict'; - -// Copyright 2011 Chris Williams - -module.exports = { - raw: function(emitter, buffer) { - emitter.emit('data', buffer); - }, - - // encoding: ascii utf8 utf16le ucs2 base64 binary hex - // More: http://nodejs.org/api/buffer.html#buffer_buffer - readline: function(delimiter, encoding) { - if (typeof delimiter === 'undefined' || delimiter === null) { delimiter = '\r' } - if (typeof encoding === 'undefined' || encoding === null) { encoding = 'utf8' } - // Delimiter buffer saved in closure - var data = ''; - return function(emitter, buffer) { - // Collect data - data += buffer.toString(encoding); - // Split collected data by delimiter - var parts = data.split(delimiter); - data = parts.pop(); - parts.forEach((part) => { - emitter.emit('data', part); - }); - }; - }, - - // Emit a data event every `length` bytes - byteLength: function(length) { - var data = Buffer.alloc(0); - return function(emitter, buffer) { - data = Buffer.concat([data, buffer]); - while (data.length >= length) { - var out = data.slice(0, length); - data = data.slice(length); - emitter.emit('data', out); - } - }; - }, - - // Emit a data event each time a byte sequence (delimiter is an array of byte) is found - // Sample usage : byteDelimiter([10, 13]) - byteDelimiter: function(delimiter) { - if (Object.prototype.toString.call(delimiter) !== '[object Array]') { - delimiter = [ delimiter ]; - } - var buf = []; - var nextDelimIndex = 0; - return function(emitter, buffer) { - for (var i = 0; i < buffer.length; i++) { - buf[buf.length] = buffer[i]; - if (buf[buf.length - 1] === delimiter[nextDelimIndex]) { - nextDelimIndex++; - } - if (nextDelimIndex === delimiter.length) { - emitter.emit('data', buf); - buf = []; - nextDelimIndex = 0; - } - } - }; - } -}; +'use strict'; + +// Copyright 2011 Chris Williams + +module.exports = { + raw: function(emitter, buffer) { + emitter.emit('data', buffer); + }, + + // encoding: ascii utf8 utf16le ucs2 base64 binary hex + // More: http://nodejs.org/api/buffer.html#buffer_buffer + readline: function(delimiter, encoding) { + if (typeof delimiter === 'undefined' || delimiter === null) { delimiter = '\r' } + if (typeof encoding === 'undefined' || encoding === null) { encoding = 'utf8' } + // Delimiter buffer saved in closure + var data = ''; + return function(emitter, buffer) { + // Collect data + data += buffer.toString(encoding); + // Split collected data by delimiter + var parts = data.split(delimiter); + data = parts.pop(); + parts.forEach((part) => { + emitter.emit('data', part); + }); + }; + }, + + // Emit a data event every `length` bytes + byteLength: function(length) { + var data = Buffer.alloc(0); + return function(emitter, buffer) { + data = Buffer.concat([data, buffer]); + while (data.length >= length) { + var out = data.slice(0, length); + data = data.slice(length); + emitter.emit('data', out); + } + }; + }, + + // Emit a data event each time a byte sequence (delimiter is an array of byte) is found + // Sample usage : byteDelimiter([10, 13]) + byteDelimiter: function(delimiter) { + if (Object.prototype.toString.call(delimiter) !== '[object Array]') { + delimiter = [ delimiter ]; + } + var buf = []; + var nextDelimIndex = 0; + return function(emitter, buffer) { + for (var i = 0; i < buffer.length; i++) { + buf[buf.length] = buffer[i]; + if (buf[buf.length - 1] === delimiter[nextDelimIndex]) { + nextDelimIndex++; + } + if (nextDelimIndex === delimiter.length) { + emitter.emit('data', buf); + buf = []; + nextDelimIndex = 0; + } + } + }; + } +}; diff --git a/vendor/node-usb-native/lib/serialport.js b/vendor/node-usb-native/lib/serialport.js index 6fcc88e16..754f21769 100644 --- a/vendor/node-usb-native/lib/serialport.js +++ b/vendor/node-usb-native/lib/serialport.js @@ -1,502 +1,502 @@ -'use strict'; - -// Copyright 2011 Chris Williams - -const _debug = false; -const debug = (message) => { - if (_debug) console.log(message); -}; - -// shims -// Internal Dependencies -var SerialPortBinding = require('./bindings'); -var parsers = require('./parsers'); - -// Built-ins Dependencies -var fs = require('fs'); -var stream = require('stream'); -var util = require('util'); - -// VALIDATION ARRAYS -var DATABITS = [5, 6, 7, 8]; -var STOPBITS = [1, 1.5, 2]; -var PARITY = ['none', 'even', 'mark', 'odd', 'space']; -var FLOWCONTROLS = ['xon', 'xoff', 'xany', 'rtscts']; -var SET_OPTIONS = ['brk', 'cts', 'dtr', 'dts', 'rts']; - -// Stuff from ReadStream, refactored for our usage: -var kPoolSize = 40 * 1024; -var kMinPoolSpace = 128; - -var defaultSettings = { - baudRate: 9600, - autoOpen: true, - parity: 'none', - xon: false, - xoff: false, - xany: false, - rtscts: false, - hupcl: true, - dataBits: 8, - stopBits: 1, - bufferSize: 64 * 1024, - lock: true, - parser: parsers.raw, - platformOptions: SerialPortBinding.platformOptions -}; - -var defaultSetFlags = { - brk: false, - cts: false, - dtr: true, - dts: false, - rts: true -}; - -// deprecate the lowercase version of these options next major release -var LOWERCASE_OPTIONS = [ - 'baudRate', - 'dataBits', - 'stopBits', - 'bufferSize', - 'platformOptions' -]; - -function correctOptions(options) { - LOWERCASE_OPTIONS.forEach((name) => { - var lowerName = name.toLowerCase(); - if (options.hasOwnProperty(lowerName)) { - var value = options[lowerName]; - delete options[lowerName]; - options[name] = value; - } - }); - return options; -} - -function SerialPort(path, options, callback) { - if (typeof callback === 'boolean') { - throw new TypeError('`openImmediately` is now called `autoOpen` and is a property of options'); - } - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - options = options || {}; - - stream.Stream.call(this); - - if (!path) { - throw new TypeError('No path specified'); - } - - this.path = path; - - var correctedOptions = correctOptions(options); - var settings = Object.assign({}, defaultSettings, correctedOptions); - - if (typeof settings.baudRate !== 'number') { - throw new TypeError(`Invalid "baudRate" must be a number got: ${settings.baudRate}`); - } - - if (DATABITS.indexOf(settings.dataBits) === -1) { - throw new TypeError(`Invalid "databits": ${settings.dataBits}`); - } - - if (STOPBITS.indexOf(settings.stopBits) === -1) { - throw new TypeError(`Invalid "stopbits": ${settings.stopBits}`); - } - - if (PARITY.indexOf(settings.parity) === -1) { - throw new TypeError(`Invalid "parity": ${settings.parity}`); - } - - FLOWCONTROLS.forEach((control) => { - if (typeof settings[control] !== 'boolean') { - throw new TypeError(`Invalid "${control}" is not boolean`); - } - }); - - settings.disconnectedCallback = this._disconnected.bind(this); - settings.dataCallback = settings.parser.bind(this, this); - - this.fd = null; - this.paused = true; - this.opening = false; - this.closing = false; - - if (process.platform !== 'win32') { - this.bufferSize = settings.bufferSize; - this.readable = true; - this.reading = false; - } - - this.options = settings; - - if (this.options.autoOpen) { - // is nextTick necessary? - process.nextTick(this.open.bind(this, callback)); - } -} - -util.inherits(SerialPort, stream.Stream); - -SerialPort.prototype._error = function(error, callback) { - if (callback) { - callback.call(this, error); - } else { - this.emit('error', error); - } -}; - -SerialPort.prototype.open = function(callback) { - if (this.isOpen()) { - return this._error(new Error('Port is already open'), callback); - } - - if (this.opening) { - return this._error(new Error('Port is opening'), callback); - } - - this.paused = true; - this.readable = true; - this.reading = false; - this.opening = true; - - SerialPortBinding.open(this.path, this.options, (err, fd) => { - this.opening = false; - if (err) { - debug('SerialPortBinding.open had an error', err); - return this._error(err, callback); - } - this.fd = fd; - this.paused = false; - - if (process.platform !== 'win32') { - this.serialPoller = new SerialPortBinding.SerialportPoller(this.fd, (err) => { - if (!err) { - this._read(); - } else { - this._disconnected(err); - } - }); - this.serialPoller.start(); - } - - this.emit('open'); - if (callback) { - callback.call(this, null); - } - }); -}; - -SerialPort.prototype.update = function(options, callback) { - if (!this.isOpen()) { - debug('update attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - var correctedOptions = correctOptions(options); - var settings = Object.assign({}, defaultSettings, correctedOptions); - this.options.baudRate = settings.baudRate; - - SerialPortBinding.update(this.fd, this.options, (err) => { - if (err) { - return this._error(err, callback); - } - if (callback) { - callback.call(this, null); - } - }); -}; - -SerialPort.prototype.isOpen = function() { - return this.fd !== null && !this.closing; -}; - -SerialPort.prototype.write = function(buffer, ending, callback) { - if (!this.isOpen()) { - debug('write attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - if (!Buffer.isBuffer(buffer)) { - buffer = Buffer.from(buffer); - } - - switch (ending) { - case 'Newline': - buffer = Buffer.concat([buffer, Buffer.from('\n')]); - break; - case 'Carriage return': - buffer = Buffer.concat([buffer, Buffer.from('\r')]); - break; - case 'Both NL & CR': - buffer = Buffer.concat([buffer, Buffer.from('\r\n')]); - break; - default: - break; - } - - debug(`write ${buffer.length} bytes of data`); - SerialPortBinding.write(this.fd, buffer, (err) => { - if (err) { - debug('SerialPortBinding.write had an error', err); - return this._error(err, callback); - } - if (callback) { - callback.call(this, null); - } - }); -}; - -if (process.platform !== 'win32') { - SerialPort.prototype._read = function() { - if (!this.readable || this.paused || this.reading || this.closing) { - return; - } - - this.reading = true; - - if (!this.pool || this.pool.length - this.pool.used < kMinPoolSpace) { - // discard the old pool. Can't add to the free list because - // users might have references to slices on it. - this.pool = Buffer.alloc(kPoolSize); - this.pool.used = 0; - } - - // Grab another reference to the pool in the case that while we're in the - // thread pool another read() finishes up the pool, and allocates a new - // one. - var toRead = Math.min(this.pool.length - this.pool.used, ~~this.bufferSize); - var start = this.pool.used; - - var _afterRead = (err, bytesRead, readPool, bytesRequested) => { - this.reading = false; - if (err) { - if (err.code && err.code === 'EAGAIN') { - if (this.isOpen()) { - this.serialPoller.start(); - } - // handle edge case were mac/unix doesn't clearly know the error. - } else if (err.code && (err.code === 'EBADF' || err.code === 'ENXIO' || (err.errno === -1 || err.code === 'UNKNOWN'))) { - this._disconnected(err); - } else { - this.fd = null; - this.readable = false; - this.emit('error', err); - } - return; - } - - // Since we will often not read the number of bytes requested, - // let's mark the ones we didn't need as available again. - this.pool.used -= bytesRequested - bytesRead; - - if (bytesRead === 0) { - if (this.isOpen()) { - this.serialPoller.start(); - } - } else { - var b = this.pool.slice(start, start + bytesRead); - - // do not emit events if the stream is paused - if (this.paused) { - if (!this.buffer) { - this.buffer = Buffer.alloc(0); - } - this.buffer = Buffer.concat([this.buffer, b]); - return; - } - this._emitData(b); - - // do not emit events anymore after we declared the stream unreadable - if (!this.readable) { - return; - } - this._read(); - } - }; - - fs.read(this.fd, this.pool, this.pool.used, toRead, null, (err, bytesRead) => { - var readPool = this.pool; - var bytesRequested = toRead; - _afterRead(err, bytesRead, readPool, bytesRequested); - }); - - this.pool.used += toRead; - }; - - SerialPort.prototype._emitData = function(data) { - this.options.dataCallback(data); - }; - - SerialPort.prototype.pause = function() { - this.paused = true; - }; - - SerialPort.prototype.resume = function() { - this.paused = false; - - if (this.buffer) { - var buffer = this.buffer; - this.buffer = null; - this._emitData(buffer); - } - - // No longer open? - if (!this.isOpen()) { - return; - } - - this._read(); - }; -} // if !'win32' - -SerialPort.prototype._disconnected = function(err) { - this.paused = true; - this.emit('disconnect', err); - if (this.closing) { - return; - } - - if (this.fd === null) { - return; - } - - this.closing = true; - if (process.platform !== 'win32') { - this.readable = false; - this.serialPoller.close(); - } - - SerialPortBinding.close(this.fd, (err) => { - this.closing = false; - if (err) { - debug('Disconnect close completed with error: ', err); - } - this.fd = null; - this.emit('close'); - }); -}; - -SerialPort.prototype.close = function(callback) { - this.paused = true; - - if (this.closing) { - debug('close attempted, but port is already closing'); - return this._error(new Error('Port is not open'), callback); - } - - if (!this.isOpen()) { - debug('close attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - this.closing = true; - - // Stop polling before closing the port. - if (process.platform !== 'win32') { - this.readable = false; - this.serialPoller.close(); - } - SerialPortBinding.close(this.fd, (err) => { - this.closing = false; - if (err) { - debug('SerialPortBinding.close had an error', err); - return this._error(err, callback); - } - - this.fd = null; - this.emit('close'); - if (callback) { - callback.call(this, null); - } - }); -}; - -SerialPort.prototype.flush = function(callback) { - if (!this.isOpen()) { - debug('flush attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - SerialPortBinding.flush(this.fd, (err, result) => { - if (err) { - debug('SerialPortBinding.flush had an error', err); - return this._error(err, callback); - } - if (callback) { - callback.call(this, null, result); - } - }); -}; - -SerialPort.prototype.set = function(options, callback) { - if (!this.isOpen()) { - debug('set attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - options = options || {}; - if (!callback && typeof options === 'function') { - callback = options; - options = {}; - } - - var settings = {}; - for (var i = SET_OPTIONS.length - 1; i >= 0; i--) { - var flag = SET_OPTIONS[i]; - if (options[flag] !== undefined) { - settings[flag] = options[flag]; - } else { - settings[flag] = defaultSetFlags[flag]; - } - } - - SerialPortBinding.set(this.fd, settings, (err) => { - if (err) { - debug('SerialPortBinding.set had an error', err); - return this._error(err, callback); - } - if (callback) { - callback.call(this, null); - } - }); -}; - -SerialPort.prototype.drain = function(callback) { - if (!this.isOpen()) { - debug('drain attempted, but port is not open'); - return this._error(new Error('Port is not open'), callback); - } - - SerialPortBinding.drain(this.fd, (err) => { - if (err) { - debug('SerialPortBinding.drain had an error', err); - return this._error(err, callback); - } - if (callback) { - callback.call(this, null); - } - }); -}; - -SerialPort.parsers = parsers; -SerialPort.list = SerialPortBinding.list; - -// Write a depreciation warning once -Object.defineProperty(SerialPort, 'SerialPort', { - get: function() { - // console.warn('DEPRECATION: Please use `require(\'serialport\')` instead of `require(\'serialport\').SerialPort`'); - Object.defineProperty(SerialPort, 'SerialPort', { - value: SerialPort - }); - return SerialPort; - }, - configurable: true -}); - -module.exports = SerialPort; +'use strict'; + +// Copyright 2011 Chris Williams + +const _debug = false; +const debug = (message) => { + if (_debug) console.log(message); +}; + +// shims +// Internal Dependencies +var SerialPortBinding = require('./bindings'); +var parsers = require('./parsers'); + +// Built-ins Dependencies +var fs = require('fs'); +var stream = require('stream'); +var util = require('util'); + +// VALIDATION ARRAYS +var DATABITS = [5, 6, 7, 8]; +var STOPBITS = [1, 1.5, 2]; +var PARITY = ['none', 'even', 'mark', 'odd', 'space']; +var FLOWCONTROLS = ['xon', 'xoff', 'xany', 'rtscts']; +var SET_OPTIONS = ['brk', 'cts', 'dtr', 'dts', 'rts']; + +// Stuff from ReadStream, refactored for our usage: +var kPoolSize = 40 * 1024; +var kMinPoolSpace = 128; + +var defaultSettings = { + baudRate: 9600, + autoOpen: true, + parity: 'none', + xon: false, + xoff: false, + xany: false, + rtscts: false, + hupcl: true, + dataBits: 8, + stopBits: 1, + bufferSize: 64 * 1024, + lock: true, + parser: parsers.raw, + platformOptions: SerialPortBinding.platformOptions +}; + +var defaultSetFlags = { + brk: false, + cts: false, + dtr: true, + dts: false, + rts: true +}; + +// deprecate the lowercase version of these options next major release +var LOWERCASE_OPTIONS = [ + 'baudRate', + 'dataBits', + 'stopBits', + 'bufferSize', + 'platformOptions' +]; + +function correctOptions(options) { + LOWERCASE_OPTIONS.forEach((name) => { + var lowerName = name.toLowerCase(); + if (options.hasOwnProperty(lowerName)) { + var value = options[lowerName]; + delete options[lowerName]; + options[name] = value; + } + }); + return options; +} + +function SerialPort(path, options, callback) { + if (typeof callback === 'boolean') { + throw new TypeError('`openImmediately` is now called `autoOpen` and is a property of options'); + } + + if (typeof options === 'function') { + callback = options; + options = {}; + } + + options = options || {}; + + stream.Stream.call(this); + + if (!path) { + throw new TypeError('No path specified'); + } + + this.path = path; + + var correctedOptions = correctOptions(options); + var settings = Object.assign({}, defaultSettings, correctedOptions); + + if (typeof settings.baudRate !== 'number') { + throw new TypeError(`Invalid "baudRate" must be a number got: ${settings.baudRate}`); + } + + if (DATABITS.indexOf(settings.dataBits) === -1) { + throw new TypeError(`Invalid "databits": ${settings.dataBits}`); + } + + if (STOPBITS.indexOf(settings.stopBits) === -1) { + throw new TypeError(`Invalid "stopbits": ${settings.stopBits}`); + } + + if (PARITY.indexOf(settings.parity) === -1) { + throw new TypeError(`Invalid "parity": ${settings.parity}`); + } + + FLOWCONTROLS.forEach((control) => { + if (typeof settings[control] !== 'boolean') { + throw new TypeError(`Invalid "${control}" is not boolean`); + } + }); + + settings.disconnectedCallback = this._disconnected.bind(this); + settings.dataCallback = settings.parser.bind(this, this); + + this.fd = null; + this.paused = true; + this.opening = false; + this.closing = false; + + if (process.platform !== 'win32') { + this.bufferSize = settings.bufferSize; + this.readable = true; + this.reading = false; + } + + this.options = settings; + + if (this.options.autoOpen) { + // is nextTick necessary? + process.nextTick(this.open.bind(this, callback)); + } +} + +util.inherits(SerialPort, stream.Stream); + +SerialPort.prototype._error = function(error, callback) { + if (callback) { + callback.call(this, error); + } else { + this.emit('error', error); + } +}; + +SerialPort.prototype.open = function(callback) { + if (this.isOpen()) { + return this._error(new Error('Port is already open'), callback); + } + + if (this.opening) { + return this._error(new Error('Port is opening'), callback); + } + + this.paused = true; + this.readable = true; + this.reading = false; + this.opening = true; + + SerialPortBinding.open(this.path, this.options, (err, fd) => { + this.opening = false; + if (err) { + debug('SerialPortBinding.open had an error', err); + return this._error(err, callback); + } + this.fd = fd; + this.paused = false; + + if (process.platform !== 'win32') { + this.serialPoller = new SerialPortBinding.SerialportPoller(this.fd, (err) => { + if (!err) { + this._read(); + } else { + this._disconnected(err); + } + }); + this.serialPoller.start(); + } + + this.emit('open'); + if (callback) { + callback.call(this, null); + } + }); +}; + +SerialPort.prototype.update = function(options, callback) { + if (!this.isOpen()) { + debug('update attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + var correctedOptions = correctOptions(options); + var settings = Object.assign({}, defaultSettings, correctedOptions); + this.options.baudRate = settings.baudRate; + + SerialPortBinding.update(this.fd, this.options, (err) => { + if (err) { + return this._error(err, callback); + } + if (callback) { + callback.call(this, null); + } + }); +}; + +SerialPort.prototype.isOpen = function() { + return this.fd !== null && !this.closing; +}; + +SerialPort.prototype.write = function(buffer, ending, callback) { + if (!this.isOpen()) { + debug('write attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + if (!Buffer.isBuffer(buffer)) { + buffer = Buffer.from(buffer); + } + + switch (ending) { + case 'Newline': + buffer = Buffer.concat([buffer, Buffer.from('\n')]); + break; + case 'Carriage return': + buffer = Buffer.concat([buffer, Buffer.from('\r')]); + break; + case 'Both NL & CR': + buffer = Buffer.concat([buffer, Buffer.from('\r\n')]); + break; + default: + break; + } + + debug(`write ${buffer.length} bytes of data`); + SerialPortBinding.write(this.fd, buffer, (err) => { + if (err) { + debug('SerialPortBinding.write had an error', err); + return this._error(err, callback); + } + if (callback) { + callback.call(this, null); + } + }); +}; + +if (process.platform !== 'win32') { + SerialPort.prototype._read = function() { + if (!this.readable || this.paused || this.reading || this.closing) { + return; + } + + this.reading = true; + + if (!this.pool || this.pool.length - this.pool.used < kMinPoolSpace) { + // discard the old pool. Can't add to the free list because + // users might have references to slices on it. + this.pool = Buffer.alloc(kPoolSize); + this.pool.used = 0; + } + + // Grab another reference to the pool in the case that while we're in the + // thread pool another read() finishes up the pool, and allocates a new + // one. + var toRead = Math.min(this.pool.length - this.pool.used, ~~this.bufferSize); + var start = this.pool.used; + + var _afterRead = (err, bytesRead, readPool, bytesRequested) => { + this.reading = false; + if (err) { + if (err.code && err.code === 'EAGAIN') { + if (this.isOpen()) { + this.serialPoller.start(); + } + // handle edge case were mac/unix doesn't clearly know the error. + } else if (err.code && (err.code === 'EBADF' || err.code === 'ENXIO' || (err.errno === -1 || err.code === 'UNKNOWN'))) { + this._disconnected(err); + } else { + this.fd = null; + this.readable = false; + this.emit('error', err); + } + return; + } + + // Since we will often not read the number of bytes requested, + // let's mark the ones we didn't need as available again. + this.pool.used -= bytesRequested - bytesRead; + + if (bytesRead === 0) { + if (this.isOpen()) { + this.serialPoller.start(); + } + } else { + var b = this.pool.slice(start, start + bytesRead); + + // do not emit events if the stream is paused + if (this.paused) { + if (!this.buffer) { + this.buffer = Buffer.alloc(0); + } + this.buffer = Buffer.concat([this.buffer, b]); + return; + } + this._emitData(b); + + // do not emit events anymore after we declared the stream unreadable + if (!this.readable) { + return; + } + this._read(); + } + }; + + fs.read(this.fd, this.pool, this.pool.used, toRead, null, (err, bytesRead) => { + var readPool = this.pool; + var bytesRequested = toRead; + _afterRead(err, bytesRead, readPool, bytesRequested); + }); + + this.pool.used += toRead; + }; + + SerialPort.prototype._emitData = function(data) { + this.options.dataCallback(data); + }; + + SerialPort.prototype.pause = function() { + this.paused = true; + }; + + SerialPort.prototype.resume = function() { + this.paused = false; + + if (this.buffer) { + var buffer = this.buffer; + this.buffer = null; + this._emitData(buffer); + } + + // No longer open? + if (!this.isOpen()) { + return; + } + + this._read(); + }; +} // if !'win32' + +SerialPort.prototype._disconnected = function(err) { + this.paused = true; + this.emit('disconnect', err); + if (this.closing) { + return; + } + + if (this.fd === null) { + return; + } + + this.closing = true; + if (process.platform !== 'win32') { + this.readable = false; + this.serialPoller.close(); + } + + SerialPortBinding.close(this.fd, (err) => { + this.closing = false; + if (err) { + debug('Disconnect close completed with error: ', err); + } + this.fd = null; + this.emit('close'); + }); +}; + +SerialPort.prototype.close = function(callback) { + this.paused = true; + + if (this.closing) { + debug('close attempted, but port is already closing'); + return this._error(new Error('Port is not open'), callback); + } + + if (!this.isOpen()) { + debug('close attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + this.closing = true; + + // Stop polling before closing the port. + if (process.platform !== 'win32') { + this.readable = false; + this.serialPoller.close(); + } + SerialPortBinding.close(this.fd, (err) => { + this.closing = false; + if (err) { + debug('SerialPortBinding.close had an error', err); + return this._error(err, callback); + } + + this.fd = null; + this.emit('close'); + if (callback) { + callback.call(this, null); + } + }); +}; + +SerialPort.prototype.flush = function(callback) { + if (!this.isOpen()) { + debug('flush attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + SerialPortBinding.flush(this.fd, (err, result) => { + if (err) { + debug('SerialPortBinding.flush had an error', err); + return this._error(err, callback); + } + if (callback) { + callback.call(this, null, result); + } + }); +}; + +SerialPort.prototype.set = function(options, callback) { + if (!this.isOpen()) { + debug('set attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + options = options || {}; + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + var settings = {}; + for (var i = SET_OPTIONS.length - 1; i >= 0; i--) { + var flag = SET_OPTIONS[i]; + if (options[flag] !== undefined) { + settings[flag] = options[flag]; + } else { + settings[flag] = defaultSetFlags[flag]; + } + } + + SerialPortBinding.set(this.fd, settings, (err) => { + if (err) { + debug('SerialPortBinding.set had an error', err); + return this._error(err, callback); + } + if (callback) { + callback.call(this, null); + } + }); +}; + +SerialPort.prototype.drain = function(callback) { + if (!this.isOpen()) { + debug('drain attempted, but port is not open'); + return this._error(new Error('Port is not open'), callback); + } + + SerialPortBinding.drain(this.fd, (err) => { + if (err) { + debug('SerialPortBinding.drain had an error', err); + return this._error(err, callback); + } + if (callback) { + callback.call(this, null); + } + }); +}; + +SerialPort.parsers = parsers; +SerialPort.list = SerialPortBinding.list; + +// Write a depreciation warning once +Object.defineProperty(SerialPort, 'SerialPort', { + get: function() { + // console.warn('DEPRECATION: Please use `require(\'serialport\')` instead of `require(\'serialport\').SerialPort`'); + Object.defineProperty(SerialPort, 'SerialPort', { + value: SerialPort + }); + return SerialPort; + }, + configurable: true +}); + +module.exports = SerialPort; diff --git a/vendor/node-usb-native/license b/vendor/node-usb-native/license index 8cff664c4..4322c5ab6 100644 --- a/vendor/node-usb-native/license +++ b/vendor/node-usb-native/license @@ -1,19 +1,19 @@ -Copyright (c) 2013 Kaba AG - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +Copyright (c) 2013 Kaba AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/node-usb-native/package.json b/vendor/node-usb-native/package.json index c62428c71..7779f1140 100644 --- a/vendor/node-usb-native/package.json +++ b/vendor/node-usb-native/package.json @@ -1,34 +1,34 @@ -{ - "name": "usb-native", - "version": "0.0.1", - "description": "node-usb && node-serialport combined.", - "main": "lib/index.js", - "gypfile": true, - "keywords": [ - "usb", - "device", - "hardware", - "list", - "insert", - "add", - "remove", - "change", - "plug", - "unplug", - "notification" - ], - "license": "MIT", - "scripts": { - "install": "node-gyp rebuild --target=1.6.6 --arch=x64 --dist-url=https://atom.io/download/electron" - }, - "dependencies": { - "eventemitter2": "^4.1.0" - }, - "devDependencies": { - "chai": "^3.0.0", - "chai-as-promised": "^5.1.0", - "chalk": "^1.0.0", - "mocha": "^2.2.5", - "nan": "^2.12.1" - } +{ + "name": "usb-native", + "version": "0.0.1", + "description": "node-usb && node-serialport combined.", + "main": "lib/index.js", + "gypfile": true, + "keywords": [ + "usb", + "device", + "hardware", + "list", + "insert", + "add", + "remove", + "change", + "plug", + "unplug", + "notification" + ], + "license": "MIT", + "scripts": { + "install": "node-gyp rebuild --target=1.6.6 --arch=x64 --dist-url=https://atom.io/download/electron" + }, + "dependencies": { + "eventemitter2": "^4.1.0" + }, + "devDependencies": { + "chai": "^3.0.0", + "chai-as-promised": "^5.1.0", + "chalk": "^1.0.0", + "mocha": "^2.2.5", + "nan": "^2.12.1" + } } \ No newline at end of file diff --git a/vendor/node-usb-native/src/combined.cpp b/vendor/node-usb-native/src/combined.cpp index a7f4cc0ff..28c3ec526 100644 --- a/vendor/node-usb-native/src/combined.cpp +++ b/vendor/node-usb-native/src/combined.cpp @@ -1,24 +1,24 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" { - void init_serialport(v8::Handle target); -#ifndef DISABLE_USB_DETECTOR - void init_detector(v8::Handle target); -#endif - void initAll(v8::Handle target) { - init_serialport(target); - #ifndef DISABLE_USB_DETECTOR - init_detector(target); - #endif - } -} - -NODE_MODULE(detection, initAll); +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + void init_serialport( v8::Local target); +#ifndef DISABLE_USB_DETECTOR + void init_detector( v8::Local target); +#endif + void initAll( v8::Local target) { + init_serialport(target); + #ifndef DISABLE_USB_DETECTOR + init_detector(target); + #endif + } +} + +NODE_MODULE(detection, initAll); diff --git a/vendor/node-usb-native/src/detection.cpp b/vendor/node-usb-native/src/detection.cpp index 5a16729f7..13f7bdc6a 100644 --- a/vendor/node-usb-native/src/detection.cpp +++ b/vendor/node-usb-native/src/detection.cpp @@ -1,222 +1,222 @@ -#include "detection.h" - - -#define OBJECT_ITEM_LOCATION_ID "locationId" -#define OBJECT_ITEM_VENDOR_ID "vendorId" -#define OBJECT_ITEM_PRODUCT_ID "productId" -#define OBJECT_ITEM_DEVICE_NAME "deviceName" -#define OBJECT_ITEM_MANUFACTURER "manufacturer" -#define OBJECT_ITEM_SERIAL_NUMBER "serialNumber" -#define OBJECT_ITEM_DEVICE_ADDRESS "deviceAddress" - - -Nan::Callback* addedCallback; -bool isAddedRegistered = false; - -Nan::Callback* removedCallback; -bool isRemovedRegistered = false; - -void RegisterAdded(const Nan::FunctionCallbackInfo& args) { - Nan::HandleScope scope; - - v8::Local callback; - - if (args.Length() == 0) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - if (args.Length() == 1) { - // callback - if(!args[0]->IsFunction()) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - callback = args[0].As(); - } - - addedCallback = new Nan::Callback(callback); - isAddedRegistered = true; -} - -void NotifyAdded(ListResultItem_t* it) { - Nan::HandleScope scope; - - if (it == NULL) { - return; - } - - if (isAddedRegistered){ - v8::Local argv[1]; - v8::Local item = Nan::New(); - item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New(it->locationId)); - item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New(it->vendorId)); - item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New(it->productId)); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New(it->deviceName.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New(it->manufacturer.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New(it->serialNumber.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New(it->deviceAddress)); - argv[0] = item; - - addedCallback->Call(1, argv); - } -} - -void RegisterRemoved(const Nan::FunctionCallbackInfo& args) { - Nan::HandleScope scope; - - v8::Local callback; - - if (args.Length() == 0) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - if (args.Length() == 1) { - // callback - if(!args[0]->IsFunction()) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - callback = args[0].As(); - } - - removedCallback = new Nan::Callback(callback); - isRemovedRegistered = true; -} - -void NotifyRemoved(ListResultItem_t* it) { - Nan::HandleScope scope; - - if (it == NULL) { - return; - } - - if (isRemovedRegistered) { - v8::Local argv[1]; - v8::Local item = Nan::New(); - item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New(it->locationId)); - item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New(it->vendorId)); - item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New(it->productId)); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New(it->deviceName.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New(it->manufacturer.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New(it->serialNumber.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New(it->deviceAddress)); - argv[0] = item; - - removedCallback->Call(1, argv); - } -} - -void Find(const Nan::FunctionCallbackInfo& args) { - Nan::HandleScope scope; - - int vid = 0; - int pid = 0; - v8::Local callback; - - if (args.Length() == 0) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - if (args.Length() == 3) { - if (args[0]->IsNumber() && args[1]->IsNumber()) { - vid = (int) args[0]->NumberValue(); - pid = (int) args[1]->NumberValue(); - } - - // callback - if(!args[2]->IsFunction()) { - return Nan::ThrowTypeError("Third argument must be a function"); - } - - callback = args[2].As(); - } - - if (args.Length() == 2) { - if (args[0]->IsNumber()) { - vid = (int) args[0]->NumberValue(); - } - - // callback - if(!args[1]->IsFunction()) { - return Nan::ThrowTypeError("Second argument must be a function"); - } - - callback = args[1].As(); - } - - if (args.Length() == 1) { - // callback - if(!args[0]->IsFunction()) { - return Nan::ThrowTypeError("First argument must be a function"); - } - - callback = args[0].As(); - } - - ListBaton* baton = new ListBaton(); - strcpy(baton->errorString, ""); - baton->callback = new Nan::Callback(callback); - baton->vid = vid; - baton->pid = pid; - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_Find, (uv_after_work_cb)EIO_AfterFind); -} - -void EIO_AfterFind(uv_work_t* req) { - Nan::HandleScope scope; - - ListBaton* data = static_cast(req->data); - - v8::Local argv[2]; - if(data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - argv[1] = Nan::Undefined(); - } - else { - v8::Local results = Nan::New(); - int i = 0; - for(std::list::iterator it = data->results.begin(); it != data->results.end(); it++, i++) { - v8::Local item = Nan::New(); - item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New((*it)->locationId)); - item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New((*it)->vendorId)); - item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New((*it)->productId)); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New((*it)->deviceName.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New((*it)->manufacturer.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New((*it)->serialNumber.c_str()).ToLocalChecked()); - item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New((*it)->deviceAddress)); - results->Set(i, item); - } - argv[0] = Nan::Undefined(); - argv[1] = results; - } - - data->callback->Call(2, argv); - - for(std::list::iterator it = data->results.begin(); it != data->results.end(); it++) { - delete *it; - } - delete data; - delete req; -} - -void StartMonitoring(const Nan::FunctionCallbackInfo& args) { - Start(); -} - -void StopMonitoring(const Nan::FunctionCallbackInfo& args) { - Stop(); -} - -extern "C" { - void init_detector (v8::Handle target) { - Nan::SetMethod(target, "find", Find); - Nan::SetMethod(target, "registerAdded", RegisterAdded); - Nan::SetMethod(target, "registerRemoved", RegisterRemoved); - Nan::SetMethod(target, "startMonitoring", StartMonitoring); - Nan::SetMethod(target, "stopMonitoring", StopMonitoring); - InitDetection(); - - } +#include "detection.h" + + +#define OBJECT_ITEM_LOCATION_ID "locationId" +#define OBJECT_ITEM_VENDOR_ID "vendorId" +#define OBJECT_ITEM_PRODUCT_ID "productId" +#define OBJECT_ITEM_DEVICE_NAME "deviceName" +#define OBJECT_ITEM_MANUFACTURER "manufacturer" +#define OBJECT_ITEM_SERIAL_NUMBER "serialNumber" +#define OBJECT_ITEM_DEVICE_ADDRESS "deviceAddress" + + +Nan::Callback* addedCallback; +bool isAddedRegistered = false; + +Nan::Callback* removedCallback; +bool isRemovedRegistered = false; + +void RegisterAdded(const Nan::FunctionCallbackInfo& args) { + Nan::HandleScope scope; + + v8::Local callback; + + if (args.Length() == 0) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + if (args.Length() == 1) { + // callback + if(!args[0]->IsFunction()) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + callback = args[0].As(); + } + + addedCallback = new Nan::Callback(callback); + isAddedRegistered = true; +} + +void NotifyAdded(ListResultItem_t* it) { + Nan::HandleScope scope; + + if (it == NULL) { + return; + } + + if (isAddedRegistered){ + v8::Local argv[1]; + v8::Local item = Nan::New(); + item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New(it->locationId)); + item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New(it->vendorId)); + item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New(it->productId)); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New(it->deviceName.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New(it->manufacturer.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New(it->serialNumber.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New(it->deviceAddress)); + argv[0] = item; + + addedCallback->Call(1, argv); + } +} + +void RegisterRemoved(const Nan::FunctionCallbackInfo& args) { + Nan::HandleScope scope; + + v8::Local callback; + + if (args.Length() == 0) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + if (args.Length() == 1) { + // callback + if(!args[0]->IsFunction()) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + callback = args[0].As(); + } + + removedCallback = new Nan::Callback(callback); + isRemovedRegistered = true; +} + +void NotifyRemoved(ListResultItem_t* it) { + Nan::HandleScope scope; + + if (it == NULL) { + return; + } + + if (isRemovedRegistered) { + v8::Local argv[1]; + v8::Local item = Nan::New(); + item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New(it->locationId)); + item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New(it->vendorId)); + item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New(it->productId)); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New(it->deviceName.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New(it->manufacturer.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New(it->serialNumber.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New(it->deviceAddress)); + argv[0] = item; + + removedCallback->Call(1, argv); + } +} + +void Find(const Nan::FunctionCallbackInfo& args) { + Nan::HandleScope scope; + + int vid = 0; + int pid = 0; + v8::Local callback; + + if (args.Length() == 0) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + if (args.Length() == 3) { + if (args[0]->IsNumber() && args[1]->IsNumber()) { + vid = (int) args[0]->NumberValue(); + pid = (int) args[1]->NumberValue(); + } + + // callback + if(!args[2]->IsFunction()) { + return Nan::ThrowTypeError("Third argument must be a function"); + } + + callback = args[2].As(); + } + + if (args.Length() == 2) { + if (args[0]->IsNumber()) { + vid = (int) args[0]->NumberValue(); + } + + // callback + if(!args[1]->IsFunction()) { + return Nan::ThrowTypeError("Second argument must be a function"); + } + + callback = args[1].As(); + } + + if (args.Length() == 1) { + // callback + if(!args[0]->IsFunction()) { + return Nan::ThrowTypeError("First argument must be a function"); + } + + callback = args[0].As(); + } + + ListBaton* baton = new ListBaton(); + strcpy(baton->errorString, ""); + baton->callback = new Nan::Callback(callback); + baton->vid = vid; + baton->pid = pid; + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_Find, (uv_after_work_cb)EIO_AfterFind); +} + +void EIO_AfterFind(uv_work_t* req) { + Nan::HandleScope scope; + + ListBaton* data = static_cast(req->data); + + v8::Local argv[2]; + if(data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + argv[1] = Nan::Undefined(); + } + else { + v8::Local results = Nan::New(); + int i = 0; + for(std::list::iterator it = data->results.begin(); it != data->results.end(); it++, i++) { + v8::Local item = Nan::New(); + item->Set(Nan::New(OBJECT_ITEM_LOCATION_ID).ToLocalChecked(), Nan::New((*it)->locationId)); + item->Set(Nan::New(OBJECT_ITEM_VENDOR_ID).ToLocalChecked(), Nan::New((*it)->vendorId)); + item->Set(Nan::New(OBJECT_ITEM_PRODUCT_ID).ToLocalChecked(), Nan::New((*it)->productId)); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_NAME).ToLocalChecked(), Nan::New((*it)->deviceName.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_MANUFACTURER).ToLocalChecked(), Nan::New((*it)->manufacturer.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_SERIAL_NUMBER).ToLocalChecked(), Nan::New((*it)->serialNumber.c_str()).ToLocalChecked()); + item->Set(Nan::New(OBJECT_ITEM_DEVICE_ADDRESS).ToLocalChecked(), Nan::New((*it)->deviceAddress)); + results->Set(i, item); + } + argv[0] = Nan::Undefined(); + argv[1] = results; + } + + data->callback->Call(2, argv); + + for(std::list::iterator it = data->results.begin(); it != data->results.end(); it++) { + delete *it; + } + delete data; + delete req; +} + +void StartMonitoring(const Nan::FunctionCallbackInfo& args) { + Start(); +} + +void StopMonitoring(const Nan::FunctionCallbackInfo& args) { + Stop(); +} + +extern "C" { + void init_detector ( v8::Local target) { + Nan::SetMethod(target, "find", Find); + Nan::SetMethod(target, "registerAdded", RegisterAdded); + Nan::SetMethod(target, "registerRemoved", RegisterRemoved); + Nan::SetMethod(target, "startMonitoring", StartMonitoring); + Nan::SetMethod(target, "stopMonitoring", StopMonitoring); + InitDetection(); + + } } \ No newline at end of file diff --git a/vendor/node-usb-native/src/detection.h b/vendor/node-usb-native/src/detection.h index 39b21c735..dbcf672cd 100644 --- a/vendor/node-usb-native/src/detection.h +++ b/vendor/node-usb-native/src/detection.h @@ -1,42 +1,42 @@ - -#ifndef _USB_DETECTION_H -#define _USB_DETECTION_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "deviceList.h" - -void Find(const Nan::FunctionCallbackInfo& args); -void EIO_Find(uv_work_t* req); -void EIO_AfterFind(uv_work_t* req); -void InitDetection(); -void StartMonitoring(const Nan::FunctionCallbackInfo& args); -void Start(); -void StopMonitoring(const Nan::FunctionCallbackInfo& args); -void Stop(); - - -struct ListBaton { - public: - //v8::Persistent callback; - Nan::Callback* callback; - std::list results; - char errorString[1024]; - int vid; - int pid; -}; - -void RegisterAdded(const Nan::FunctionCallbackInfo& args); -void NotifyAdded(ListResultItem_t* it); -void RegisterRemoved(const Nan::FunctionCallbackInfo& args); -void NotifyRemoved(ListResultItem_t* it); - -#endif + +#ifndef _USB_DETECTION_H +#define _USB_DETECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "deviceList.h" + +void Find(const Nan::FunctionCallbackInfo& args); +void EIO_Find(uv_work_t* req); +void EIO_AfterFind(uv_work_t* req); +void InitDetection(); +void StartMonitoring(const Nan::FunctionCallbackInfo& args); +void Start(); +void StopMonitoring(const Nan::FunctionCallbackInfo& args); +void Stop(); + + +struct ListBaton { + public: + //v8::Persistent callback; + Nan::Callback* callback; + std::list results; + char errorString[1024]; + int vid; + int pid; +}; + +void RegisterAdded(const Nan::FunctionCallbackInfo& args); +void NotifyAdded(ListResultItem_t* it); +void RegisterRemoved(const Nan::FunctionCallbackInfo& args); +void NotifyRemoved(ListResultItem_t* it); + +#endif diff --git a/vendor/node-usb-native/src/detection_linux.cpp b/vendor/node-usb-native/src/detection_linux.cpp index aaa618f72..4c23877ce 100644 --- a/vendor/node-usb-native/src/detection_linux.cpp +++ b/vendor/node-usb-native/src/detection_linux.cpp @@ -1,317 +1,317 @@ -#include -#include - -#include "detection.h" -#include "deviceList.h" - -using namespace std; - - - -/********************************** - * Local defines - **********************************/ -#define DEVICE_ACTION_ADDED "add" -#define DEVICE_ACTION_REMOVED "remove" - -#define DEVICE_TYPE_DEVICE "usb_device" - -#define DEVICE_PROPERTY_NAME "ID_MODEL" -#define DEVICE_PROPERTY_SERIAL "ID_SERIAL_SHORT" -#define DEVICE_PROPERTY_VENDOR "ID_VENDOR" - - -/********************************** - * Local typedefs - **********************************/ - - - -/********************************** - * Local Variables - **********************************/ -ListResultItem_t* currentItem; -bool isAdded; - -struct udev *udev; -struct udev_enumerate *enumerate; -struct udev_list_entry *devices, *dev_list_entry; -struct udev_device *dev; - -struct udev_monitor *mon; -int fd; - -pthread_t thread; -pthread_mutex_t notify_mutex; -pthread_cond_t notifyNewDevice; -pthread_cond_t notifyDeviceHandled; - -bool newDeviceAvailable = false; -bool deviceHandled = true; - -bool isRunning = false; -/********************************** - * Local Helper Functions protoypes - **********************************/ -void BuildInitialDeviceList(); - -void* ThreadFunc(void* ptr); -void WaitForDeviceHandled(); -void SignalDeviceHandled(); -void WaitForNewDevice(); -void SignalDeviceAvailable(); - -/********************************** - * Public Functions - **********************************/ -void NotifyAsync(uv_work_t* req) { - WaitForNewDevice(); -} - -void NotifyFinished(uv_work_t* req) { - if (isRunning) { - if (isAdded) { - NotifyAdded(currentItem); - } - else { - NotifyRemoved(currentItem); - } - } - - // Delete Item in case of removal - if(isAdded == false) { - delete currentItem; - } - - SignalDeviceHandled(); - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); -} - -void Start() { - isRunning = true; -} - -void Stop() { - isRunning = false; - pthread_mutex_lock(¬ify_mutex); - pthread_cond_signal(¬ifyNewDevice); - pthread_mutex_unlock(¬ify_mutex); -} - -void InitDetection() { - /* Create the udev object */ - udev = udev_new(); - if (!udev) - { - printf("Can't create udev\n"); - return; - } - - /* Set up a monitor to monitor devices */ - mon = udev_monitor_new_from_netlink(udev, "udev"); - udev_monitor_enable_receiving(mon); - - /* Get the file descriptor (fd) for the monitor. - This fd will get passed to select() */ - fd = udev_monitor_get_fd(mon); - - BuildInitialDeviceList(); - - pthread_mutex_init(¬ify_mutex, NULL); - pthread_cond_init(¬ifyNewDevice, NULL); - pthread_cond_init(¬ifyDeviceHandled, NULL); - - uv_work_t* req = new uv_work_t(); - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); - - pthread_create(&thread, NULL, ThreadFunc, NULL); - - Start(); -} - - -void EIO_Find(uv_work_t* req) { - ListBaton* data = static_cast(req->data); - - CreateFilteredList(&data->results, data->vid, data->pid); -} - -/********************************** - * Local Functions - **********************************/ -void WaitForDeviceHandled() { - pthread_mutex_lock(¬ify_mutex); - if(deviceHandled == false) { - pthread_cond_wait(¬ifyDeviceHandled, ¬ify_mutex); - } - deviceHandled = false; - pthread_mutex_unlock(¬ify_mutex); -} - -void SignalDeviceHandled() { - pthread_mutex_lock(¬ify_mutex); - deviceHandled = true; - pthread_cond_signal(¬ifyDeviceHandled); - pthread_mutex_unlock(¬ify_mutex); -} - -void WaitForNewDevice() { - pthread_mutex_lock(¬ify_mutex); - if(newDeviceAvailable == false){ - pthread_cond_wait(¬ifyNewDevice, ¬ify_mutex); - } - newDeviceAvailable = false; - pthread_mutex_unlock(¬ify_mutex); -} - -void SignalDeviceAvailable() { - pthread_mutex_lock(¬ify_mutex); - newDeviceAvailable = true; - pthread_cond_signal(¬ifyNewDevice); - pthread_mutex_unlock(¬ify_mutex); -} - - - ListResultItem_t* GetProperties(struct udev_device* dev, ListResultItem_t* item) { - struct udev_list_entry* sysattrs; - struct udev_list_entry* entry; - sysattrs = udev_device_get_properties_list_entry(dev); - udev_list_entry_foreach(entry, sysattrs) { - const char *name, *value; - name = udev_list_entry_get_name(entry); - value = udev_list_entry_get_value(entry); - - if(strcmp(name, DEVICE_PROPERTY_NAME) == 0) { - item->deviceName = value; - } - else if(strcmp(name, DEVICE_PROPERTY_SERIAL) == 0) { - item->serialNumber = value; - } - else if(strcmp(name, DEVICE_PROPERTY_VENDOR) == 0) { - item->manufacturer = value; - } - } - item->vendorId = strtol(udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16); - item->productId = strtol(udev_device_get_sysattr_value(dev,"idProduct"), NULL, 16); - item->deviceAddress = 0; - item->locationId = 0; - - return item; -} - -void DeviceAdded(struct udev_device* dev) { - DeviceItem_t* item = new DeviceItem_t(); - GetProperties(dev, &item->deviceParams); - - AddItemToList((char *)udev_device_get_devnode(dev), item); - - currentItem = &item->deviceParams; - isAdded = true; - - SignalDeviceAvailable(); -} - -void DeviceRemoved(struct udev_device* dev) { - ListResultItem_t* item = NULL; - - if(IsItemAlreadyStored((char *)udev_device_get_devnode(dev))) { - DeviceItem_t* deviceItem = GetItemFromList((char *)udev_device_get_devnode(dev)); - if(deviceItem) { - item = CopyElement(&deviceItem->deviceParams); - } - RemoveItemFromList(deviceItem); - delete deviceItem; - } - - if(item == NULL) { - item = new ListResultItem_t(); - GetProperties(dev, item); - } - - currentItem = item; - isAdded = false; - - SignalDeviceAvailable(); -} - - -void* ThreadFunc(void* ptr) { - while (1) { - /* Make the call to receive the device. - select() ensured that this will not block. */ - dev = udev_monitor_receive_device(mon); - if (dev) { - if(udev_device_get_devtype(dev) && strcmp(udev_device_get_devtype(dev), DEVICE_TYPE_DEVICE) == 0) { - if(strcmp(udev_device_get_action(dev), DEVICE_ACTION_ADDED) == 0) { - WaitForDeviceHandled(); - DeviceAdded(dev); - } - else if(strcmp(udev_device_get_action(dev), DEVICE_ACTION_REMOVED) == 0) { - WaitForDeviceHandled(); - DeviceRemoved(dev); - } - } - udev_device_unref(dev); - } - } - - return NULL; -} - - -void BuildInitialDeviceList() { - /* Create a list of the devices */ - enumerate = udev_enumerate_new(udev); - udev_enumerate_scan_devices(enumerate); - devices = udev_enumerate_get_list_entry(enumerate); - /* For each item enumerated, print out its information. - udev_list_entry_foreach is a macro which expands to - a loop. The loop will be executed for each member in - devices, setting dev_list_entry to a list entry - which contains the device's path in /sys. */ - udev_list_entry_foreach(dev_list_entry, devices) { - const char *path; - - /* Get the filename of the /sys entry for the device - and create a udev_device object (dev) representing it */ - path = udev_list_entry_get_name(dev_list_entry); - dev = udev_device_new_from_syspath(udev, path); - - /* usb_device_get_devnode() returns the path to the device node - itself in /dev. */ - if(udev_device_get_devnode(dev) == NULL || udev_device_get_sysattr_value(dev,"idVendor") == NULL) { - continue; - } - - /* From here, we can call get_sysattr_value() for each file - in the device's /sys entry. The strings passed into these - functions (idProduct, idVendor, serial, etc.) correspond - directly to the files in the /sys directory which - represents the USB device. Note that USB strings are - Unicode, UCS2 encoded, but the strings returned from - udev_device_get_sysattr_value() are UTF-8 encoded. */ - - DeviceItem_t* item = new DeviceItem_t(); - item->deviceParams.vendorId = strtol (udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16); - item->deviceParams.productId = strtol (udev_device_get_sysattr_value(dev,"idProduct"), NULL, 16); - if(udev_device_get_sysattr_value(dev,"product") != NULL) { - item->deviceParams.deviceName = udev_device_get_sysattr_value(dev,"product"); - } - if(udev_device_get_sysattr_value(dev,"manufacturer") != NULL) { - item->deviceParams.manufacturer = udev_device_get_sysattr_value(dev,"manufacturer"); - } - if(udev_device_get_sysattr_value(dev,"serial") != NULL) { - item->deviceParams.serialNumber = udev_device_get_sysattr_value(dev, "serial"); - } - item->deviceParams.deviceAddress = 0; - item->deviceParams.locationId = 0; - - item->deviceState = DeviceState_Connect; - - AddItemToList((char *)udev_device_get_devnode(dev), item); - - udev_device_unref(dev); - } - /* Free the enumerator object */ - udev_enumerate_unref(enumerate); -} +#include +#include + +#include "detection.h" +#include "deviceList.h" + +using namespace std; + + + +/********************************** + * Local defines + **********************************/ +#define DEVICE_ACTION_ADDED "add" +#define DEVICE_ACTION_REMOVED "remove" + +#define DEVICE_TYPE_DEVICE "usb_device" + +#define DEVICE_PROPERTY_NAME "ID_MODEL" +#define DEVICE_PROPERTY_SERIAL "ID_SERIAL_SHORT" +#define DEVICE_PROPERTY_VENDOR "ID_VENDOR" + + +/********************************** + * Local typedefs + **********************************/ + + + +/********************************** + * Local Variables + **********************************/ +ListResultItem_t* currentItem; +bool isAdded; + +struct udev *udev; +struct udev_enumerate *enumerate; +struct udev_list_entry *devices, *dev_list_entry; +struct udev_device *dev; + +struct udev_monitor *mon; +int fd; + +pthread_t thread; +pthread_mutex_t notify_mutex; +pthread_cond_t notifyNewDevice; +pthread_cond_t notifyDeviceHandled; + +bool newDeviceAvailable = false; +bool deviceHandled = true; + +bool isRunning = false; +/********************************** + * Local Helper Functions protoypes + **********************************/ +void BuildInitialDeviceList(); + +void* ThreadFunc(void* ptr); +void WaitForDeviceHandled(); +void SignalDeviceHandled(); +void WaitForNewDevice(); +void SignalDeviceAvailable(); + +/********************************** + * Public Functions + **********************************/ +void NotifyAsync(uv_work_t* req) { + WaitForNewDevice(); +} + +void NotifyFinished(uv_work_t* req) { + if (isRunning) { + if (isAdded) { + NotifyAdded(currentItem); + } + else { + NotifyRemoved(currentItem); + } + } + + // Delete Item in case of removal + if(isAdded == false) { + delete currentItem; + } + + SignalDeviceHandled(); + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); +} + +void Start() { + isRunning = true; +} + +void Stop() { + isRunning = false; + pthread_mutex_lock(¬ify_mutex); + pthread_cond_signal(¬ifyNewDevice); + pthread_mutex_unlock(¬ify_mutex); +} + +void InitDetection() { + /* Create the udev object */ + udev = udev_new(); + if (!udev) + { + printf("Can't create udev\n"); + return; + } + + /* Set up a monitor to monitor devices */ + mon = udev_monitor_new_from_netlink(udev, "udev"); + udev_monitor_enable_receiving(mon); + + /* Get the file descriptor (fd) for the monitor. + This fd will get passed to select() */ + fd = udev_monitor_get_fd(mon); + + BuildInitialDeviceList(); + + pthread_mutex_init(¬ify_mutex, NULL); + pthread_cond_init(¬ifyNewDevice, NULL); + pthread_cond_init(¬ifyDeviceHandled, NULL); + + uv_work_t* req = new uv_work_t(); + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); + + pthread_create(&thread, NULL, ThreadFunc, NULL); + + Start(); +} + + +void EIO_Find(uv_work_t* req) { + ListBaton* data = static_cast(req->data); + + CreateFilteredList(&data->results, data->vid, data->pid); +} + +/********************************** + * Local Functions + **********************************/ +void WaitForDeviceHandled() { + pthread_mutex_lock(¬ify_mutex); + if(deviceHandled == false) { + pthread_cond_wait(¬ifyDeviceHandled, ¬ify_mutex); + } + deviceHandled = false; + pthread_mutex_unlock(¬ify_mutex); +} + +void SignalDeviceHandled() { + pthread_mutex_lock(¬ify_mutex); + deviceHandled = true; + pthread_cond_signal(¬ifyDeviceHandled); + pthread_mutex_unlock(¬ify_mutex); +} + +void WaitForNewDevice() { + pthread_mutex_lock(¬ify_mutex); + if(newDeviceAvailable == false){ + pthread_cond_wait(¬ifyNewDevice, ¬ify_mutex); + } + newDeviceAvailable = false; + pthread_mutex_unlock(¬ify_mutex); +} + +void SignalDeviceAvailable() { + pthread_mutex_lock(¬ify_mutex); + newDeviceAvailable = true; + pthread_cond_signal(¬ifyNewDevice); + pthread_mutex_unlock(¬ify_mutex); +} + + + ListResultItem_t* GetProperties(struct udev_device* dev, ListResultItem_t* item) { + struct udev_list_entry* sysattrs; + struct udev_list_entry* entry; + sysattrs = udev_device_get_properties_list_entry(dev); + udev_list_entry_foreach(entry, sysattrs) { + const char *name, *value; + name = udev_list_entry_get_name(entry); + value = udev_list_entry_get_value(entry); + + if(strcmp(name, DEVICE_PROPERTY_NAME) == 0) { + item->deviceName = value; + } + else if(strcmp(name, DEVICE_PROPERTY_SERIAL) == 0) { + item->serialNumber = value; + } + else if(strcmp(name, DEVICE_PROPERTY_VENDOR) == 0) { + item->manufacturer = value; + } + } + item->vendorId = strtol(udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16); + item->productId = strtol(udev_device_get_sysattr_value(dev,"idProduct"), NULL, 16); + item->deviceAddress = 0; + item->locationId = 0; + + return item; +} + +void DeviceAdded(struct udev_device* dev) { + DeviceItem_t* item = new DeviceItem_t(); + GetProperties(dev, &item->deviceParams); + + AddItemToList((char *)udev_device_get_devnode(dev), item); + + currentItem = &item->deviceParams; + isAdded = true; + + SignalDeviceAvailable(); +} + +void DeviceRemoved(struct udev_device* dev) { + ListResultItem_t* item = NULL; + + if(IsItemAlreadyStored((char *)udev_device_get_devnode(dev))) { + DeviceItem_t* deviceItem = GetItemFromList((char *)udev_device_get_devnode(dev)); + if(deviceItem) { + item = CopyElement(&deviceItem->deviceParams); + } + RemoveItemFromList(deviceItem); + delete deviceItem; + } + + if(item == NULL) { + item = new ListResultItem_t(); + GetProperties(dev, item); + } + + currentItem = item; + isAdded = false; + + SignalDeviceAvailable(); +} + + +void* ThreadFunc(void* ptr) { + while (1) { + /* Make the call to receive the device. + select() ensured that this will not block. */ + dev = udev_monitor_receive_device(mon); + if (dev) { + if(udev_device_get_devtype(dev) && strcmp(udev_device_get_devtype(dev), DEVICE_TYPE_DEVICE) == 0) { + if(strcmp(udev_device_get_action(dev), DEVICE_ACTION_ADDED) == 0) { + WaitForDeviceHandled(); + DeviceAdded(dev); + } + else if(strcmp(udev_device_get_action(dev), DEVICE_ACTION_REMOVED) == 0) { + WaitForDeviceHandled(); + DeviceRemoved(dev); + } + } + udev_device_unref(dev); + } + } + + return NULL; +} + + +void BuildInitialDeviceList() { + /* Create a list of the devices */ + enumerate = udev_enumerate_new(udev); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + /* For each item enumerated, print out its information. + udev_list_entry_foreach is a macro which expands to + a loop. The loop will be executed for each member in + devices, setting dev_list_entry to a list entry + which contains the device's path in /sys. */ + udev_list_entry_foreach(dev_list_entry, devices) { + const char *path; + + /* Get the filename of the /sys entry for the device + and create a udev_device object (dev) representing it */ + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(udev, path); + + /* usb_device_get_devnode() returns the path to the device node + itself in /dev. */ + if(udev_device_get_devnode(dev) == NULL || udev_device_get_sysattr_value(dev,"idVendor") == NULL) { + continue; + } + + /* From here, we can call get_sysattr_value() for each file + in the device's /sys entry. The strings passed into these + functions (idProduct, idVendor, serial, etc.) correspond + directly to the files in the /sys directory which + represents the USB device. Note that USB strings are + Unicode, UCS2 encoded, but the strings returned from + udev_device_get_sysattr_value() are UTF-8 encoded. */ + + DeviceItem_t* item = new DeviceItem_t(); + item->deviceParams.vendorId = strtol (udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16); + item->deviceParams.productId = strtol (udev_device_get_sysattr_value(dev,"idProduct"), NULL, 16); + if(udev_device_get_sysattr_value(dev,"product") != NULL) { + item->deviceParams.deviceName = udev_device_get_sysattr_value(dev,"product"); + } + if(udev_device_get_sysattr_value(dev,"manufacturer") != NULL) { + item->deviceParams.manufacturer = udev_device_get_sysattr_value(dev,"manufacturer"); + } + if(udev_device_get_sysattr_value(dev,"serial") != NULL) { + item->deviceParams.serialNumber = udev_device_get_sysattr_value(dev, "serial"); + } + item->deviceParams.deviceAddress = 0; + item->deviceParams.locationId = 0; + + item->deviceState = DeviceState_Connect; + + AddItemToList((char *)udev_device_get_devnode(dev), item); + + udev_device_unref(dev); + } + /* Free the enumerator object */ + udev_enumerate_unref(enumerate); +} diff --git a/vendor/node-usb-native/src/detection_mac.cpp b/vendor/node-usb-native/src/detection_mac.cpp index 30f161cd1..bcdfbef31 100644 --- a/vendor/node-usb-native/src/detection_mac.cpp +++ b/vendor/node-usb-native/src/detection_mac.cpp @@ -1,461 +1,461 @@ -#include "detection.h" -#include "deviceList.h" - -#include - -#include -#include -#include -#include - -#include -#include - -#include - - -typedef struct DeviceListItem { - io_object_t notification; - IOUSBDeviceInterface** deviceInterface; - DeviceItem_t* deviceItem; -} stDeviceListItem; - -static IONotificationPortRef gNotifyPort; -static io_iterator_t gAddedIter; -static CFRunLoopRef gRunLoop; - - -CFMutableDictionaryRef matchingDict; -CFRunLoopSourceRef runLoopSource; - -static pthread_t lookupThread; - -pthread_mutex_t notify_mutex; -pthread_cond_t notifyNewDevice; -pthread_cond_t notifyDeviceHandled; - -bool newDeviceAvailable = false; -bool deviceHandled = true; - -ListResultItem_t* notify_item; -bool isAdded = false; -bool isRunning = false; -bool intialDeviceImport = true; - -void WaitForDeviceHandled(); -void SignalDeviceHandled(); -void WaitForNewDevice(); -void SignalDeviceAvailable(); - -//================================================================================================ -// -// DeviceRemoved -// -// This routine will get called whenever any kIOGeneralInterest notification happens. We are -// interested in the kIOMessageServiceIsTerminated message so that's what we look for. Other -// messages are defined in IOMessage.h. -// -//================================================================================================ -void DeviceRemoved(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) { - kern_return_t kr; - stDeviceListItem* deviceListItem = (stDeviceListItem *) refCon; - DeviceItem_t* deviceItem = deviceListItem->deviceItem; - - if(messageType == kIOMessageServiceIsTerminated) { - if(deviceListItem->deviceInterface) { - kr = (*deviceListItem->deviceInterface)->Release(deviceListItem->deviceInterface); - } - - kr = IOObjectRelease(deviceListItem->notification); - - - ListResultItem_t* item = NULL; - if(deviceItem) { - item = CopyElement(&deviceItem->deviceParams); - RemoveItemFromList(deviceItem); - delete deviceItem; - } - else { - item = new ListResultItem_t(); - } - - WaitForDeviceHandled(); - notify_item = item; - isAdded = false; - SignalDeviceAvailable(); - - } -} - -//================================================================================================ -// -// DeviceAdded -// -// This routine is the callback for our IOServiceAddMatchingNotification. When we get called -// we will look at all the devices that were added and we will: -// -// 1. Create some private data to relate to each device (in this case we use the service's name -// and the location ID of the device -// 2. Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device, -// using the refCon field to store a pointer to our private data. When we get called with -// this interest notification, we can grab the refCon and access our private data. -// -//================================================================================================ -void DeviceAdded(void *refCon, io_iterator_t iterator) { - kern_return_t kr; - io_service_t usbDevice; - IOCFPlugInInterface **plugInInterface = NULL; - SInt32 score; - HRESULT res; - - while((usbDevice = IOIteratorNext(iterator))) { - io_name_t deviceName; - CFStringRef deviceNameAsCFString; - UInt32 locationID; - UInt16 vendorId; - UInt16 productId; - UInt16 addr; - - DeviceItem_t* deviceItem = new DeviceItem_t(); - - // Get the USB device's name. - kr = IORegistryEntryGetName(usbDevice, deviceName); - if(KERN_SUCCESS != kr) { - deviceName[0] = '\0'; - } - - deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII); - - - if(deviceNameAsCFString) { - Boolean result; - char deviceName[MAXPATHLEN]; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString(deviceNameAsCFString, - deviceName, - sizeof(deviceName), - kCFStringEncodingUTF8); - - if(result) { - deviceItem->deviceParams.deviceName = deviceName; - } - - CFRelease(deviceNameAsCFString); - } - - CFStringRef manufacturerAsCFString = (CFStringRef)IORegistryEntrySearchCFProperty( - usbDevice, - kIOServicePlane, - CFSTR(kUSBVendorString), - kCFAllocatorDefault, - kIORegistryIterateRecursively - ); - - if(manufacturerAsCFString) { - Boolean result; - char manufacturer[MAXPATHLEN]; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString( - manufacturerAsCFString, - manufacturer, - sizeof(manufacturer), - kCFStringEncodingUTF8 - ); - - if(result) { - deviceItem->deviceParams.manufacturer = manufacturer; - } - - CFRelease(manufacturerAsCFString); - } - - CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty( - usbDevice, - kIOServicePlane, - CFSTR(kUSBSerialNumberString), - kCFAllocatorDefault, - kIORegistryIterateRecursively - ); - - if(serialNumberAsCFString) { - Boolean result; - char serialNumber[MAXPATHLEN]; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString( - serialNumberAsCFString, - serialNumber, - sizeof(serialNumber), - kCFStringEncodingUTF8 - ); - - if(result) { - deviceItem->deviceParams.serialNumber = serialNumber; - } - - CFRelease(serialNumberAsCFString); - } - - - // Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface - // for our device. This will create the necessary connections between our userland application and the - // kernel object for the USB Device. - kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); - - if((kIOReturnSuccess != kr) || !plugInInterface) { - fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr); - continue; - } - - stDeviceListItem *deviceListItem = new stDeviceListItem(); - - // Use the plugin interface to retrieve the device interface. - res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceListItem->deviceInterface); - - // Now done with the plugin interface. - (*plugInInterface)->Release(plugInInterface); - - if(res || deviceListItem->deviceInterface == NULL) { - fprintf(stderr, "QueryInterface returned %d.\n", (int) res); - continue; - } - - // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h. - // In this case, fetch the locationID. The locationID uniquely identifies the device - // and will remain the same, even across reboots, so long as the bus topology doesn't change. - - kr = (*deviceListItem->deviceInterface)->GetLocationID(deviceListItem->deviceInterface, &locationID); - if(KERN_SUCCESS != kr) { - fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr); - continue; - } - deviceItem->deviceParams.locationId = locationID; - - - kr = (*deviceListItem->deviceInterface)->GetDeviceAddress(deviceListItem->deviceInterface, &addr); - if(KERN_SUCCESS != kr) { - fprintf(stderr, "GetDeviceAddress returned 0x%08x.\n", kr); - continue; - } - deviceItem->deviceParams.deviceAddress = addr; - - - kr = (*deviceListItem->deviceInterface)->GetDeviceVendor(deviceListItem->deviceInterface, &vendorId); - if(KERN_SUCCESS != kr) { - fprintf(stderr, "GetDeviceVendor returned 0x%08x.\n", kr); - continue; - } - deviceItem->deviceParams.vendorId = vendorId; - - kr = (*deviceListItem->deviceInterface)->GetDeviceProduct(deviceListItem->deviceInterface, &productId); - if(KERN_SUCCESS != kr) { - fprintf(stderr, "GetDeviceProduct returned 0x%08x.\n", kr); - continue; - } - deviceItem->deviceParams.productId = productId; - - - // Extract path name as unique key - io_string_t pathName; - IORegistryEntryGetPath(usbDevice, kIOServicePlane, pathName); - deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, pathName, kCFStringEncodingASCII); - char cPathName[MAXPATHLEN]; - - if(deviceNameAsCFString) { - Boolean result; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString( - deviceNameAsCFString, - cPathName, - sizeof(cPathName), - kCFStringEncodingUTF8 - ); - - - CFRelease(deviceNameAsCFString); - } - - AddItemToList(cPathName, deviceItem); - deviceListItem->deviceItem = deviceItem; - - if(intialDeviceImport == false) { - WaitForDeviceHandled(); - notify_item = &deviceItem->deviceParams; - isAdded = true; - SignalDeviceAvailable(); - } - - // Register for an interest notification of this device being removed. Use a reference to our - // private data as the refCon which will be passed to the notification callback. - kr = IOServiceAddInterestNotification( - gNotifyPort, // notifyPort - usbDevice, // service - kIOGeneralInterest, // interestType - DeviceRemoved, // callback - deviceListItem, // refCon - &(deviceListItem->notification) // notification - ); - - if(KERN_SUCCESS != kr) { - printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr); - } - - // Done with this USB device; release the reference added by IOIteratorNext - kr = IOObjectRelease(usbDevice); - } -} - - -void WaitForDeviceHandled() { - pthread_mutex_lock(¬ify_mutex); - if(deviceHandled == false) { - pthread_cond_wait(¬ifyDeviceHandled, ¬ify_mutex); - } - deviceHandled = false; - pthread_mutex_unlock(¬ify_mutex); -} - -void SignalDeviceHandled() { - pthread_mutex_lock(¬ify_mutex); - deviceHandled = true; - pthread_cond_signal(¬ifyDeviceHandled); - pthread_mutex_unlock(¬ify_mutex); -} - -void WaitForNewDevice() { - pthread_mutex_lock(¬ify_mutex); - if(newDeviceAvailable == false) { - pthread_cond_wait(¬ifyNewDevice, ¬ify_mutex); - } - newDeviceAvailable = false; - pthread_mutex_unlock(¬ify_mutex); -} - -void SignalDeviceAvailable() { - pthread_mutex_lock(¬ify_mutex); - newDeviceAvailable = true; - pthread_cond_signal(¬ifyNewDevice); - pthread_mutex_unlock(¬ify_mutex); -} - - -void *RunLoop(void * arg) { - - runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); - - gRunLoop = CFRunLoopGetCurrent(); - CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode); - - // Start the run loop. Now we'll receive notifications. - CFRunLoopRun(); - - // We should never get here - fprintf(stderr, "Unexpectedly back from CFRunLoopRun()!\n"); - - return NULL; -} - -void NotifyAsync(uv_work_t* req) { - WaitForNewDevice(); -} - -void NotifyFinished(uv_work_t* req) { - if(isRunning) { - if(isAdded) { - NotifyAdded(notify_item); - } - else { - NotifyRemoved(notify_item); - } - } - - // Delete Item in case of removal - if(isAdded == false) { - delete notify_item; - } - - if(isRunning) { - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); - } - SignalDeviceHandled(); -} - -void Start() { - isRunning = true; -} - -void Stop() { - isRunning = false; - pthread_mutex_lock(¬ify_mutex); - pthread_cond_signal(¬ifyNewDevice); - pthread_mutex_unlock(¬ify_mutex); -} - -void InitDetection() { - - kern_return_t kr; - - // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow - // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7. - // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" - // . - // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching - // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will - // consume this dictionary reference, so there is no need to release it later on. - - // Interested in instances of class - // IOUSBDevice and its subclasses - matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - - if (matchingDict == NULL) { - fprintf(stderr, "IOServiceMatching returned NULL.\n"); - } - - // Create a notification port and add its run loop event source to our run loop - // This is how async notifications get set up. - - gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault); - - // Now set up a notification to be called when a device is first matched by I/O Kit. - kr = IOServiceAddMatchingNotification( - gNotifyPort, // notifyPort - kIOFirstMatchNotification, // notificationType - matchingDict, // matching - DeviceAdded, // callback - NULL, // refCon - &gAddedIter // notification - ); - - if (KERN_SUCCESS != kr) { - printf("IOServiceAddMatchingNotification returned 0x%08x.\n", kr); - } - - // Iterate once to get already-present devices and arm the notification - DeviceAdded(NULL, gAddedIter); - intialDeviceImport = false; - - - pthread_mutex_init(¬ify_mutex, NULL); - pthread_cond_init(¬ifyNewDevice, NULL); - pthread_cond_init(¬ifyDeviceHandled, NULL); - - int rc = pthread_create(&lookupThread, NULL, RunLoop, NULL); - if (rc) { - printf("ERROR; return code from pthread_create() is %d\n", rc); - exit(-1); - } - - uv_work_t* req = new uv_work_t(); - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); - - Start(); -} - -void EIO_Find(uv_work_t* req) { - ListBaton* data = static_cast(req->data); - - CreateFilteredList(&data->results, data->vid, data->pid); -} +#include "detection.h" +#include "deviceList.h" + +#include + +#include +#include +#include +#include + +#include +#include + +#include + + +typedef struct DeviceListItem { + io_object_t notification; + IOUSBDeviceInterface** deviceInterface; + DeviceItem_t* deviceItem; +} stDeviceListItem; + +static IONotificationPortRef gNotifyPort; +static io_iterator_t gAddedIter; +static CFRunLoopRef gRunLoop; + + +CFMutableDictionaryRef matchingDict; +CFRunLoopSourceRef runLoopSource; + +static pthread_t lookupThread; + +pthread_mutex_t notify_mutex; +pthread_cond_t notifyNewDevice; +pthread_cond_t notifyDeviceHandled; + +bool newDeviceAvailable = false; +bool deviceHandled = true; + +ListResultItem_t* notify_item; +bool isAdded = false; +bool isRunning = false; +bool intialDeviceImport = true; + +void WaitForDeviceHandled(); +void SignalDeviceHandled(); +void WaitForNewDevice(); +void SignalDeviceAvailable(); + +//================================================================================================ +// +// DeviceRemoved +// +// This routine will get called whenever any kIOGeneralInterest notification happens. We are +// interested in the kIOMessageServiceIsTerminated message so that's what we look for. Other +// messages are defined in IOMessage.h. +// +//================================================================================================ +void DeviceRemoved(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) { + kern_return_t kr; + stDeviceListItem* deviceListItem = (stDeviceListItem *) refCon; + DeviceItem_t* deviceItem = deviceListItem->deviceItem; + + if(messageType == kIOMessageServiceIsTerminated) { + if(deviceListItem->deviceInterface) { + kr = (*deviceListItem->deviceInterface)->Release(deviceListItem->deviceInterface); + } + + kr = IOObjectRelease(deviceListItem->notification); + + + ListResultItem_t* item = NULL; + if(deviceItem) { + item = CopyElement(&deviceItem->deviceParams); + RemoveItemFromList(deviceItem); + delete deviceItem; + } + else { + item = new ListResultItem_t(); + } + + WaitForDeviceHandled(); + notify_item = item; + isAdded = false; + SignalDeviceAvailable(); + + } +} + +//================================================================================================ +// +// DeviceAdded +// +// This routine is the callback for our IOServiceAddMatchingNotification. When we get called +// we will look at all the devices that were added and we will: +// +// 1. Create some private data to relate to each device (in this case we use the service's name +// and the location ID of the device +// 2. Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device, +// using the refCon field to store a pointer to our private data. When we get called with +// this interest notification, we can grab the refCon and access our private data. +// +//================================================================================================ +void DeviceAdded(void *refCon, io_iterator_t iterator) { + kern_return_t kr; + io_service_t usbDevice; + IOCFPlugInInterface **plugInInterface = NULL; + SInt32 score; + HRESULT res; + + while((usbDevice = IOIteratorNext(iterator))) { + io_name_t deviceName; + CFStringRef deviceNameAsCFString; + UInt32 locationID; + UInt16 vendorId; + UInt16 productId; + UInt16 addr; + + DeviceItem_t* deviceItem = new DeviceItem_t(); + + // Get the USB device's name. + kr = IORegistryEntryGetName(usbDevice, deviceName); + if(KERN_SUCCESS != kr) { + deviceName[0] = '\0'; + } + + deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII); + + + if(deviceNameAsCFString) { + Boolean result; + char deviceName[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString(deviceNameAsCFString, + deviceName, + sizeof(deviceName), + kCFStringEncodingUTF8); + + if(result) { + deviceItem->deviceParams.deviceName = deviceName; + } + + CFRelease(deviceNameAsCFString); + } + + CFStringRef manufacturerAsCFString = (CFStringRef)IORegistryEntrySearchCFProperty( + usbDevice, + kIOServicePlane, + CFSTR(kUSBVendorString), + kCFAllocatorDefault, + kIORegistryIterateRecursively + ); + + if(manufacturerAsCFString) { + Boolean result; + char manufacturer[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString( + manufacturerAsCFString, + manufacturer, + sizeof(manufacturer), + kCFStringEncodingUTF8 + ); + + if(result) { + deviceItem->deviceParams.manufacturer = manufacturer; + } + + CFRelease(manufacturerAsCFString); + } + + CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty( + usbDevice, + kIOServicePlane, + CFSTR(kUSBSerialNumberString), + kCFAllocatorDefault, + kIORegistryIterateRecursively + ); + + if(serialNumberAsCFString) { + Boolean result; + char serialNumber[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString( + serialNumberAsCFString, + serialNumber, + sizeof(serialNumber), + kCFStringEncodingUTF8 + ); + + if(result) { + deviceItem->deviceParams.serialNumber = serialNumber; + } + + CFRelease(serialNumberAsCFString); + } + + + // Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface + // for our device. This will create the necessary connections between our userland application and the + // kernel object for the USB Device. + kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); + + if((kIOReturnSuccess != kr) || !plugInInterface) { + fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr); + continue; + } + + stDeviceListItem *deviceListItem = new stDeviceListItem(); + + // Use the plugin interface to retrieve the device interface. + res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceListItem->deviceInterface); + + // Now done with the plugin interface. + (*plugInInterface)->Release(plugInInterface); + + if(res || deviceListItem->deviceInterface == NULL) { + fprintf(stderr, "QueryInterface returned %d.\n", (int) res); + continue; + } + + // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h. + // In this case, fetch the locationID. The locationID uniquely identifies the device + // and will remain the same, even across reboots, so long as the bus topology doesn't change. + + kr = (*deviceListItem->deviceInterface)->GetLocationID(deviceListItem->deviceInterface, &locationID); + if(KERN_SUCCESS != kr) { + fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr); + continue; + } + deviceItem->deviceParams.locationId = locationID; + + + kr = (*deviceListItem->deviceInterface)->GetDeviceAddress(deviceListItem->deviceInterface, &addr); + if(KERN_SUCCESS != kr) { + fprintf(stderr, "GetDeviceAddress returned 0x%08x.\n", kr); + continue; + } + deviceItem->deviceParams.deviceAddress = addr; + + + kr = (*deviceListItem->deviceInterface)->GetDeviceVendor(deviceListItem->deviceInterface, &vendorId); + if(KERN_SUCCESS != kr) { + fprintf(stderr, "GetDeviceVendor returned 0x%08x.\n", kr); + continue; + } + deviceItem->deviceParams.vendorId = vendorId; + + kr = (*deviceListItem->deviceInterface)->GetDeviceProduct(deviceListItem->deviceInterface, &productId); + if(KERN_SUCCESS != kr) { + fprintf(stderr, "GetDeviceProduct returned 0x%08x.\n", kr); + continue; + } + deviceItem->deviceParams.productId = productId; + + + // Extract path name as unique key + io_string_t pathName; + IORegistryEntryGetPath(usbDevice, kIOServicePlane, pathName); + deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, pathName, kCFStringEncodingASCII); + char cPathName[MAXPATHLEN]; + + if(deviceNameAsCFString) { + Boolean result; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString( + deviceNameAsCFString, + cPathName, + sizeof(cPathName), + kCFStringEncodingUTF8 + ); + + + CFRelease(deviceNameAsCFString); + } + + AddItemToList(cPathName, deviceItem); + deviceListItem->deviceItem = deviceItem; + + if(intialDeviceImport == false) { + WaitForDeviceHandled(); + notify_item = &deviceItem->deviceParams; + isAdded = true; + SignalDeviceAvailable(); + } + + // Register for an interest notification of this device being removed. Use a reference to our + // private data as the refCon which will be passed to the notification callback. + kr = IOServiceAddInterestNotification( + gNotifyPort, // notifyPort + usbDevice, // service + kIOGeneralInterest, // interestType + DeviceRemoved, // callback + deviceListItem, // refCon + &(deviceListItem->notification) // notification + ); + + if(KERN_SUCCESS != kr) { + printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr); + } + + // Done with this USB device; release the reference added by IOIteratorNext + kr = IOObjectRelease(usbDevice); + } +} + + +void WaitForDeviceHandled() { + pthread_mutex_lock(¬ify_mutex); + if(deviceHandled == false) { + pthread_cond_wait(¬ifyDeviceHandled, ¬ify_mutex); + } + deviceHandled = false; + pthread_mutex_unlock(¬ify_mutex); +} + +void SignalDeviceHandled() { + pthread_mutex_lock(¬ify_mutex); + deviceHandled = true; + pthread_cond_signal(¬ifyDeviceHandled); + pthread_mutex_unlock(¬ify_mutex); +} + +void WaitForNewDevice() { + pthread_mutex_lock(¬ify_mutex); + if(newDeviceAvailable == false) { + pthread_cond_wait(¬ifyNewDevice, ¬ify_mutex); + } + newDeviceAvailable = false; + pthread_mutex_unlock(¬ify_mutex); +} + +void SignalDeviceAvailable() { + pthread_mutex_lock(¬ify_mutex); + newDeviceAvailable = true; + pthread_cond_signal(¬ifyNewDevice); + pthread_mutex_unlock(¬ify_mutex); +} + + +void *RunLoop(void * arg) { + + runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); + + gRunLoop = CFRunLoopGetCurrent(); + CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode); + + // Start the run loop. Now we'll receive notifications. + CFRunLoopRun(); + + // We should never get here + fprintf(stderr, "Unexpectedly back from CFRunLoopRun()!\n"); + + return NULL; +} + +void NotifyAsync(uv_work_t* req) { + WaitForNewDevice(); +} + +void NotifyFinished(uv_work_t* req) { + if(isRunning) { + if(isAdded) { + NotifyAdded(notify_item); + } + else { + NotifyRemoved(notify_item); + } + } + + // Delete Item in case of removal + if(isAdded == false) { + delete notify_item; + } + + if(isRunning) { + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); + } + SignalDeviceHandled(); +} + +void Start() { + isRunning = true; +} + +void Stop() { + isRunning = false; + pthread_mutex_lock(¬ify_mutex); + pthread_cond_signal(¬ifyNewDevice); + pthread_mutex_unlock(¬ify_mutex); +} + +void InitDetection() { + + kern_return_t kr; + + // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow + // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7. + // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" + // . + // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching + // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will + // consume this dictionary reference, so there is no need to release it later on. + + // Interested in instances of class + // IOUSBDevice and its subclasses + matchingDict = IOServiceMatching(kIOUSBDeviceClassName); + + if (matchingDict == NULL) { + fprintf(stderr, "IOServiceMatching returned NULL.\n"); + } + + // Create a notification port and add its run loop event source to our run loop + // This is how async notifications get set up. + + gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault); + + // Now set up a notification to be called when a device is first matched by I/O Kit. + kr = IOServiceAddMatchingNotification( + gNotifyPort, // notifyPort + kIOFirstMatchNotification, // notificationType + matchingDict, // matching + DeviceAdded, // callback + NULL, // refCon + &gAddedIter // notification + ); + + if (KERN_SUCCESS != kr) { + printf("IOServiceAddMatchingNotification returned 0x%08x.\n", kr); + } + + // Iterate once to get already-present devices and arm the notification + DeviceAdded(NULL, gAddedIter); + intialDeviceImport = false; + + + pthread_mutex_init(¬ify_mutex, NULL); + pthread_cond_init(¬ifyNewDevice, NULL); + pthread_cond_init(¬ifyDeviceHandled, NULL); + + int rc = pthread_create(&lookupThread, NULL, RunLoop, NULL); + if (rc) { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + + uv_work_t* req = new uv_work_t(); + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); + + Start(); +} + +void EIO_Find(uv_work_t* req) { + ListBaton* data = static_cast(req->data); + + CreateFilteredList(&data->results, data->vid, data->pid); +} diff --git a/vendor/node-usb-native/src/detection_win.cpp b/vendor/node-usb-native/src/detection_win.cpp index eb02e18c4..4d6645960 100644 --- a/vendor/node-usb-native/src/detection_win.cpp +++ b/vendor/node-usb-native/src/detection_win.cpp @@ -1,471 +1,471 @@ -#include -#include -#include -#include -#include - - -// Include Windows headers -#include -#include -#include -#include -#include - -#include "detection.h" -#include "deviceList.h" - -using namespace std; - -/********************************** - * Local defines - **********************************/ -#define VID_TAG "VID_" -#define PID_TAG "PID_" - -#define LIBRARY_NAME ("setupapi.dll") - - -#define DllImport __declspec(dllimport) - -#define MAX_THREAD_WINDOW_NAME 64 - -/********************************** - * Local typedefs - **********************************/ - - - -/********************************** - * Local Variables - **********************************/ -GUID GUID_DEVINTERFACE_USB_DEVICE = { - 0xA5DCBF10L, - 0x6530, - 0x11D2, - 0x90, - 0x1F, - 0x00, - 0xC0, - 0x4F, - 0xB9, - 0x51, - 0xED -}; - -HWND handle; -DWORD threadId; -HANDLE threadHandle; - -HANDLE deviceChangedRegisteredEvent; -HANDLE deviceChangedSentEvent; - -ListResultItem_t* currentDevice; -bool isAdded; -bool isRunning = false; - -HINSTANCE hinstLib; - - -typedef BOOL (WINAPI *_SetupDiEnumDeviceInfo) (HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData); -typedef HDEVINFO (WINAPI *_SetupDiGetClassDevs) (const GUID *ClassGuid, PCTSTR Enumerator, HWND hwndParent, DWORD Flags); -typedef BOOL (WINAPI *_SetupDiDestroyDeviceInfoList) (HDEVINFO DeviceInfoSet); -typedef BOOL (WINAPI *_SetupDiGetDeviceInstanceId) (HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PTSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize); -typedef BOOL (WINAPI *_SetupDiGetDeviceRegistryProperty) (HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize); - - -_SetupDiEnumDeviceInfo DllSetupDiEnumDeviceInfo; -_SetupDiGetClassDevs DllSetupDiGetClassDevs; -_SetupDiDestroyDeviceInfoList DllSetupDiDestroyDeviceInfoList; -_SetupDiGetDeviceInstanceId DllSetupDiGetDeviceInstanceId; -_SetupDiGetDeviceRegistryProperty DllSetupDiGetDeviceRegistryProperty; - - -/********************************** - * Local Helper Functions protoypes - **********************************/ -void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam, DeviceState_t state); -DWORD WINAPI ListenerThread(LPVOID lpParam); - -void BuildInitialDeviceList(); - -void NotifyAsync(uv_work_t* req); -void NotifyFinished(uv_work_t* req); - -void ExtractDeviceInfo(HDEVINFO hDevInfo, SP_DEVINFO_DATA* pspDevInfoData, TCHAR* buf, DWORD buffSize, ListResultItem_t* resultItem); -bool CheckValidity(ListResultItem_t* item); - - -/********************************** - * Public Functions - **********************************/ -void NotifyAsync(uv_work_t* req) { - WaitForSingleObject(deviceChangedRegisteredEvent, INFINITE); -} - - -void NotifyFinished(uv_work_t* req) { - if (isRunning) { - if(isAdded) { - NotifyAdded(currentDevice); - } - else { - NotifyRemoved(currentDevice); - } - } - - // Delete Item in case of removal - if(isAdded == false) { - delete currentDevice; - } - - SetEvent(deviceChangedSentEvent); - - currentDevice = NULL; - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); -} - -void LoadFunctions() { - - bool success; - - hinstLib = LoadLibrary(LIBRARY_NAME); - - if (hinstLib != NULL) { - DllSetupDiEnumDeviceInfo = (_SetupDiEnumDeviceInfo) GetProcAddress(hinstLib, "SetupDiEnumDeviceInfo"); - - DllSetupDiGetClassDevs = (_SetupDiGetClassDevs) GetProcAddress(hinstLib, "SetupDiGetClassDevsA"); - - DllSetupDiDestroyDeviceInfoList = (_SetupDiDestroyDeviceInfoList) GetProcAddress(hinstLib, "SetupDiDestroyDeviceInfoList"); - - DllSetupDiGetDeviceInstanceId = (_SetupDiGetDeviceInstanceId) GetProcAddress(hinstLib, "SetupDiGetDeviceInstanceIdA"); - - DllSetupDiGetDeviceRegistryProperty = (_SetupDiGetDeviceRegistryProperty) GetProcAddress(hinstLib, "SetupDiGetDeviceRegistryPropertyA"); - - success = ( - DllSetupDiEnumDeviceInfo != NULL && - DllSetupDiGetClassDevs != NULL && - DllSetupDiDestroyDeviceInfoList != NULL && - DllSetupDiGetDeviceInstanceId != NULL && - DllSetupDiGetDeviceRegistryProperty != NULL - ); - } - else { - success = false; - } - - if(!success) { - printf("Could not load library functions from dll -> abort (Check if %s is available)\r\n", LIBRARY_NAME); - exit(1); - } -} - -void Start() { - isRunning = true; -} - -void Stop() { - isRunning = false; - SetEvent(deviceChangedRegisteredEvent); -} - -void InitDetection() { - - LoadFunctions(); - - deviceChangedRegisteredEvent = CreateEvent(NULL, false /* auto-reset event */, false /* non-signalled state */, ""); - deviceChangedSentEvent = CreateEvent(NULL, false /* auto-reset event */, true /* non-signalled state */, ""); - - BuildInitialDeviceList(); - - threadHandle = CreateThread( - NULL, // default security attributes - 0, // use default stack size - ListenerThread, // thread function name - NULL, // argument to thread function - 0, // use default creation flags - &threadId - ); - - uv_work_t* req = new uv_work_t(); - uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); - - Start(); -} - - -void EIO_Find(uv_work_t* req) { - - ListBaton* data = static_cast(req->data); - - CreateFilteredList(&data->results, data->vid, data->pid); -} - - -/********************************** - * Local Functions - **********************************/ -void ToUpper(char * buf) { - char* c = buf; - while (*c != '\0') { - *c = toupper((unsigned char)*c); - c++; - } -} - - -void extractVidPid(char * buf, ListResultItem_t * item) { - if(buf == NULL) { - return; - } - - ToUpper(buf); - - char* string; - char* temp; - char* pidStr, *vidStr; - int vid = 0; - int pid = 0; - - string = new char[strlen(buf) + 1]; - memcpy(string, buf, strlen(buf) + 1); - - vidStr = strstr(string, VID_TAG); - pidStr = strstr(string, PID_TAG); - - if(vidStr != NULL) { - temp = (char*) (vidStr + strlen(VID_TAG)); - temp[4] = '\0'; - vid = strtol (temp, NULL, 16); - } - - if(pidStr != NULL) { - temp = (char*) (pidStr + strlen(PID_TAG)); - temp[4] = '\0'; - pid = strtol (temp, NULL, 16); - } - item->vendorId = vid; - item->productId = pid; - - delete string; -} - - -LRESULT CALLBACK DetectCallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_DEVICECHANGE) { - if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) { - PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; - PDEV_BROADCAST_DEVICEINTERFACE pDevInf; - - if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; - UpdateDevice(pDevInf, wParam, (DBT_DEVICEARRIVAL == wParam) ? DeviceState_Connect : DeviceState_Disconnect); - } - } - } - - return 1; -} - - -DWORD WINAPI ListenerThread( LPVOID lpParam ) { - char className[MAX_THREAD_WINDOW_NAME]; - _snprintf_s(className, MAX_THREAD_WINDOW_NAME, "ListnerThreadUsbDetection_%d", GetCurrentThreadId()); - - WNDCLASSA wincl = {0}; - wincl.hInstance = GetModuleHandle(0); - wincl.lpszClassName = className; - wincl.lpfnWndProc = DetectCallback; - - if (!RegisterClassA(&wincl)) { - DWORD le = GetLastError(); - printf("RegisterClassA() failed [Error: %x]\r\n", le); - return 1; - } - - - HWND hwnd = CreateWindowExA(WS_EX_TOPMOST, className, className, 0, 0, 0, 0, 0, NULL, 0, 0, 0); - if (!hwnd) { - DWORD le = GetLastError(); - printf("CreateWindowExA() failed [Error: %x]\r\n", le); - return 1; - } - - DEV_BROADCAST_DEVICEINTERFACE_A notifyFilter = {0}; - notifyFilter.dbcc_size = sizeof(notifyFilter); - notifyFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - notifyFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; - - HDEVNOTIFY hDevNotify = RegisterDeviceNotificationA(hwnd, ¬ifyFilter, DEVICE_NOTIFY_WINDOW_HANDLE); - if (!hDevNotify) { - DWORD le = GetLastError(); - printf("RegisterDeviceNotificationA() failed [Error: %x]\r\n", le); - return 1; - } - - MSG msg; - while(TRUE) { - BOOL bRet = GetMessage(&msg, hwnd, 0, 0); - if ((bRet == 0) || (bRet == -1)) { - break; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - return 0; -} - - -void BuildInitialDeviceList() { - TCHAR buf[MAX_PATH]; - DWORD dwFlag = (DIGCF_ALLCLASSES | DIGCF_PRESENT); - HDEVINFO hDevInfo = DllSetupDiGetClassDevs(NULL, "USB", NULL, dwFlag); - - if(INVALID_HANDLE_VALUE == hDevInfo) { - return; - } - - SP_DEVINFO_DATA* pspDevInfoData = (SP_DEVINFO_DATA*) HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA)); - pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); - for(int i=0; DllSetupDiEnumDeviceInfo(hDevInfo, i, pspDevInfoData); i++) { - DWORD nSize=0 ; - - if (!DllSetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize)) { - break; - } - - DeviceItem_t* item = new DeviceItem_t(); - item->deviceState = DeviceState_Connect; - - DWORD DataT; - DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, MAX_PATH, &nSize); - - AddItemToList(buf, item); - ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, &item->deviceParams); - } - - if(pspDevInfoData) { - HeapFree(GetProcessHeap(), 0, pspDevInfoData); - } - - if(hDevInfo) { - DllSetupDiDestroyDeviceInfoList(hDevInfo); - } -} - - -void ExtractDeviceInfo(HDEVINFO hDevInfo, SP_DEVINFO_DATA* pspDevInfoData, TCHAR* buf, DWORD buffSize, ListResultItem_t* resultItem) { - - DWORD DataT; - DWORD nSize; - static int dummy = 1; - - resultItem->locationId = 0; - resultItem->deviceAddress = dummy++; - - // device found - if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, buffSize, &nSize)) { - resultItem->deviceName = buf; - } - else if ( DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, buffSize, &nSize)) - { - resultItem->deviceName = buf; - } - if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_MFG, &DataT, (PBYTE)buf, buffSize, &nSize)) { - resultItem->manufacturer = buf; - } - if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, buffSize, &nSize)) { - // Use this to extract VID / PID - extractVidPid(buf, resultItem); - } -} - - -void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam, DeviceState_t state) { - // dbcc_name: - // \\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed} - // convert to - // USB\Vid_04e8&Pid_503b\0002F9A9828E0F06 - CString szDevId = pDevInf->dbcc_name+4; - int idx = szDevId.ReverseFind(_T('#')); - - szDevId.Truncate(idx); - szDevId.Replace(_T('#'), _T('\\')); - szDevId.MakeUpper(); - - CString szClass; - idx = szDevId.Find(_T('\\')); - szClass = szDevId.Left(idx); - - // if we are adding device, we only need present devices - // otherwise, we need all devices - DWORD dwFlag = DBT_DEVICEARRIVAL != wParam ? DIGCF_ALLCLASSES : (DIGCF_ALLCLASSES | DIGCF_PRESENT); - HDEVINFO hDevInfo = DllSetupDiGetClassDevs(NULL, szClass, NULL, dwFlag); - if(INVALID_HANDLE_VALUE == hDevInfo) { - return; - } - - SP_DEVINFO_DATA* pspDevInfoData = (SP_DEVINFO_DATA*) HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA)); - pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); - for(int i=0; DllSetupDiEnumDeviceInfo(hDevInfo, i, pspDevInfoData); i++) { - DWORD nSize=0 ; - TCHAR buf[MAX_PATH]; - - if (!DllSetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize)) { - break; - } - - if(szDevId == buf) { - - WaitForSingleObject(deviceChangedSentEvent, INFINITE); - - DWORD DataT; - DWORD nSize; - DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, MAX_PATH, &nSize); - - if(state == DeviceState_Connect) { - DeviceItem_t* device = new DeviceItem_t(); - - AddItemToList(buf, device); - ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, &device->deviceParams); - - currentDevice = &device->deviceParams; - isAdded = true; - } - else { - - ListResultItem_t* item = NULL; - if(IsItemAlreadyStored(buf)) { - DeviceItem_t* deviceItem = GetItemFromList(buf); - if(deviceItem) - { - item = CopyElement(&deviceItem->deviceParams); - } - RemoveItemFromList(deviceItem); - delete deviceItem; - } - - if(item == NULL) { - item = new ListResultItem_t(); - ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, item); - } - currentDevice = item; - isAdded = false; - } - - break; - } - } - - if (pspDevInfoData) { - HeapFree(GetProcessHeap(), 0, pspDevInfoData); - } - - if(hDevInfo) { - DllSetupDiDestroyDeviceInfoList(hDevInfo); - } - - SetEvent(deviceChangedRegisteredEvent); -} +#include +#include +#include +#include +#include + + +// Include Windows headers +#include +#include +#include +#include +#include + +#include "detection.h" +#include "deviceList.h" + +using namespace std; + +/********************************** + * Local defines + **********************************/ +#define VID_TAG "VID_" +#define PID_TAG "PID_" + +#define LIBRARY_NAME ("setupapi.dll") + + +#define DllImport __declspec(dllimport) + +#define MAX_THREAD_WINDOW_NAME 64 + +/********************************** + * Local typedefs + **********************************/ + + + +/********************************** + * Local Variables + **********************************/ +GUID GUID_DEVINTERFACE_USB_DEVICE = { + 0xA5DCBF10L, + 0x6530, + 0x11D2, + 0x90, + 0x1F, + 0x00, + 0xC0, + 0x4F, + 0xB9, + 0x51, + 0xED +}; + +HWND handle; +DWORD threadId; +HANDLE threadHandle; + +HANDLE deviceChangedRegisteredEvent; +HANDLE deviceChangedSentEvent; + +ListResultItem_t* currentDevice; +bool isAdded; +bool isRunning = false; + +HINSTANCE hinstLib; + + +typedef BOOL (WINAPI *_SetupDiEnumDeviceInfo) (HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData); +typedef HDEVINFO (WINAPI *_SetupDiGetClassDevs) (const GUID *ClassGuid, PCTSTR Enumerator, HWND hwndParent, DWORD Flags); +typedef BOOL (WINAPI *_SetupDiDestroyDeviceInfoList) (HDEVINFO DeviceInfoSet); +typedef BOOL (WINAPI *_SetupDiGetDeviceInstanceId) (HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PTSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize); +typedef BOOL (WINAPI *_SetupDiGetDeviceRegistryProperty) (HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize); + + +_SetupDiEnumDeviceInfo DllSetupDiEnumDeviceInfo; +_SetupDiGetClassDevs DllSetupDiGetClassDevs; +_SetupDiDestroyDeviceInfoList DllSetupDiDestroyDeviceInfoList; +_SetupDiGetDeviceInstanceId DllSetupDiGetDeviceInstanceId; +_SetupDiGetDeviceRegistryProperty DllSetupDiGetDeviceRegistryProperty; + + +/********************************** + * Local Helper Functions protoypes + **********************************/ +void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam, DeviceState_t state); +DWORD WINAPI ListenerThread(LPVOID lpParam); + +void BuildInitialDeviceList(); + +void NotifyAsync(uv_work_t* req); +void NotifyFinished(uv_work_t* req); + +void ExtractDeviceInfo(HDEVINFO hDevInfo, SP_DEVINFO_DATA* pspDevInfoData, TCHAR* buf, DWORD buffSize, ListResultItem_t* resultItem); +bool CheckValidity(ListResultItem_t* item); + + +/********************************** + * Public Functions + **********************************/ +void NotifyAsync(uv_work_t* req) { + WaitForSingleObject(deviceChangedRegisteredEvent, INFINITE); +} + + +void NotifyFinished(uv_work_t* req) { + if (isRunning) { + if(isAdded) { + NotifyAdded(currentDevice); + } + else { + NotifyRemoved(currentDevice); + } + } + + // Delete Item in case of removal + if(isAdded == false) { + delete currentDevice; + } + + SetEvent(deviceChangedSentEvent); + + currentDevice = NULL; + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); +} + +void LoadFunctions() { + + bool success; + + hinstLib = LoadLibrary(LIBRARY_NAME); + + if (hinstLib != NULL) { + DllSetupDiEnumDeviceInfo = (_SetupDiEnumDeviceInfo) GetProcAddress(hinstLib, "SetupDiEnumDeviceInfo"); + + DllSetupDiGetClassDevs = (_SetupDiGetClassDevs) GetProcAddress(hinstLib, "SetupDiGetClassDevsA"); + + DllSetupDiDestroyDeviceInfoList = (_SetupDiDestroyDeviceInfoList) GetProcAddress(hinstLib, "SetupDiDestroyDeviceInfoList"); + + DllSetupDiGetDeviceInstanceId = (_SetupDiGetDeviceInstanceId) GetProcAddress(hinstLib, "SetupDiGetDeviceInstanceIdA"); + + DllSetupDiGetDeviceRegistryProperty = (_SetupDiGetDeviceRegistryProperty) GetProcAddress(hinstLib, "SetupDiGetDeviceRegistryPropertyA"); + + success = ( + DllSetupDiEnumDeviceInfo != NULL && + DllSetupDiGetClassDevs != NULL && + DllSetupDiDestroyDeviceInfoList != NULL && + DllSetupDiGetDeviceInstanceId != NULL && + DllSetupDiGetDeviceRegistryProperty != NULL + ); + } + else { + success = false; + } + + if(!success) { + printf("Could not load library functions from dll -> abort (Check if %s is available)\r\n", LIBRARY_NAME); + exit(1); + } +} + +void Start() { + isRunning = true; +} + +void Stop() { + isRunning = false; + SetEvent(deviceChangedRegisteredEvent); +} + +void InitDetection() { + + LoadFunctions(); + + deviceChangedRegisteredEvent = CreateEvent(NULL, false /* auto-reset event */, false /* non-signalled state */, ""); + deviceChangedSentEvent = CreateEvent(NULL, false /* auto-reset event */, true /* non-signalled state */, ""); + + BuildInitialDeviceList(); + + threadHandle = CreateThread( + NULL, // default security attributes + 0, // use default stack size + ListenerThread, // thread function name + NULL, // argument to thread function + 0, // use default creation flags + &threadId + ); + + uv_work_t* req = new uv_work_t(); + uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished); + + Start(); +} + + +void EIO_Find(uv_work_t* req) { + + ListBaton* data = static_cast(req->data); + + CreateFilteredList(&data->results, data->vid, data->pid); +} + + +/********************************** + * Local Functions + **********************************/ +void ToUpper(char * buf) { + char* c = buf; + while (*c != '\0') { + *c = toupper((unsigned char)*c); + c++; + } +} + + +void extractVidPid(char * buf, ListResultItem_t * item) { + if(buf == NULL) { + return; + } + + ToUpper(buf); + + char* string; + char* temp; + char* pidStr, *vidStr; + int vid = 0; + int pid = 0; + + string = new char[strlen(buf) + 1]; + memcpy(string, buf, strlen(buf) + 1); + + vidStr = strstr(string, VID_TAG); + pidStr = strstr(string, PID_TAG); + + if(vidStr != NULL) { + temp = (char*) (vidStr + strlen(VID_TAG)); + temp[4] = '\0'; + vid = strtol (temp, NULL, 16); + } + + if(pidStr != NULL) { + temp = (char*) (pidStr + strlen(PID_TAG)); + temp[4] = '\0'; + pid = strtol (temp, NULL, 16); + } + item->vendorId = vid; + item->productId = pid; + + delete string; +} + + +LRESULT CALLBACK DetectCallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (msg == WM_DEVICECHANGE) { + if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) { + PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; + PDEV_BROADCAST_DEVICEINTERFACE pDevInf; + + if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; + UpdateDevice(pDevInf, wParam, (DBT_DEVICEARRIVAL == wParam) ? DeviceState_Connect : DeviceState_Disconnect); + } + } + } + + return 1; +} + + +DWORD WINAPI ListenerThread( LPVOID lpParam ) { + char className[MAX_THREAD_WINDOW_NAME]; + _snprintf_s(className, MAX_THREAD_WINDOW_NAME, "ListnerThreadUsbDetection_%d", GetCurrentThreadId()); + + WNDCLASSA wincl = {0}; + wincl.hInstance = GetModuleHandle(0); + wincl.lpszClassName = className; + wincl.lpfnWndProc = DetectCallback; + + if (!RegisterClassA(&wincl)) { + DWORD le = GetLastError(); + printf("RegisterClassA() failed [Error: %x]\r\n", le); + return 1; + } + + + HWND hwnd = CreateWindowExA(WS_EX_TOPMOST, className, className, 0, 0, 0, 0, 0, NULL, 0, 0, 0); + if (!hwnd) { + DWORD le = GetLastError(); + printf("CreateWindowExA() failed [Error: %x]\r\n", le); + return 1; + } + + DEV_BROADCAST_DEVICEINTERFACE_A notifyFilter = {0}; + notifyFilter.dbcc_size = sizeof(notifyFilter); + notifyFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + notifyFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; + + HDEVNOTIFY hDevNotify = RegisterDeviceNotificationA(hwnd, ¬ifyFilter, DEVICE_NOTIFY_WINDOW_HANDLE); + if (!hDevNotify) { + DWORD le = GetLastError(); + printf("RegisterDeviceNotificationA() failed [Error: %x]\r\n", le); + return 1; + } + + MSG msg; + while(TRUE) { + BOOL bRet = GetMessage(&msg, hwnd, 0, 0); + if ((bRet == 0) || (bRet == -1)) { + break; + } + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} + + +void BuildInitialDeviceList() { + TCHAR buf[MAX_PATH]; + DWORD dwFlag = (DIGCF_ALLCLASSES | DIGCF_PRESENT); + HDEVINFO hDevInfo = DllSetupDiGetClassDevs(NULL, "USB", NULL, dwFlag); + + if(INVALID_HANDLE_VALUE == hDevInfo) { + return; + } + + SP_DEVINFO_DATA* pspDevInfoData = (SP_DEVINFO_DATA*) HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA)); + pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); + for(int i=0; DllSetupDiEnumDeviceInfo(hDevInfo, i, pspDevInfoData); i++) { + DWORD nSize=0 ; + + if (!DllSetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize)) { + break; + } + + DeviceItem_t* item = new DeviceItem_t(); + item->deviceState = DeviceState_Connect; + + DWORD DataT; + DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, MAX_PATH, &nSize); + + AddItemToList(buf, item); + ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, &item->deviceParams); + } + + if(pspDevInfoData) { + HeapFree(GetProcessHeap(), 0, pspDevInfoData); + } + + if(hDevInfo) { + DllSetupDiDestroyDeviceInfoList(hDevInfo); + } +} + + +void ExtractDeviceInfo(HDEVINFO hDevInfo, SP_DEVINFO_DATA* pspDevInfoData, TCHAR* buf, DWORD buffSize, ListResultItem_t* resultItem) { + + DWORD DataT; + DWORD nSize; + static int dummy = 1; + + resultItem->locationId = 0; + resultItem->deviceAddress = dummy++; + + // device found + if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, buffSize, &nSize)) { + resultItem->deviceName = buf; + } + else if ( DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, buffSize, &nSize)) + { + resultItem->deviceName = buf; + } + if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_MFG, &DataT, (PBYTE)buf, buffSize, &nSize)) { + resultItem->manufacturer = buf; + } + if (DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, buffSize, &nSize)) { + // Use this to extract VID / PID + extractVidPid(buf, resultItem); + } +} + + +void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam, DeviceState_t state) { + // dbcc_name: + // \\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed} + // convert to + // USB\Vid_04e8&Pid_503b\0002F9A9828E0F06 + CString szDevId = pDevInf->dbcc_name+4; + int idx = szDevId.ReverseFind(_T('#')); + + szDevId.Truncate(idx); + szDevId.Replace(_T('#'), _T('\\')); + szDevId.MakeUpper(); + + CString szClass; + idx = szDevId.Find(_T('\\')); + szClass = szDevId.Left(idx); + + // if we are adding device, we only need present devices + // otherwise, we need all devices + DWORD dwFlag = DBT_DEVICEARRIVAL != wParam ? DIGCF_ALLCLASSES : (DIGCF_ALLCLASSES | DIGCF_PRESENT); + HDEVINFO hDevInfo = DllSetupDiGetClassDevs(NULL, szClass, NULL, dwFlag); + if(INVALID_HANDLE_VALUE == hDevInfo) { + return; + } + + SP_DEVINFO_DATA* pspDevInfoData = (SP_DEVINFO_DATA*) HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA)); + pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); + for(int i=0; DllSetupDiEnumDeviceInfo(hDevInfo, i, pspDevInfoData); i++) { + DWORD nSize=0 ; + TCHAR buf[MAX_PATH]; + + if (!DllSetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize)) { + break; + } + + if(szDevId == buf) { + + WaitForSingleObject(deviceChangedSentEvent, INFINITE); + + DWORD DataT; + DWORD nSize; + DllSetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buf, MAX_PATH, &nSize); + + if(state == DeviceState_Connect) { + DeviceItem_t* device = new DeviceItem_t(); + + AddItemToList(buf, device); + ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, &device->deviceParams); + + currentDevice = &device->deviceParams; + isAdded = true; + } + else { + + ListResultItem_t* item = NULL; + if(IsItemAlreadyStored(buf)) { + DeviceItem_t* deviceItem = GetItemFromList(buf); + if(deviceItem) + { + item = CopyElement(&deviceItem->deviceParams); + } + RemoveItemFromList(deviceItem); + delete deviceItem; + } + + if(item == NULL) { + item = new ListResultItem_t(); + ExtractDeviceInfo(hDevInfo, pspDevInfoData, buf, MAX_PATH, item); + } + currentDevice = item; + isAdded = false; + } + + break; + } + } + + if (pspDevInfoData) { + HeapFree(GetProcessHeap(), 0, pspDevInfoData); + } + + if(hDevInfo) { + DllSetupDiDestroyDeviceInfoList(hDevInfo); + } + + SetEvent(deviceChangedRegisteredEvent); +} diff --git a/vendor/node-usb-native/src/deviceList.cpp b/vendor/node-usb-native/src/deviceList.cpp index 1cdcbdb1e..af9a96a0f 100644 --- a/vendor/node-usb-native/src/deviceList.cpp +++ b/vendor/node-usb-native/src/deviceList.cpp @@ -1,75 +1,75 @@ -#include -#include -#include - -#include "deviceList.h" - - -using namespace std; - -map deviceMap; - -void AddItemToList(char* key, DeviceItem_t * item) { - item->SetKey(key); - deviceMap.insert(pair(item->GetKey(), item)); -} - -void RemoveItemFromList(DeviceItem_t* item) { - deviceMap.erase(item->GetKey()); -} - -DeviceItem_t* GetItemFromList(char* key) { - map::iterator it; - - it = deviceMap.find(key); - if(it == deviceMap.end()) { - return NULL; - } - else { - return it->second; - } -} - -bool IsItemAlreadyStored(char* key) { - map::iterator it; - - it = deviceMap.find(key); - if(it == deviceMap.end()) { - return false; - } - else { - return true; - } - - return true; -} - -ListResultItem_t* CopyElement(ListResultItem_t* item) { - ListResultItem_t* dst = new ListResultItem_t(); - dst->locationId = item->locationId; - dst->vendorId = item->vendorId; - dst->productId = item->productId; - dst->deviceName = item->deviceName; - dst->manufacturer = item->manufacturer; - dst->serialNumber = item->serialNumber; - dst->deviceAddress = item->deviceAddress; - - return dst; -} - -void CreateFilteredList(list *filteredList, int vid, int pid) { - map::iterator it; - - for (it = deviceMap.begin(); it != deviceMap.end(); ++it) { - DeviceItem_t* item = it->second; - - if ( - (( vid != 0 && pid != 0) && (vid == item->deviceParams.vendorId && pid == item->deviceParams.productId)) - || ((vid != 0 && pid == 0) && vid == item->deviceParams.vendorId) - || (vid == 0 && pid == 0) - ) { - (*filteredList).push_back(CopyElement(&item->deviceParams)); - } - - } -} +#include +#include +#include + +#include "deviceList.h" + + +using namespace std; + +map deviceMap; + +void AddItemToList(char* key, DeviceItem_t * item) { + item->SetKey(key); + deviceMap.insert(pair(item->GetKey(), item)); +} + +void RemoveItemFromList(DeviceItem_t* item) { + deviceMap.erase(item->GetKey()); +} + +DeviceItem_t* GetItemFromList(char* key) { + map::iterator it; + + it = deviceMap.find(key); + if(it == deviceMap.end()) { + return NULL; + } + else { + return it->second; + } +} + +bool IsItemAlreadyStored(char* key) { + map::iterator it; + + it = deviceMap.find(key); + if(it == deviceMap.end()) { + return false; + } + else { + return true; + } + + return true; +} + +ListResultItem_t* CopyElement(ListResultItem_t* item) { + ListResultItem_t* dst = new ListResultItem_t(); + dst->locationId = item->locationId; + dst->vendorId = item->vendorId; + dst->productId = item->productId; + dst->deviceName = item->deviceName; + dst->manufacturer = item->manufacturer; + dst->serialNumber = item->serialNumber; + dst->deviceAddress = item->deviceAddress; + + return dst; +} + +void CreateFilteredList(list *filteredList, int vid, int pid) { + map::iterator it; + + for (it = deviceMap.begin(); it != deviceMap.end(); ++it) { + DeviceItem_t* item = it->second; + + if ( + (( vid != 0 && pid != 0) && (vid == item->deviceParams.vendorId && pid == item->deviceParams.productId)) + || ((vid != 0 && pid == 0) && vid == item->deviceParams.vendorId) + || (vid == 0 && pid == 0) + ) { + (*filteredList).push_back(CopyElement(&item->deviceParams)); + } + + } +} diff --git a/vendor/node-usb-native/src/deviceList.h b/vendor/node-usb-native/src/deviceList.h index 23d121bcf..6751e093c 100644 --- a/vendor/node-usb-native/src/deviceList.h +++ b/vendor/node-usb-native/src/deviceList.h @@ -1,63 +1,63 @@ -#ifndef _DEVICE_LIST_H -#define _DEVICE_LIST_H - -#include -#include - -typedef struct { - public: - int locationId; - int vendorId; - int productId; - std::string deviceName; - std::string manufacturer; - std::string serialNumber; - int deviceAddress; -} ListResultItem_t; - -typedef enum _DeviceState_t { - DeviceState_Connect, - DeviceState_Disconnect, -} DeviceState_t; - -typedef struct _DeviceItem_t { - ListResultItem_t deviceParams; - DeviceState_t deviceState; - - private: - char* key; - - - public: - _DeviceItem_t() { - key = NULL; - } - - ~_DeviceItem_t() { - if(this->key != NULL) { - delete this->key; - } - } - - void SetKey(char* key) { - if(this->key != NULL) { - delete this->key; - } - this->key = new char[strlen(key) + 1]; - memcpy(this->key, key, strlen(key) + 1); - } - - char* GetKey() { - return this->key; - } -} DeviceItem_t; - - -void AddItemToList(char* key, DeviceItem_t * item); -void RemoveItemFromList(DeviceItem_t* item); -bool IsItemAlreadyStored(char* identifier); -DeviceItem_t* GetItemFromList(char* key); -ListResultItem_t* CopyElement(ListResultItem_t* item); -void CreateFilteredList(std::list* filteredList, int vid, int pid); - -#endif +#ifndef _DEVICE_LIST_H +#define _DEVICE_LIST_H + +#include +#include + +typedef struct { + public: + int locationId; + int vendorId; + int productId; + std::string deviceName; + std::string manufacturer; + std::string serialNumber; + int deviceAddress; +} ListResultItem_t; + +typedef enum _DeviceState_t { + DeviceState_Connect, + DeviceState_Disconnect, +} DeviceState_t; + +typedef struct _DeviceItem_t { + ListResultItem_t deviceParams; + DeviceState_t deviceState; + + private: + char* key; + + + public: + _DeviceItem_t() { + key = NULL; + } + + ~_DeviceItem_t() { + if(this->key != NULL) { + delete this->key; + } + } + + void SetKey(char* key) { + if(this->key != NULL) { + delete this->key; + } + this->key = new char[strlen(key) + 1]; + memcpy(this->key, key, strlen(key) + 1); + } + + char* GetKey() { + return this->key; + } +} DeviceItem_t; + + +void AddItemToList(char* key, DeviceItem_t * item); +void RemoveItemFromList(DeviceItem_t* item); +bool IsItemAlreadyStored(char* identifier); +DeviceItem_t* GetItemFromList(char* key); +ListResultItem_t* CopyElement(ListResultItem_t* item); +void CreateFilteredList(std::list* filteredList, int vid, int pid); + +#endif diff --git a/vendor/node-usb-native/src/serialport.cpp b/vendor/node-usb-native/src/serialport.cpp index 755037b38..6e9027034 100644 --- a/vendor/node-usb-native/src/serialport.cpp +++ b/vendor/node-usb-native/src/serialport.cpp @@ -1,717 +1,717 @@ -#include "./serialport.h" - -#ifdef WIN32 -#define strncasecmp strnicmp -#else -#include "./serialport_poller.h" -#endif - -struct _WriteQueue { - const int _fd; // the fd that is associated with this write queue - QueuedWrite _write_queue; - uv_mutex_t _write_queue_mutex; - _WriteQueue *_next; - - _WriteQueue(const int fd) : _fd(fd), _write_queue(), _next(NULL) { - uv_mutex_init(&_write_queue_mutex); - } - - void lock() { uv_mutex_lock(&_write_queue_mutex); } - void unlock() { uv_mutex_unlock(&_write_queue_mutex); } - - QueuedWrite &get() { return _write_queue; } -}; - -static _WriteQueue *write_queues = NULL; - -static _WriteQueue *qForFD(const int fd) { - _WriteQueue *q = write_queues; - while (q != NULL) { - if (q->_fd == fd) { - return q; - } - q = q->_next; - } - return NULL; -} - -static _WriteQueue *newQForFD(const int fd) { - _WriteQueue *q = qForFD(fd); - - if (q == NULL) { - if (write_queues == NULL) { - write_queues = new _WriteQueue(fd); - return write_queues; - } else { - q = write_queues; - while (q->_next != NULL) { - q = q->_next; - } - q->_next = new _WriteQueue(fd); - return q->_next; - } - } - - return q; -} - -static void deleteQForFD(const int fd) { - if (write_queues == NULL) - return; - - _WriteQueue *q = write_queues; - if (write_queues->_fd == fd) { - write_queues = write_queues->_next; - delete q; - - return; - } - - while (q->_next != NULL) { - if (q->_next->_fd == fd) { - _WriteQueue *out_q = q->_next; - q->_next = q->_next->_next; - delete out_q; - - return; - } - q = q->_next; - } - - // It wasn't found... -} - -v8::Local getValueFromObject(v8::Local options, std::string key) { - v8::Local v8str = Nan::New(key).ToLocalChecked(); - return Nan::Get(options, v8str).ToLocalChecked(); -} - -int getIntFromObject(v8::Local options, std::string key) { - #if NODE_MAJOR_VERSION >= 10 - return getValueFromObject(options, key)->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - return getValueFromObject(options, key)->ToInt32()->Int32Value(); - #endif -} - -bool getBoolFromObject(v8::Local options, std::string key) { - return getValueFromObject(options, key)->ToBoolean()->BooleanValue(); -} - -v8::Local getStringFromObj(v8::Local options, std::string key) { - return getValueFromObject(options, key)->ToString(); -} - -double getDoubleFromObject(v8::Local options, std::string key) { - #if NODE_MAJOR_VERSION >= 10 - return getValueFromObject(options, key)->ToNumber(v8::Isolate::GetCurrent())->NumberValue(); - #else - return getValueFromObject(options, key)->ToNumber()->NumberValue(); - #endif -} - -NAN_METHOD(Open) { - // path - if (!info[0]->IsString()) { - Nan::ThrowTypeError("First argument must be a string"); - return; - } - v8::String::Utf8Value path(info[0]->ToString()); - - // options - if (!info[1]->IsObject()) { - Nan::ThrowTypeError("Second argument must be an object"); - return; - } - v8::Local options = info[1]->ToObject(); - - // callback - if (!info[2]->IsFunction()) { - Nan::ThrowTypeError("Third argument must be a function"); - return; - } - - OpenBaton* baton = new OpenBaton(); - memset(baton, 0, sizeof(OpenBaton)); - strcpy(baton->path, *path); - baton->baudRate = getIntFromObject(options, "baudRate"); - baton->dataBits = getIntFromObject(options, "dataBits"); - baton->bufferSize = getIntFromObject(options, "bufferSize"); - baton->parity = ToParityEnum(getStringFromObj(options, "parity")); - baton->stopBits = ToStopBitEnum(getDoubleFromObject(options, "stopBits")); - baton->rtscts = getBoolFromObject(options, "rtscts"); - baton->xon = getBoolFromObject(options, "xon"); - baton->xoff = getBoolFromObject(options, "xoff"); - baton->xany = getBoolFromObject(options, "xany"); - baton->hupcl = getBoolFromObject(options, "hupcl"); - baton->lock = getBoolFromObject(options, "lock"); - - v8::Local platformOptions = getValueFromObject(options, "platformOptions")->ToObject(); - baton->platformOptions = ParsePlatformOptions(platformOptions); - - baton->callback.Reset(info[2].As()); - baton->dataCallback = new Nan::Callback(getValueFromObject(options, "dataCallback").As()); - baton->disconnectedCallback = new Nan::Callback(getValueFromObject(options, "disconnectedCallback").As()); - baton->errorCallback = new Nan::Callback(getValueFromObject(options, "errorCallback").As()); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - - uv_queue_work(uv_default_loop(), req, EIO_Open, (uv_after_work_cb)EIO_AfterOpen); - - return; -} - -void EIO_AfterOpen(uv_work_t* req) { - Nan::HandleScope scope; - - OpenBaton* data = static_cast(req->data); - - v8::Local argv[2]; - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - argv[1] = Nan::Undefined(); - // not needed because we're not calling AfterOpenSuccess - delete data->dataCallback; - delete data->errorCallback; - delete data->disconnectedCallback; - } else { - argv[0] = Nan::Null(); - argv[1] = Nan::New(data->result); - - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = argv[1]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = argv[1]->ToInt32()->Int32Value(); - #endif - newQForFD(fd); - - AfterOpenSuccess(data->result, data->dataCallback, data->disconnectedCallback, data->errorCallback); - } - - data->callback.Call(2, argv); - - delete data->platformOptions; - delete data; - delete req; -} - -NAN_METHOD(Update) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = info[0]->ToInt32()->Int32Value(); - #endif - - // options - if (!info[1]->IsObject()) { - Nan::ThrowTypeError("Second argument must be an object"); - return; - } - v8::Local options = info[1]->ToObject(); - - if (!Nan::Has(options, Nan::New("baudRate").ToLocalChecked()).FromMaybe(false)) { - Nan::ThrowTypeError("baudRate must be set on options object"); - return; - } - - // callback - if (!info[2]->IsFunction()) { - Nan::ThrowTypeError("Third argument must be a function"); - return; - } - - ConnectionOptionsBaton* baton = new ConnectionOptionsBaton(); - memset(baton, 0, sizeof(ConnectionOptionsBaton)); - - baton->fd = fd; - #if NODE_MAJOR_VERSION >= 10 - baton->baudRate = Nan::Get(options, Nan::New("baudRate").ToLocalChecked()).ToLocalChecked()->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - baton->baudRate = Nan::Get(options, Nan::New("baudRate").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); - #endif - baton->callback.Reset(info[2].As()); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - - uv_queue_work(uv_default_loop(), req, EIO_Update, (uv_after_work_cb)EIO_AfterUpdate); - - return; -} - -void EIO_AfterUpdate(uv_work_t* req) { - Nan::HandleScope scope; - - ConnectionOptionsBaton* data = static_cast(req->data); - - v8::Local argv[1]; - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Null(); - } - - data->callback.Call(1, argv); - - delete data; - delete req; -} - -NAN_METHOD(Write) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = info[0]->ToInt32()->Int32Value(); - #endif - - // buffer - if (!info[1]->IsObject() || !node::Buffer::HasInstance(info[1])) { - Nan::ThrowTypeError("Second argument must be a buffer"); - return; - } - v8::Local buffer = info[1]->ToObject(); - char* bufferData = node::Buffer::Data(buffer); - size_t bufferLength = node::Buffer::Length(buffer); - - // callback - if (!info[2]->IsFunction()) { - Nan::ThrowTypeError("Third argument must be a function"); - return; - } - - WriteBaton* baton = new WriteBaton(); - memset(baton, 0, sizeof(WriteBaton)); - baton->fd = fd; - baton->buffer.Reset(buffer); - baton->bufferData = bufferData; - baton->bufferLength = bufferLength; - baton->offset = 0; - baton->callback.Reset(info[2].As()); - - QueuedWrite* queuedWrite = new QueuedWrite(); - memset(queuedWrite, 0, sizeof(QueuedWrite)); - queuedWrite->baton = baton; - queuedWrite->req.data = queuedWrite; - - _WriteQueue *q = qForFD(fd); - if (!q) { - Nan::ThrowTypeError("There's no write queue for that file descriptor (write)!"); - return; - } - - q->lock(); - QueuedWrite &write_queue = q->get(); - bool empty = write_queue.empty(); - - write_queue.insert_tail(queuedWrite); - - if (empty) { - uv_queue_work(uv_default_loop(), &queuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); - } - q->unlock(); - - return; -} - -void EIO_AfterWrite(uv_work_t* req) { - Nan::HandleScope scope; - - QueuedWrite* queuedWrite = static_cast(req->data); - WriteBaton* data = static_cast(queuedWrite->baton); - - v8::Local argv[1]; - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Null(); - } - - if (data->offset < data->bufferLength && !data->errorString[0]) { - // We're not done with this baton, so throw it right back onto the queue. - // Don't re-push the write in the event loop if there was an error; because same error could occur again! - // TODO: Add a uv_poll here for unix... - // fprintf(stderr, "Write again...\n"); - uv_queue_work(uv_default_loop(), req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); - return; - } - - // throwing errors instead of returning them at this point is rude - int fd = data->fd; - _WriteQueue *q = qForFD(fd); - if (!q) { - Nan::ThrowTypeError("There's no write queue for that file descriptor (after write)!"); - return; - } - - q->lock(); - QueuedWrite &write_queue = q->get(); - - // remove this one from the list - queuedWrite->remove(); - - data->callback.Call(1, argv); - - // If there are any left, start a new thread to write the next one. - if (!write_queue.empty()) { - // Always pull the next work item from the head of the queue - QueuedWrite* nextQueuedWrite = write_queue.next; - uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); - } - q->unlock(); - - data->buffer.Reset(); - delete data; - delete queuedWrite; -} - -NAN_METHOD(Close) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - - // callback - if (!info[1]->IsFunction()) { - Nan::ThrowTypeError("Second argument must be a function"); - return; - } - - CloseBaton* baton = new CloseBaton(); - memset(baton, 0, sizeof(CloseBaton)); - #if NODE_MAJOR_VERSION >= 10 - baton->fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - baton->fd = info[0]->ToInt32()->Int32Value(); - #endif - - baton->callback.Reset(info[1].As()); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_Close, (uv_after_work_cb)EIO_AfterClose); - - return; -} - -void EIO_AfterClose(uv_work_t* req) { - Nan::HandleScope scope; - CloseBaton* data = static_cast(req->data); - - v8::Local argv[1]; - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Null(); - - // We don't have an error, so clean up the write queue for that fd - _WriteQueue *q = qForFD(data->fd); - if (q) { - q->lock(); - QueuedWrite &write_queue = q->get(); - while (!write_queue.empty()) { - QueuedWrite *del_q = write_queue.next; - del_q->baton->buffer.Reset(); - del_q->remove(); - } - q->unlock(); - deleteQForFD(data->fd); - } - } - data->callback.Call(1, argv); - - delete data; - delete req; -} - -NAN_METHOD(List) { - // callback - if (!info[0]->IsFunction()) { - Nan::ThrowTypeError("First argument must be a function"); - return; - } - - ListBaton* baton = new ListBaton(); - strcpy(baton->errorString, ""); - baton->callback.Reset(info[0].As()); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_List, (uv_after_work_cb)EIO_AfterList); - - return; -} - -void setIfNotEmpty(v8::Local item, std::string key, const char *value) { - v8::Local v8key = Nan::New(key).ToLocalChecked(); - if (strlen(value) > 0) { - Nan::Set(item, v8key, Nan::New(value).ToLocalChecked()); - } else { - Nan::Set(item, v8key, Nan::Undefined()); - } - -} - -void EIO_AfterList(uv_work_t* req) { - Nan::HandleScope scope; - - ListBaton* data = static_cast(req->data); - - v8::Local argv[2]; - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - argv[1] = Nan::Undefined(); - } else { - v8::Local results = Nan::New(); - int i = 0; - for (std::list::iterator it = data->results.begin(); it != data->results.end(); ++it, i++) { - v8::Local item = Nan::New(); - - setIfNotEmpty(item, "comName", (*it)->comName.c_str()); - setIfNotEmpty(item, "manufacturer", (*it)->manufacturer.c_str()); - setIfNotEmpty(item, "serialNumber", (*it)->serialNumber.c_str()); - setIfNotEmpty(item, "pnpId", (*it)->pnpId.c_str()); - setIfNotEmpty(item, "locationId", (*it)->locationId.c_str()); - setIfNotEmpty(item, "vendorId", (*it)->vendorId.c_str()); - setIfNotEmpty(item, "productId", (*it)->productId.c_str()); - - Nan::Set(results, i, item); - } - argv[0] = Nan::Null(); - argv[1] = results; - } - data->callback.Call(2, argv); - - for (std::list::iterator it = data->results.begin(); it != data->results.end(); ++it) { - delete *it; - } - delete data; - delete req; -} - -NAN_METHOD(Flush) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = info[0]->ToInt32()->Int32Value(); - #endif - - // callback - if (!info[1]->IsFunction()) { - Nan::ThrowTypeError("Second argument must be a function"); - return; - } - v8::Local callback = info[1].As(); - - FlushBaton* baton = new FlushBaton(); - memset(baton, 0, sizeof(FlushBaton)); - baton->fd = fd; - baton->callback.Reset(callback); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_Flush, (uv_after_work_cb)EIO_AfterFlush); - - return; -} - -void EIO_AfterFlush(uv_work_t* req) { - Nan::HandleScope scope; - - FlushBaton* data = static_cast(req->data); - - v8::Local argv[2]; - - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - argv[1] = Nan::Undefined(); - } else { - argv[0] = Nan::Undefined(); - argv[1] = Nan::New(data->result); - } - - data->callback.Call(2, argv); - - delete data; - delete req; -} - -NAN_METHOD(Set) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = info[0]->ToInt32()->Int32Value(); - #endif - - // options - if (!info[1]->IsObject()) { - Nan::ThrowTypeError("Second argument must be an object"); - return; - } - v8::Local options = info[1]->ToObject(); - - // callback - if (!info[2]->IsFunction()) { - Nan::ThrowTypeError("Third argument must be a function"); - return; - } - v8::Local callback = info[2].As(); - - SetBaton* baton = new SetBaton(); - memset(baton, 0, sizeof(SetBaton)); - baton->fd = fd; - baton->callback.Reset(callback); - baton->brk = getBoolFromObject(options, "brk"); - baton->rts = getBoolFromObject(options, "rts"); - baton->cts = getBoolFromObject(options, "cts"); - baton->dtr = getBoolFromObject(options, "dtr"); - baton->dsr = getBoolFromObject(options, "dsr"); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_Set, (uv_after_work_cb)EIO_AfterSet); - - return; -} - -void EIO_AfterSet(uv_work_t* req) { - Nan::HandleScope scope; - - SetBaton* data = static_cast(req->data); - - v8::Local argv[1]; - - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Null(); - } - data->callback.Call(1, argv); - - delete data; - delete req; -} - -NAN_METHOD(Drain) { - // file descriptor - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an int"); - return; - } - int fd; - #if NODE_MAJOR_VERSION >= 10 - fd = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - fd = info[0]->ToInt32()->Int32Value(); - #endif - - // callback - if (!info[1]->IsFunction()) { - Nan::ThrowTypeError("Second argument must be a function"); - return; - } - - DrainBaton* baton = new DrainBaton(); - memset(baton, 0, sizeof(DrainBaton)); - baton->fd = fd; - baton->callback.Reset(info[1].As()); - - uv_work_t* req = new uv_work_t(); - req->data = baton; - uv_queue_work(uv_default_loop(), req, EIO_Drain, (uv_after_work_cb)EIO_AfterDrain); - - return; -} - -void EIO_AfterDrain(uv_work_t* req) { - Nan::HandleScope scope; - - DrainBaton* data = static_cast(req->data); - - v8::Local argv[1]; - - if (data->errorString[0]) { - argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Null(); - } - data->callback.Call(1, argv); - - delete data; - delete req; -} - -SerialPortParity NAN_INLINE(ToParityEnum(const v8::Local& v8str)) { - Nan::HandleScope scope; - Nan::Utf8String str(v8str); - size_t count = strlen(*str); - SerialPortParity parity = SERIALPORT_PARITY_NONE; - if (!strncasecmp(*str, "none", count)) { - parity = SERIALPORT_PARITY_NONE; - } else if (!strncasecmp(*str, "even", count)) { - parity = SERIALPORT_PARITY_EVEN; - } else if (!strncasecmp(*str, "mark", count)) { - parity = SERIALPORT_PARITY_MARK; - } else if (!strncasecmp(*str, "odd", count)) { - parity = SERIALPORT_PARITY_ODD; - } else if (!strncasecmp(*str, "space", count)) { - parity = SERIALPORT_PARITY_SPACE; - } - return parity; -} - -SerialPortStopBits NAN_INLINE(ToStopBitEnum(double stopBits)) { - if (stopBits > 1.4 && stopBits < 1.6) { - return SERIALPORT_STOPBITS_ONE_FIVE; - } - if (stopBits == 2) { - return SERIALPORT_STOPBITS_TWO; - } - return SERIALPORT_STOPBITS_ONE; -} - -extern "C" { - void init_serialport(v8::Handle target) { - Nan::HandleScope scope; - Nan::SetMethod(target, "set", Set); - Nan::SetMethod(target, "open", Open); - Nan::SetMethod(target, "update", Update); - Nan::SetMethod(target, "write", Write); - Nan::SetMethod(target, "close", Close); - Nan::SetMethod(target, "list", List); - Nan::SetMethod(target, "flush", Flush); - Nan::SetMethod(target, "drain", Drain); - -#ifndef WIN32 - SerialportPoller::Init(target); -#endif - } -} - -//NODE_MODULE(serialport, init); +#include "./serialport.h" + +#ifdef WIN32 +#define strncasecmp strnicmp +#else +#include "./serialport_poller.h" +#endif + +struct _WriteQueue { + const int _fd; // the fd that is associated with this write queue + QueuedWrite _write_queue; + uv_mutex_t _write_queue_mutex; + _WriteQueue *_next; + + _WriteQueue(const int fd) : _fd(fd), _write_queue(), _next(NULL) { + uv_mutex_init(&_write_queue_mutex); + } + + void lock() { uv_mutex_lock(&_write_queue_mutex); } + void unlock() { uv_mutex_unlock(&_write_queue_mutex); } + + QueuedWrite &get() { return _write_queue; } +}; + +static _WriteQueue *write_queues = NULL; + +static _WriteQueue *qForFD(const int fd) { + _WriteQueue *q = write_queues; + while (q != NULL) { + if (q->_fd == fd) { + return q; + } + q = q->_next; + } + return NULL; +} + +static _WriteQueue *newQForFD(const int fd) { + _WriteQueue *q = qForFD(fd); + + if (q == NULL) { + if (write_queues == NULL) { + write_queues = new _WriteQueue(fd); + return write_queues; + } else { + q = write_queues; + while (q->_next != NULL) { + q = q->_next; + } + q->_next = new _WriteQueue(fd); + return q->_next; + } + } + + return q; +} + +static void deleteQForFD(const int fd) { + if (write_queues == NULL) + return; + + _WriteQueue *q = write_queues; + if (write_queues->_fd == fd) { + write_queues = write_queues->_next; + delete q; + + return; + } + + while (q->_next != NULL) { + if (q->_next->_fd == fd) { + _WriteQueue *out_q = q->_next; + q->_next = q->_next->_next; + delete out_q; + + return; + } + q = q->_next; + } + + // It wasn't found... +} + +v8::Local getValueFromObject(v8::Local options, std::string key) { + v8::Local v8str = Nan::New(key).ToLocalChecked(); + return Nan::Get(options, v8str).ToLocalChecked(); +} + +int getIntFromObject(v8::Local options, std::string key) { + #if NODE_MAJOR_VERSION >= 10 + return Nan::To(getValueFromObject(options, key)).ToLocalChecked()->Value(); + #else + return getValueFromObject(options, key)->ToInt32()->Int32Value(); + #endif +} + +bool getBoolFromObject(v8::Local options, std::string key) { + return getValueFromObject(options, key)->ToBoolean()->BooleanValue(); +} + +v8::Local getStringFromObj(v8::Local options, std::string key) { + return getValueFromObject(options, key)->ToString(); +} + +double getDoubleFromObject(v8::Local options, std::string key) { + #if NODE_MAJOR_VERSION >= 10 + return Nan::To(getValueFromObject(options, key)).FromMaybe(0); + #else + return getValueFromObject(options, key)->ToNumber()->NumberValue(); + #endif +} + +NAN_METHOD(Open) { + // path + if (!info[0]->IsString()) { + Nan::ThrowTypeError("First argument must be a string"); + return; + } + v8::String::Utf8Value path(info[0]->ToString()); + + // options + if (!info[1]->IsObject()) { + Nan::ThrowTypeError("Second argument must be an object"); + return; + } + v8::Local options = info[1]->ToObject(); + + // callback + if (!info[2]->IsFunction()) { + Nan::ThrowTypeError("Third argument must be a function"); + return; + } + + OpenBaton* baton = new OpenBaton(); + memset(baton, 0, sizeof(OpenBaton)); + strcpy(baton->path, *path); + baton->baudRate = getIntFromObject(options, "baudRate"); + baton->dataBits = getIntFromObject(options, "dataBits"); + baton->bufferSize = getIntFromObject(options, "bufferSize"); + baton->parity = ToParityEnum(getStringFromObj(options, "parity")); + baton->stopBits = ToStopBitEnum(getDoubleFromObject(options, "stopBits")); + baton->rtscts = getBoolFromObject(options, "rtscts"); + baton->xon = getBoolFromObject(options, "xon"); + baton->xoff = getBoolFromObject(options, "xoff"); + baton->xany = getBoolFromObject(options, "xany"); + baton->hupcl = getBoolFromObject(options, "hupcl"); + baton->lock = getBoolFromObject(options, "lock"); + + v8::Local platformOptions = getValueFromObject(options, "platformOptions")->ToObject(); + baton->platformOptions = ParsePlatformOptions(platformOptions); + + baton->callback.Reset(info[2].As()); + baton->dataCallback = new Nan::Callback(getValueFromObject(options, "dataCallback").As()); + baton->disconnectedCallback = new Nan::Callback(getValueFromObject(options, "disconnectedCallback").As()); + baton->errorCallback = new Nan::Callback(getValueFromObject(options, "errorCallback").As()); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + + uv_queue_work(uv_default_loop(), req, EIO_Open, (uv_after_work_cb)EIO_AfterOpen); + + return; +} + +void EIO_AfterOpen(uv_work_t* req) { + Nan::HandleScope scope; + + OpenBaton* data = static_cast(req->data); + + v8::Local argv[2]; + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + argv[1] = Nan::Undefined(); + // not needed because we're not calling AfterOpenSuccess + delete data->dataCallback; + delete data->errorCallback; + delete data->disconnectedCallback; + } else { + argv[0] = Nan::Null(); + argv[1] = Nan::New(data->result); + + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = argv[1]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = argv[1]->ToInt32()->Int32Value(); + #endif + newQForFD(fd); + + AfterOpenSuccess(data->result, data->dataCallback, data->disconnectedCallback, data->errorCallback); + } + + data->callback.Call(2, argv); + + delete data->platformOptions; + delete data; + delete req; +} + +NAN_METHOD(Update) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = info[0]->ToInt32()->Int32Value(); + #endif + + // options + if (!info[1]->IsObject()) { + Nan::ThrowTypeError("Second argument must be an object"); + return; + } + v8::Local options = info[1]->ToObject(); + + if (!Nan::Has(options, Nan::New("baudRate").ToLocalChecked()).FromMaybe(false)) { + Nan::ThrowTypeError("baudRate must be set on options object"); + return; + } + + // callback + if (!info[2]->IsFunction()) { + Nan::ThrowTypeError("Third argument must be a function"); + return; + } + + ConnectionOptionsBaton* baton = new ConnectionOptionsBaton(); + memset(baton, 0, sizeof(ConnectionOptionsBaton)); + + baton->fd = fd; + #if NODE_MAJOR_VERSION >= 10 + baton->baudRate = Nan::Get(options, Nan::New("baudRate").ToLocalChecked()).ToLocalChecked()->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + baton->baudRate = Nan::Get(options, Nan::New("baudRate").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); + #endif + baton->callback.Reset(info[2].As()); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + + uv_queue_work(uv_default_loop(), req, EIO_Update, (uv_after_work_cb)EIO_AfterUpdate); + + return; +} + +void EIO_AfterUpdate(uv_work_t* req) { + Nan::HandleScope scope; + + ConnectionOptionsBaton* data = static_cast(req->data); + + v8::Local argv[1]; + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Null(); + } + + data->callback.Call(1, argv); + + delete data; + delete req; +} + +NAN_METHOD(Write) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = info[0]->ToInt32()->Int32Value(); + #endif + + // buffer + if (!info[1]->IsObject() || !node::Buffer::HasInstance(info[1])) { + Nan::ThrowTypeError("Second argument must be a buffer"); + return; + } + v8::Local buffer = info[1]->ToObject(); + char* bufferData = node::Buffer::Data(buffer); + size_t bufferLength = node::Buffer::Length(buffer); + + // callback + if (!info[2]->IsFunction()) { + Nan::ThrowTypeError("Third argument must be a function"); + return; + } + + WriteBaton* baton = new WriteBaton(); + memset(baton, 0, sizeof(WriteBaton)); + baton->fd = fd; + baton->buffer.Reset(buffer); + baton->bufferData = bufferData; + baton->bufferLength = bufferLength; + baton->offset = 0; + baton->callback.Reset(info[2].As()); + + QueuedWrite* queuedWrite = new QueuedWrite(); + memset(queuedWrite, 0, sizeof(QueuedWrite)); + queuedWrite->baton = baton; + queuedWrite->req.data = queuedWrite; + + _WriteQueue *q = qForFD(fd); + if (!q) { + Nan::ThrowTypeError("There's no write queue for that file descriptor (write)!"); + return; + } + + q->lock(); + QueuedWrite &write_queue = q->get(); + bool empty = write_queue.empty(); + + write_queue.insert_tail(queuedWrite); + + if (empty) { + uv_queue_work(uv_default_loop(), &queuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); + } + q->unlock(); + + return; +} + +void EIO_AfterWrite(uv_work_t* req) { + Nan::HandleScope scope; + + QueuedWrite* queuedWrite = static_cast(req->data); + WriteBaton* data = static_cast(queuedWrite->baton); + + v8::Local argv[1]; + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Null(); + } + + if (data->offset < data->bufferLength && !data->errorString[0]) { + // We're not done with this baton, so throw it right back onto the queue. + // Don't re-push the write in the event loop if there was an error; because same error could occur again! + // TODO: Add a uv_poll here for unix... + // fprintf(stderr, "Write again...\n"); + uv_queue_work(uv_default_loop(), req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); + return; + } + + // throwing errors instead of returning them at this point is rude + int fd = data->fd; + _WriteQueue *q = qForFD(fd); + if (!q) { + Nan::ThrowTypeError("There's no write queue for that file descriptor (after write)!"); + return; + } + + q->lock(); + QueuedWrite &write_queue = q->get(); + + // remove this one from the list + queuedWrite->remove(); + + data->callback.Call(1, argv); + + // If there are any left, start a new thread to write the next one. + if (!write_queue.empty()) { + // Always pull the next work item from the head of the queue + QueuedWrite* nextQueuedWrite = write_queue.next; + uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite); + } + q->unlock(); + + data->buffer.Reset(); + delete data; + delete queuedWrite; +} + +NAN_METHOD(Close) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + + // callback + if (!info[1]->IsFunction()) { + Nan::ThrowTypeError("Second argument must be a function"); + return; + } + + CloseBaton* baton = new CloseBaton(); + memset(baton, 0, sizeof(CloseBaton)); + #if NODE_MAJOR_VERSION >= 10 + baton->fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + baton->fd = info[0]->ToInt32()->Int32Value(); + #endif + + baton->callback.Reset(info[1].As()); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_Close, (uv_after_work_cb)EIO_AfterClose); + + return; +} + +void EIO_AfterClose(uv_work_t* req) { + Nan::HandleScope scope; + CloseBaton* data = static_cast(req->data); + + v8::Local argv[1]; + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Null(); + + // We don't have an error, so clean up the write queue for that fd + _WriteQueue *q = qForFD(data->fd); + if (q) { + q->lock(); + QueuedWrite &write_queue = q->get(); + while (!write_queue.empty()) { + QueuedWrite *del_q = write_queue.next; + del_q->baton->buffer.Reset(); + del_q->remove(); + } + q->unlock(); + deleteQForFD(data->fd); + } + } + data->callback.Call(1, argv); + + delete data; + delete req; +} + +NAN_METHOD(List) { + // callback + if (!info[0]->IsFunction()) { + Nan::ThrowTypeError("First argument must be a function"); + return; + } + + ListBaton* baton = new ListBaton(); + strcpy(baton->errorString, ""); + baton->callback.Reset(info[0].As()); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_List, (uv_after_work_cb)EIO_AfterList); + + return; +} + +void setIfNotEmpty(v8::Local item, std::string key, const char *value) { + v8::Local v8key = Nan::New(key).ToLocalChecked(); + if (strlen(value) > 0) { + Nan::Set(item, v8key, Nan::New(value).ToLocalChecked()); + } else { + Nan::Set(item, v8key, Nan::Undefined()); + } + +} + +void EIO_AfterList(uv_work_t* req) { + Nan::HandleScope scope; + + ListBaton* data = static_cast(req->data); + + v8::Local argv[2]; + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + argv[1] = Nan::Undefined(); + } else { + v8::Local results = Nan::New(); + int i = 0; + for (std::list::iterator it = data->results.begin(); it != data->results.end(); ++it, i++) { + v8::Local item = Nan::New(); + + setIfNotEmpty(item, "comName", (*it)->comName.c_str()); + setIfNotEmpty(item, "manufacturer", (*it)->manufacturer.c_str()); + setIfNotEmpty(item, "serialNumber", (*it)->serialNumber.c_str()); + setIfNotEmpty(item, "pnpId", (*it)->pnpId.c_str()); + setIfNotEmpty(item, "locationId", (*it)->locationId.c_str()); + setIfNotEmpty(item, "vendorId", (*it)->vendorId.c_str()); + setIfNotEmpty(item, "productId", (*it)->productId.c_str()); + + Nan::Set(results, i, item); + } + argv[0] = Nan::Null(); + argv[1] = results; + } + data->callback.Call(2, argv); + + for (std::list::iterator it = data->results.begin(); it != data->results.end(); ++it) { + delete *it; + } + delete data; + delete req; +} + +NAN_METHOD(Flush) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = info[0]->ToInt32()->Int32Value(); + #endif + + // callback + if (!info[1]->IsFunction()) { + Nan::ThrowTypeError("Second argument must be a function"); + return; + } + v8::Local callback = info[1].As(); + + FlushBaton* baton = new FlushBaton(); + memset(baton, 0, sizeof(FlushBaton)); + baton->fd = fd; + baton->callback.Reset(callback); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_Flush, (uv_after_work_cb)EIO_AfterFlush); + + return; +} + +void EIO_AfterFlush(uv_work_t* req) { + Nan::HandleScope scope; + + FlushBaton* data = static_cast(req->data); + + v8::Local argv[2]; + + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + argv[1] = Nan::Undefined(); + } else { + argv[0] = Nan::Undefined(); + argv[1] = Nan::New(data->result); + } + + data->callback.Call(2, argv); + + delete data; + delete req; +} + +NAN_METHOD(Set) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = info[0]->ToInt32()->Int32Value(); + #endif + + // options + if (!info[1]->IsObject()) { + Nan::ThrowTypeError("Second argument must be an object"); + return; + } + v8::Local options = info[1]->ToObject(); + + // callback + if (!info[2]->IsFunction()) { + Nan::ThrowTypeError("Third argument must be a function"); + return; + } + v8::Local callback = info[2].As(); + + SetBaton* baton = new SetBaton(); + memset(baton, 0, sizeof(SetBaton)); + baton->fd = fd; + baton->callback.Reset(callback); + baton->brk = getBoolFromObject(options, "brk"); + baton->rts = getBoolFromObject(options, "rts"); + baton->cts = getBoolFromObject(options, "cts"); + baton->dtr = getBoolFromObject(options, "dtr"); + baton->dsr = getBoolFromObject(options, "dsr"); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_Set, (uv_after_work_cb)EIO_AfterSet); + + return; +} + +void EIO_AfterSet(uv_work_t* req) { + Nan::HandleScope scope; + + SetBaton* data = static_cast(req->data); + + v8::Local argv[1]; + + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Null(); + } + data->callback.Call(1, argv); + + delete data; + delete req; +} + +NAN_METHOD(Drain) { + // file descriptor + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an int"); + return; + } + int fd; + #if NODE_MAJOR_VERSION >= 10 + fd = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + fd = info[0]->ToInt32()->Int32Value(); + #endif + + // callback + if (!info[1]->IsFunction()) { + Nan::ThrowTypeError("Second argument must be a function"); + return; + } + + DrainBaton* baton = new DrainBaton(); + memset(baton, 0, sizeof(DrainBaton)); + baton->fd = fd; + baton->callback.Reset(info[1].As()); + + uv_work_t* req = new uv_work_t(); + req->data = baton; + uv_queue_work(uv_default_loop(), req, EIO_Drain, (uv_after_work_cb)EIO_AfterDrain); + + return; +} + +void EIO_AfterDrain(uv_work_t* req) { + Nan::HandleScope scope; + + DrainBaton* data = static_cast(req->data); + + v8::Local argv[1]; + + if (data->errorString[0]) { + argv[0] = v8::Exception::Error(Nan::New(data->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Null(); + } + data->callback.Call(1, argv); + + delete data; + delete req; +} + +SerialPortParity NAN_INLINE(ToParityEnum(const v8::Local& v8str)) { + Nan::HandleScope scope; + Nan::Utf8String str(v8str); + size_t count = strlen(*str); + SerialPortParity parity = SERIALPORT_PARITY_NONE; + if (!strncasecmp(*str, "none", count)) { + parity = SERIALPORT_PARITY_NONE; + } else if (!strncasecmp(*str, "even", count)) { + parity = SERIALPORT_PARITY_EVEN; + } else if (!strncasecmp(*str, "mark", count)) { + parity = SERIALPORT_PARITY_MARK; + } else if (!strncasecmp(*str, "odd", count)) { + parity = SERIALPORT_PARITY_ODD; + } else if (!strncasecmp(*str, "space", count)) { + parity = SERIALPORT_PARITY_SPACE; + } + return parity; +} + +SerialPortStopBits NAN_INLINE(ToStopBitEnum(double stopBits)) { + if (stopBits > 1.4 && stopBits < 1.6) { + return SERIALPORT_STOPBITS_ONE_FIVE; + } + if (stopBits == 2) { + return SERIALPORT_STOPBITS_TWO; + } + return SERIALPORT_STOPBITS_ONE; +} + +extern "C" { + void init_serialport( v8::Local target) { + Nan::HandleScope scope; + Nan::SetMethod(target, "set", Set); + Nan::SetMethod(target, "open", Open); + Nan::SetMethod(target, "update", Update); + Nan::SetMethod(target, "write", Write); + Nan::SetMethod(target, "close", Close); + Nan::SetMethod(target, "list", List); + Nan::SetMethod(target, "flush", Flush); + Nan::SetMethod(target, "drain", Drain); + +#ifndef WIN32 + SerialportPoller::Init(target); +#endif + } +} + +//NODE_MODULE(serialport, init); diff --git a/vendor/node-usb-native/src/serialport.h b/vendor/node-usb-native/src/serialport.h index 392fc2017..883ef9b05 100644 --- a/vendor/node-usb-native/src/serialport.h +++ b/vendor/node-usb-native/src/serialport.h @@ -1,195 +1,195 @@ -#ifndef SRC_SERIALPORT_H_ -#define SRC_SERIALPORT_H_ - -#include -#include -#include -#include -#include -#include - -#define ERROR_STRING_SIZE 1024 - -NAN_METHOD(List); -void EIO_List(uv_work_t* req); -void EIO_AfterList(uv_work_t* req); - -NAN_METHOD(Open); -void EIO_Open(uv_work_t* req); -void EIO_AfterOpen(uv_work_t* req); -void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback); - -NAN_METHOD(Update); -void EIO_Update(uv_work_t* req); -void EIO_AfterUpdate(uv_work_t* req); - -NAN_METHOD(Write); -void EIO_Write(uv_work_t* req); -void EIO_AfterWrite(uv_work_t* req); - -NAN_METHOD(Close); -void EIO_Close(uv_work_t* req); -void EIO_AfterClose(uv_work_t* req); - -NAN_METHOD(Flush); -void EIO_Flush(uv_work_t* req); -void EIO_AfterFlush(uv_work_t* req); - -NAN_METHOD(Set); -void EIO_Set(uv_work_t* req); -void EIO_AfterSet(uv_work_t* req); - -NAN_METHOD(Drain); -void EIO_Drain(uv_work_t* req); -void EIO_AfterDrain(uv_work_t* req); - -enum SerialPortParity { - SERIALPORT_PARITY_NONE = 1, - SERIALPORT_PARITY_MARK = 2, - SERIALPORT_PARITY_EVEN = 3, - SERIALPORT_PARITY_ODD = 4, - SERIALPORT_PARITY_SPACE = 5 -}; - -enum SerialPortStopBits { - SERIALPORT_STOPBITS_ONE = 1, - SERIALPORT_STOPBITS_ONE_FIVE = 2, - SERIALPORT_STOPBITS_TWO = 3 -}; - -SerialPortParity ToParityEnum(const v8::Local& str); -SerialPortStopBits ToStopBitEnum(double stopBits); - -struct OpenBatonPlatformOptions { }; -OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options); - -struct OpenBaton { - char errorString[ERROR_STRING_SIZE]; - Nan::Callback callback; - char path[1024]; - int fd; - int result; - int baudRate; - int dataBits; - int bufferSize; - bool rtscts; - bool xon; - bool xoff; - bool xany; - bool dsrdtr; - bool hupcl; - bool lock; - Nan::Callback* dataCallback; - Nan::Callback* disconnectedCallback; - Nan::Callback* errorCallback; - SerialPortParity parity; - SerialPortStopBits stopBits; - OpenBatonPlatformOptions* platformOptions; -}; - -struct ConnectionOptionsBaton { - char errorString[ERROR_STRING_SIZE]; - Nan::Callback callback; - int fd; - int baudRate; -}; - -struct WriteBaton { - int fd; - char* bufferData; - size_t bufferLength; - size_t offset; - Nan::Persistent buffer; - Nan::Callback callback; - int result; - char errorString[ERROR_STRING_SIZE]; -}; - -struct QueuedWrite { - uv_work_t req; - QueuedWrite *prev; - QueuedWrite *next; - WriteBaton* baton; - - QueuedWrite() { - prev = this; - next = this; - - baton = 0; - } - - ~QueuedWrite() { - remove(); - } - - void remove() { - prev->next = next; - next->prev = prev; - - next = this; - prev = this; - } - - void insert_tail(QueuedWrite *qw) { - qw->next = this; - qw->prev = this->prev; - qw->prev->next = qw; - this->prev = qw; - } - - bool empty() { - return next == this; - } -}; - -struct CloseBaton { - int fd; - Nan::Callback callback; - char errorString[ERROR_STRING_SIZE]; -}; - -struct ListResultItem { - std::string comName; - std::string manufacturer; - std::string serialNumber; - std::string pnpId; - std::string locationId; - std::string vendorId; - std::string productId; -}; - -struct ListBaton { - Nan::Callback callback; - std::list results; - char errorString[ERROR_STRING_SIZE]; -}; - -struct FlushBaton { - int fd; - Nan::Callback callback; - int result; - char errorString[ERROR_STRING_SIZE]; -}; - -struct SetBaton { - int fd; - Nan::Callback callback; - int result; - char errorString[ERROR_STRING_SIZE]; - bool rts; - bool cts; - bool dtr; - bool dsr; - bool brk; -}; - -struct DrainBaton { - int fd; - Nan::Callback callback; - int result; - char errorString[ERROR_STRING_SIZE]; -}; - -int setup(int fd, OpenBaton *data); -int setBaudRate(ConnectionOptionsBaton *data); -#endif // SRC_SERIALPORT_H_ +#ifndef SRC_SERIALPORT_H_ +#define SRC_SERIALPORT_H_ + +#include +#include +#include +#include +#include +#include + +#define ERROR_STRING_SIZE 1024 + +NAN_METHOD(List); +void EIO_List(uv_work_t* req); +void EIO_AfterList(uv_work_t* req); + +NAN_METHOD(Open); +void EIO_Open(uv_work_t* req); +void EIO_AfterOpen(uv_work_t* req); +void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback); + +NAN_METHOD(Update); +void EIO_Update(uv_work_t* req); +void EIO_AfterUpdate(uv_work_t* req); + +NAN_METHOD(Write); +void EIO_Write(uv_work_t* req); +void EIO_AfterWrite(uv_work_t* req); + +NAN_METHOD(Close); +void EIO_Close(uv_work_t* req); +void EIO_AfterClose(uv_work_t* req); + +NAN_METHOD(Flush); +void EIO_Flush(uv_work_t* req); +void EIO_AfterFlush(uv_work_t* req); + +NAN_METHOD(Set); +void EIO_Set(uv_work_t* req); +void EIO_AfterSet(uv_work_t* req); + +NAN_METHOD(Drain); +void EIO_Drain(uv_work_t* req); +void EIO_AfterDrain(uv_work_t* req); + +enum SerialPortParity { + SERIALPORT_PARITY_NONE = 1, + SERIALPORT_PARITY_MARK = 2, + SERIALPORT_PARITY_EVEN = 3, + SERIALPORT_PARITY_ODD = 4, + SERIALPORT_PARITY_SPACE = 5 +}; + +enum SerialPortStopBits { + SERIALPORT_STOPBITS_ONE = 1, + SERIALPORT_STOPBITS_ONE_FIVE = 2, + SERIALPORT_STOPBITS_TWO = 3 +}; + +SerialPortParity ToParityEnum(const v8::Local& str); +SerialPortStopBits ToStopBitEnum(double stopBits); + +struct OpenBatonPlatformOptions { }; +OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options); + +struct OpenBaton { + char errorString[ERROR_STRING_SIZE]; + Nan::Callback callback; + char path[1024]; + int fd; + int result; + int baudRate; + int dataBits; + int bufferSize; + bool rtscts; + bool xon; + bool xoff; + bool xany; + bool dsrdtr; + bool hupcl; + bool lock; + Nan::Callback* dataCallback; + Nan::Callback* disconnectedCallback; + Nan::Callback* errorCallback; + SerialPortParity parity; + SerialPortStopBits stopBits; + OpenBatonPlatformOptions* platformOptions; +}; + +struct ConnectionOptionsBaton { + char errorString[ERROR_STRING_SIZE]; + Nan::Callback callback; + int fd; + int baudRate; +}; + +struct WriteBaton { + int fd; + char* bufferData; + size_t bufferLength; + size_t offset; + Nan::Persistent buffer; + Nan::Callback callback; + int result; + char errorString[ERROR_STRING_SIZE]; +}; + +struct QueuedWrite { + uv_work_t req; + QueuedWrite *prev; + QueuedWrite *next; + WriteBaton* baton; + + QueuedWrite() { + prev = this; + next = this; + + baton = 0; + } + + ~QueuedWrite() { + remove(); + } + + void remove() { + prev->next = next; + next->prev = prev; + + next = this; + prev = this; + } + + void insert_tail(QueuedWrite *qw) { + qw->next = this; + qw->prev = this->prev; + qw->prev->next = qw; + this->prev = qw; + } + + bool empty() { + return next == this; + } +}; + +struct CloseBaton { + int fd; + Nan::Callback callback; + char errorString[ERROR_STRING_SIZE]; +}; + +struct ListResultItem { + std::string comName; + std::string manufacturer; + std::string serialNumber; + std::string pnpId; + std::string locationId; + std::string vendorId; + std::string productId; +}; + +struct ListBaton { + Nan::Callback callback; + std::list results; + char errorString[ERROR_STRING_SIZE]; +}; + +struct FlushBaton { + int fd; + Nan::Callback callback; + int result; + char errorString[ERROR_STRING_SIZE]; +}; + +struct SetBaton { + int fd; + Nan::Callback callback; + int result; + char errorString[ERROR_STRING_SIZE]; + bool rts; + bool cts; + bool dtr; + bool dsr; + bool brk; +}; + +struct DrainBaton { + int fd; + Nan::Callback callback; + int result; + char errorString[ERROR_STRING_SIZE]; +}; + +int setup(int fd, OpenBaton *data); +int setBaudRate(ConnectionOptionsBaton *data); +#endif // SRC_SERIALPORT_H_ diff --git a/vendor/node-usb-native/src/serialport_poller.cpp b/vendor/node-usb-native/src/serialport_poller.cpp index 7471f2a38..b7db5af67 100644 --- a/vendor/node-usb-native/src/serialport_poller.cpp +++ b/vendor/node-usb-native/src/serialport_poller.cpp @@ -1,128 +1,128 @@ -// Copyright (C) 2013 Robert Giseburt -// serialport_poller.cpp Written as a part of https://github.com/voodootikigod/node-serialport -// License to use this is the same as that of node-serialport. - -#include -#include "./serialport_poller.h" - -using namespace v8; - -static Nan::Persistent serialportpoller_constructor; - -SerialportPoller::SerialportPoller() : Nan::ObjectWrap() {} -SerialportPoller::~SerialportPoller() { - // printf("~SerialportPoller\n"); - delete callback_; -} - -void _serialportReadable(uv_poll_t *req, int status, int events) { - SerialportPoller* sp = (SerialportPoller*) req->data; - // We can stop polling until we have read all of the data... - sp->_stop(); - sp->callCallback(status); -} - -void SerialportPoller::callCallback(int status) { - Nan::HandleScope scope; - // uv_work_t* req = new uv_work_t; - - // Call the callback to go read more data... - - v8::Local argv[1]; - if (status != 0) { - // error handling changed in libuv, see: - // https://github.com/joyent/libuv/commit/3ee4d3f183331 - #ifdef UV_ERRNO_H_ - const char* err_string = uv_strerror(status); - #else - uv_err_t errno = uv_last_error(uv_default_loop()); - const char* err_string = uv_strerror(errno); - #endif - snprintf(this->errorString, sizeof(this->errorString), "Error %s on polling", err_string); - argv[0] = v8::Exception::Error(Nan::New(this->errorString).ToLocalChecked()); - } else { - argv[0] = Nan::Undefined(); - } - - callback_->Call(1, argv); -} - - - -void SerialportPoller::Init(Handle target) { - Nan::HandleScope scope; - - // Prepare constructor template - Local tpl = Nan::New(New); - tpl->SetClassName(Nan::New("SerialportPoller").ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - - - // Prototype - - // SerialportPoller.close() - Nan::SetPrototypeMethod(tpl, "close", Close); - - // SerialportPoller.start() - Nan::SetPrototypeMethod(tpl, "start", Start); - - serialportpoller_constructor.Reset(tpl); - - Nan::Set(target, Nan::New("SerialportPoller").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); -} - -NAN_METHOD(SerialportPoller::New) { - if (!info[0]->IsInt32()) { - Nan::ThrowTypeError("First argument must be an fd"); - return; - } - - if (!info[1]->IsFunction()) { - Nan::ThrowTypeError("Third argument must be a function"); - return; - } - - SerialportPoller* obj = new SerialportPoller(); - #if NODE_MAJOR_VERSION >= 10 - obj->fd_ = info[0]->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - obj->fd_ = info[0]->ToInt32()->Int32Value(); - #endif - obj->callback_ = new Nan::Callback(info[1].As()); - // obj->callCallback(); - - obj->Wrap(info.This()); - - obj->poll_handle_.data = obj; - - uv_poll_init(uv_default_loop(), &obj->poll_handle_, obj->fd_); - - uv_poll_start(&obj->poll_handle_, UV_READABLE, _serialportReadable); - - info.GetReturnValue().Set(info.This()); -} - -void SerialportPoller::_start() { - uv_poll_start(&poll_handle_, UV_READABLE, _serialportReadable); -} - -void SerialportPoller::_stop() { - uv_poll_stop(&poll_handle_); -} - - -NAN_METHOD(SerialportPoller::Start) { - SerialportPoller* obj = Nan::ObjectWrap::Unwrap(info.This()); - obj->_start(); - - return; -} - -NAN_METHOD(SerialportPoller::Close) { - SerialportPoller* obj = Nan::ObjectWrap::Unwrap(info.This()); - obj->_stop(); - - // DO SOMETHING! - - return; -} +// Copyright (C) 2013 Robert Giseburt +// serialport_poller.cpp Written as a part of https://github.com/voodootikigod/node-serialport +// License to use this is the same as that of node-serialport. + +#include +#include "./serialport_poller.h" + +using namespace v8; + +static Nan::Persistent serialportpoller_constructor; + +SerialportPoller::SerialportPoller() : Nan::ObjectWrap() {} +SerialportPoller::~SerialportPoller() { + // printf("~SerialportPoller\n"); + delete callback_; +} + +void _serialportReadable(uv_poll_t *req, int status, int events) { + SerialportPoller* sp = (SerialportPoller*) req->data; + // We can stop polling until we have read all of the data... + sp->_stop(); + sp->callCallback(status); +} + +void SerialportPoller::callCallback(int status) { + Nan::HandleScope scope; + // uv_work_t* req = new uv_work_t; + + // Call the callback to go read more data... + + v8::Local argv[1]; + if (status != 0) { + // error handling changed in libuv, see: + // https://github.com/joyent/libuv/commit/3ee4d3f183331 + #ifdef UV_ERRNO_H_ + const char* err_string = uv_strerror(status); + #else + uv_err_t errno = uv_last_error(uv_default_loop()); + const char* err_string = uv_strerror(errno); + #endif + snprintf(this->errorString, sizeof(this->errorString), "Error %s on polling", err_string); + argv[0] = v8::Exception::Error(Nan::New(this->errorString).ToLocalChecked()); + } else { + argv[0] = Nan::Undefined(); + } + + callback_->Call(1, argv); +} + + + +void SerialportPoller::Init(Local target) { + Nan::HandleScope scope; + + // Prepare constructor template + Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("SerialportPoller").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + + // Prototype + + // SerialportPoller.close() + Nan::SetPrototypeMethod(tpl, "close", Close); + + // SerialportPoller.start() + Nan::SetPrototypeMethod(tpl, "start", Start); + + serialportpoller_constructor.Reset(tpl); + + Nan::Set(target, Nan::New("SerialportPoller").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); +} + +NAN_METHOD(SerialportPoller::New) { + if (!info[0]->IsInt32()) { + Nan::ThrowTypeError("First argument must be an fd"); + return; + } + + if (!info[1]->IsFunction()) { + Nan::ThrowTypeError("Third argument must be a function"); + return; + } + + SerialportPoller* obj = new SerialportPoller(); + #if NODE_MAJOR_VERSION >= 10 + obj->fd_ = info[0]->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + obj->fd_ = info[0]->ToInt32()->Int32Value(); + #endif + obj->callback_ = new Nan::Callback(info[1].As()); + // obj->callCallback(); + + obj->Wrap(info.This()); + + obj->poll_handle_.data = obj; + + uv_poll_init(uv_default_loop(), &obj->poll_handle_, obj->fd_); + + uv_poll_start(&obj->poll_handle_, UV_READABLE, _serialportReadable); + + info.GetReturnValue().Set(info.This()); +} + +void SerialportPoller::_start() { + uv_poll_start(&poll_handle_, UV_READABLE, _serialportReadable); +} + +void SerialportPoller::_stop() { + uv_poll_stop(&poll_handle_); +} + + +NAN_METHOD(SerialportPoller::Start) { + SerialportPoller* obj = Nan::ObjectWrap::Unwrap(info.This()); + obj->_start(); + + return; +} + +NAN_METHOD(SerialportPoller::Close) { + SerialportPoller* obj = Nan::ObjectWrap::Unwrap(info.This()); + obj->_stop(); + + // DO SOMETHING! + + return; +} diff --git a/vendor/node-usb-native/src/serialport_poller.h b/vendor/node-usb-native/src/serialport_poller.h index 4d20b07d6..1f4cc37c2 100644 --- a/vendor/node-usb-native/src/serialport_poller.h +++ b/vendor/node-usb-native/src/serialport_poller.h @@ -1,35 +1,35 @@ -// Copyright (C) 2013 Robert Giseburt -// serialport_poller.h Written as a part of https://github.com/voodootikigod/node-serialport -// License to use this is the same as that of node-serialport. - -#ifndef SERIALPORT_POLLER_H -#define SERIALPORT_POLLER_H - -#include -#include "./serialport.h" - -class SerialportPoller : public Nan::ObjectWrap { - public: - static void Init(v8::Handle target); - - void callCallback(int status); - - void _start(); - void _stop(); - - private: - SerialportPoller(); - ~SerialportPoller(); - - static NAN_METHOD(New); - static NAN_METHOD(Close); - static NAN_METHOD(Start); - - uv_poll_t poll_handle_; - int fd_; - char errorString[ERROR_STRING_SIZE]; - - Nan::Callback* callback_; -}; - -#endif +// Copyright (C) 2013 Robert Giseburt +// serialport_poller.h Written as a part of https://github.com/voodootikigod/node-serialport +// License to use this is the same as that of node-serialport. + +#ifndef SERIALPORT_POLLER_H +#define SERIALPORT_POLLER_H + +#include +#include "./serialport.h" + +class SerialportPoller : public Nan::ObjectWrap { + public: + static void Init( v8::Local target); + + void callCallback(int status); + + void _start(); + void _stop(); + + private: + SerialportPoller(); + ~SerialportPoller(); + + static NAN_METHOD(New); + static NAN_METHOD(Close); + static NAN_METHOD(Start); + + uv_poll_t poll_handle_; + int fd_; + char errorString[ERROR_STRING_SIZE]; + + Nan::Callback* callback_; +}; + +#endif diff --git a/vendor/node-usb-native/src/serialport_unix.cpp b/vendor/node-usb-native/src/serialport_unix.cpp index cd27b40c6..41cbe7710 100644 --- a/vendor/node-usb-native/src/serialport_unix.cpp +++ b/vendor/node-usb-native/src/serialport_unix.cpp @@ -1,740 +1,740 @@ -#include "./serialport.h" -#include "./serialport_poller.h" -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#include -#include -#include -#include -#include - -uv_mutex_t list_mutex; -Boolean lockInitialised = FALSE; -#endif - -#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) -#include -#include -#endif - -#if defined(__OpenBSD__) -#include -#endif - -#if defined(__linux__) -#include -#include -#endif - -struct UnixPlatformOptions : OpenBatonPlatformOptions { - uint8_t vmin; - uint8_t vtime; -}; - -OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options) { - Nan::HandleScope scope; - - UnixPlatformOptions* result = new UnixPlatformOptions(); - #if NODE_MAJOR_VERSION >= 10 - result->vmin = Nan::Get(options, Nan::New("vmin").ToLocalChecked()).ToLocalChecked()->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - result->vtime = Nan::Get(options, Nan::New("vtime").ToLocalChecked()).ToLocalChecked()->ToInt32(v8::Isolate::GetCurrent())->Int32Value(); - #else - result->vmin = Nan::Get(options, Nan::New("vmin").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); - result->vtime = Nan::Get(options, Nan::New("vtime").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); - #endif - - return result; -} - -int ToBaudConstant(int baudRate); -int ToDataBitsConstant(int dataBits); -int ToStopBitsConstant(SerialPortStopBits stopBits); - -void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback) { - delete dataCallback; - delete errorCallback; - delete disconnectedCallback; -} - -int ToBaudConstant(int baudRate) { - switch (baudRate) { - case 0: return B0; - case 50: return B50; - case 75: return B75; - case 110: return B110; - case 134: return B134; - case 150: return B150; - case 200: return B200; - case 300: return B300; - case 600: return B600; - case 1200: return B1200; - case 1800: return B1800; - case 2400: return B2400; - case 4800: return B4800; - case 9600: return B9600; - case 19200: return B19200; - case 38400: return B38400; - case 57600: return B57600; - case 115200: return B115200; - case 230400: return B230400; -#if defined(__linux__) - case 460800: return B460800; - case 500000: return B500000; - case 576000: return B576000; - case 921600: return B921600; - case 1000000: return B1000000; - case 1152000: return B1152000; - case 1500000: return B1500000; - case 2000000: return B2000000; - case 2500000: return B2500000; - case 3000000: return B3000000; - case 3500000: return B3500000; - case 4000000: return B4000000; -#endif - } - return -1; -} - -#ifdef __APPLE__ -typedef struct SerialDevice { - char port[MAXPATHLEN]; - char locationId[MAXPATHLEN]; - char vendorId[MAXPATHLEN]; - char productId[MAXPATHLEN]; - char manufacturer[MAXPATHLEN]; - char serialNumber[MAXPATHLEN]; -} stSerialDevice; - -typedef struct DeviceListItem { - struct SerialDevice value; - struct DeviceListItem *next; - int* length; -} stDeviceListItem; -#endif - -int ToDataBitsConstant(int dataBits) { - switch (dataBits) { - case 8: default: return CS8; - case 7: return CS7; - case 6: return CS6; - case 5: return CS5; - } - return -1; -} - -void EIO_Open(uv_work_t* req) { - OpenBaton* data = static_cast(req->data); - - int flags = (O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC | O_SYNC); - int fd = open(data->path, flags); - - if (-1 == fd) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot open %s", strerror(errno), data->path); - return; - } - - if (-1 == setup(fd, data)) { - close(fd); - return; - } - - data->result = fd; -} - -int setBaudRate(ConnectionOptionsBaton *data) { - // lookup the standard baudrates from the table - int baudRate = ToBaudConstant(data->baudRate); - int fd = data->fd; - - // get port options - struct termios options; - if (tcgetattr(fd, &options)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: tcgetattr encountering %s", strerror(errno)); - return -1; - } - - // If there is a custom baud rate on linux you can do the following trick with B38400 - #if defined(__linux__) && defined(ASYNC_SPD_CUST) - if (baudRate == -1) { - struct serial_struct serinfo; - serinfo.reserved_char[0] = 0; - if (-1 != ioctl(fd, TIOCGSERIAL, &serinfo)) { - serinfo.flags &= ~ASYNC_SPD_MASK; - serinfo.flags |= ASYNC_SPD_CUST; - serinfo.custom_divisor = (serinfo.baud_base + (data->baudRate / 2)) / data->baudRate; - if (serinfo.custom_divisor < 1) - serinfo.custom_divisor = 1; - - ioctl(fd, TIOCSSERIAL, &serinfo); - ioctl(fd, TIOCGSERIAL, &serinfo); - } else { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s setting custom baud rate of %d", strerror(errno), data->baudRate); - return -1; - } - - // Now we use "B38400" to trigger the special baud rate. - baudRate = B38400; - } - #endif - - // On OS X, starting with Tiger, we can set a custom baud rate with ioctl - #if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) - if (-1 == baudRate) { - speed_t speed = data->baudRate; - if (-1 == ioctl(fd, IOSSIOSPEED, &speed)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s calling ioctl(.., IOSSIOSPEED, %ld )", strerror(errno), speed ); - return -1; - } else { - return 1; - } - } - #endif - - // If we have a good baud rate set it and lets go - if (-1 != baudRate) { - cfsetospeed(&options, baudRate); - cfsetispeed(&options, baudRate); - tcflush(fd, TCIFLUSH); - tcsetattr(fd, TCSANOW, &options); - return 1; - } - - snprintf(data->errorString, sizeof(data->errorString), "Error baud rate of %d is not supported on your platform", data->baudRate); - return -1; -} - -void EIO_Update(uv_work_t* req) { - ConnectionOptionsBaton* data = static_cast(req->data); - setBaudRate(data); -} - -int setup(int fd, OpenBaton *data) { - UnixPlatformOptions* platformOptions = static_cast(data->platformOptions); - - int dataBits = ToDataBitsConstant(data->dataBits); - if (-1 == dataBits) { - snprintf(data->errorString, sizeof(data->errorString), "Invalid data bits setting %d", data->dataBits); - return -1; - } - - // Snow Leopard doesn't have O_CLOEXEC - if (-1 == fcntl(fd, F_SETFD, FD_CLOEXEC)) { - snprintf(data->errorString, sizeof(data->errorString), "Error %s Cannot open %s", strerror(errno), data->path); - return -1; - } - - // Copy the connection options into the ConnectionOptionsBaton to set the baud rate - ConnectionOptionsBaton* connectionOptions = new ConnectionOptionsBaton(); - memset(connectionOptions, 0, sizeof(ConnectionOptionsBaton)); - connectionOptions->fd = fd; - connectionOptions->baudRate = data->baudRate; - - if (-1 == setBaudRate(connectionOptions)) { - strncpy(data->errorString, connectionOptions->errorString, sizeof(data->errorString)); - delete(connectionOptions); - return -1; - } - delete(connectionOptions); - - // Get port configuration for modification - struct termios options; - if (tcgetattr(fd, &options)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: tcgetattr encountering %s", strerror(errno)); - return -1; - } - - // IGNPAR: ignore bytes with parity errors - options.c_iflag = IGNPAR; - - // ICRNL: map CR to NL (otherwise a CR input on the other computer will not terminate input) - // Future potential option - // options.c_iflag = ICRNL; - // otherwise make device raw (no other input processing) - - // Specify data bits - options.c_cflag &= ~CSIZE; - options.c_cflag |= dataBits; - - options.c_cflag &= ~(CRTSCTS); - - if (data->rtscts) { - options.c_cflag |= CRTSCTS; - // evaluate specific flow control options - } - - options.c_iflag &= ~(IXON | IXOFF | IXANY); - - if (data->xon) { - options.c_iflag |= IXON; - } - - if (data->xoff) { - options.c_iflag |= IXOFF; - } - - if (data->xany) { - options.c_iflag |= IXANY; - } - - switch (data->parity) { - case SERIALPORT_PARITY_NONE: - options.c_cflag &= ~PARENB; - // options.c_cflag &= ~CSTOPB; - // options.c_cflag &= ~CSIZE; - // options.c_cflag |= CS8; - break; - case SERIALPORT_PARITY_ODD: - options.c_cflag |= PARENB; - options.c_cflag |= PARODD; - // options.c_cflag &= ~CSTOPB; - // options.c_cflag &= ~CSIZE; - // options.c_cflag |= CS7; - break; - case SERIALPORT_PARITY_EVEN: - options.c_cflag |= PARENB; - options.c_cflag &= ~PARODD; - // options.c_cflag &= ~CSTOPB; - // options.c_cflag &= ~CSIZE; - // options.c_cflag |= CS7; - break; - default: - snprintf(data->errorString, sizeof(data->errorString), "Invalid parity setting %d", data->parity); - return -1; - } - - switch (data->stopBits) { - case SERIALPORT_STOPBITS_ONE: - options.c_cflag &= ~CSTOPB; - break; - case SERIALPORT_STOPBITS_TWO: - options.c_cflag |= CSTOPB; - break; - default: - snprintf(data->errorString, sizeof(data->errorString), "Invalid stop bits setting %d", data->stopBits); - return -1; - } - - options.c_cflag |= CLOCAL; // ignore status lines - options.c_cflag |= CREAD; // enable receiver - if (data->hupcl) { - options.c_cflag |= HUPCL; // drop DTR (i.e. hangup) on close - } - - // Raw output - options.c_oflag = 0; - - // ICANON makes partial lines not readable. It should be optional. - // It works with ICRNL. - options.c_lflag = 0; // ICANON; - - options.c_cc[VMIN]= platformOptions->vmin; - options.c_cc[VTIME]= platformOptions->vtime; - - // why? - tcflush(fd, TCIFLUSH); - - // check for error? - tcsetattr(fd, TCSANOW, &options); - - if (data->lock){ - if (-1 == flock(fd, LOCK_EX | LOCK_NB)) { - snprintf(data->errorString, sizeof(data->errorString), "Error %s Cannot lock port", strerror(errno)); - return -1; - } - } - - return 1; -} - -void EIO_Write(uv_work_t* req) { - QueuedWrite* queuedWrite = static_cast(req->data); - WriteBaton* data = static_cast(queuedWrite->baton); - int bytesWritten = 0; - - do { - errno = 0; // probably don't need this - bytesWritten = write(data->fd, data->bufferData + data->offset, data->bufferLength - data->offset); - if (-1 != bytesWritten) { - // there wasn't an error, do the math on what we actually wrote and keep writing until finished - data->offset += bytesWritten; - continue; - } - - // The write call was interrupted before anything was written, try again immediately. - if (errno == EINTR) { - // why try again right away instead of in another event loop? - continue; - } - - // Try again in another event loop - if (errno == EAGAIN || errno == EWOULDBLOCK){ - return; - } - - // EBAD would mean we're "disconnected" - - // a real error so lets bail - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, calling write", strerror(errno)); - return; - } while (data->bufferLength > data->offset); -} - -void EIO_Close(uv_work_t* req) { - CloseBaton* data = static_cast(req->data); - if (-1 == close(data->fd)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, unable to close fd %d", strerror(errno), data->fd); - } -} - -#ifdef __APPLE__ - -// Function prototypes -static kern_return_t FindModems(io_iterator_t *matchingServices); -static io_service_t GetUsbDevice(io_service_t service); -static stDeviceListItem* GetSerialDevices(); - - -static kern_return_t FindModems(io_iterator_t *matchingServices) { - kern_return_t kernResult; - CFMutableDictionaryRef classesToMatch; - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch != NULL) { - CFDictionarySetValue(classesToMatch, - CFSTR(kIOSerialBSDTypeKey), - CFSTR(kIOSerialBSDAllTypes)); - } - - kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices); - - return kernResult; -} - -static io_service_t GetUsbDevice(io_service_t service) { - IOReturn status; - io_iterator_t iterator = 0; - io_service_t device = 0; - - if (!service) { - return device; - } - - status = IORegistryEntryCreateIterator(service, - kIOServicePlane, - (kIORegistryIterateParents | kIORegistryIterateRecursively), - &iterator); - - if (status == kIOReturnSuccess) { - io_service_t currentService; - while ((currentService = IOIteratorNext(iterator)) && device == 0) { - io_name_t serviceName; - status = IORegistryEntryGetNameInPlane(currentService, kIOServicePlane, serviceName); - if (status == kIOReturnSuccess && IOObjectConformsTo(currentService, kIOUSBDeviceClassName)) { - device = currentService; - } else { - // Release the service object which is no longer needed - (void) IOObjectRelease(currentService); - } - } - - // Release the iterator - (void) IOObjectRelease(iterator); - } - - return device; -} - -static void ExtractUsbInformation(stSerialDevice *serialDevice, IOUSBDeviceInterface **deviceInterface) { - kern_return_t kernResult; - UInt32 locationID; - kernResult = (*deviceInterface)->GetLocationID(deviceInterface, &locationID); - if (KERN_SUCCESS == kernResult) { - snprintf(serialDevice->locationId, 11, "0x%08x", locationID); - } - - UInt16 vendorID; - kernResult = (*deviceInterface)->GetDeviceVendor(deviceInterface, &vendorID); - if (KERN_SUCCESS == kernResult) { - snprintf(serialDevice->vendorId, 7, "0x%04x", vendorID); - } - - UInt16 productID; - kernResult = (*deviceInterface)->GetDeviceProduct(deviceInterface, &productID); - if (KERN_SUCCESS == kernResult) { - snprintf(serialDevice->productId, 7, "0x%04x", productID); - } -} - -static stDeviceListItem* GetSerialDevices() { - kern_return_t kernResult; - io_iterator_t serialPortIterator; - char bsdPath[MAXPATHLEN]; - - FindModems(&serialPortIterator); - - io_service_t modemService; - kernResult = KERN_FAILURE; - Boolean modemFound = false; - - // Initialize the returned path - *bsdPath = '\0'; - - stDeviceListItem* devices = NULL; - stDeviceListItem* lastDevice = NULL; - int length = 0; - - while ((modemService = IOIteratorNext(serialPortIterator))) { - CFTypeRef bsdPathAsCFString; - bsdPathAsCFString = IORegistryEntrySearchCFProperty( - modemService, - kIOServicePlane, - CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, - kIORegistryIterateRecursively); - - if (bsdPathAsCFString) { - Boolean result; - - // Convert the path from a CFString to a C (NUL-terminated) - result = CFStringGetCString((CFStringRef) bsdPathAsCFString, - bsdPath, - sizeof(bsdPath), - kCFStringEncodingUTF8); - CFRelease(bsdPathAsCFString); - - if (result) { - stDeviceListItem *deviceListItem = (stDeviceListItem*) malloc(sizeof(stDeviceListItem)); - stSerialDevice *serialDevice = &(deviceListItem->value); - strcpy(serialDevice->port, bsdPath); - memset(serialDevice->locationId, 0, sizeof(serialDevice->locationId)); - memset(serialDevice->vendorId, 0, sizeof(serialDevice->vendorId)); - memset(serialDevice->productId, 0, sizeof(serialDevice->productId)); - serialDevice->manufacturer[0] = '\0'; - serialDevice->serialNumber[0] = '\0'; - deviceListItem->next = NULL; - deviceListItem->length = &length; - - if (devices == NULL) { - devices = deviceListItem; - } else { - lastDevice->next = deviceListItem; - } - - lastDevice = deviceListItem; - length++; - - modemFound = true; - kernResult = KERN_SUCCESS; - - uv_mutex_lock(&list_mutex); - - io_service_t device = GetUsbDevice(modemService); - - if (device) { - CFStringRef manufacturerAsCFString = (CFStringRef) IORegistryEntryCreateCFProperty(device, - CFSTR(kUSBVendorString), - kCFAllocatorDefault, - 0); - - if (manufacturerAsCFString) { - Boolean result; - char manufacturer[MAXPATHLEN]; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString(manufacturerAsCFString, - manufacturer, - sizeof(manufacturer), - kCFStringEncodingUTF8); - - if (result) { - strcpy(serialDevice->manufacturer, manufacturer); - } - - CFRelease(manufacturerAsCFString); - } - - CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, - kIOServicePlane, - CFSTR(kUSBSerialNumberString), - kCFAllocatorDefault, - kIORegistryIterateRecursively); - - if (serialNumberAsCFString) { - Boolean result; - char serialNumber[MAXPATHLEN]; - - // Convert from a CFString to a C (NUL-terminated) - result = CFStringGetCString(serialNumberAsCFString, - serialNumber, - sizeof(serialNumber), - kCFStringEncodingUTF8); - - if (result) { - strcpy(serialDevice->serialNumber, serialNumber); - } - - CFRelease(serialNumberAsCFString); - } - - IOCFPlugInInterface **plugInInterface = NULL; - SInt32 score; - HRESULT res; - - IOUSBDeviceInterface **deviceInterface = NULL; - - kernResult = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, - &plugInInterface, &score); - - if ((kIOReturnSuccess != kernResult) || !plugInInterface) { - continue; - } - - // Use the plugin interface to retrieve the device interface. - res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), - (LPVOID*) &deviceInterface); - - // Now done with the plugin interface. - (*plugInInterface)->Release(plugInInterface); - - if (res || deviceInterface == NULL) { - continue; - } - - // Extract the desired Information - ExtractUsbInformation(serialDevice, deviceInterface); - - // Release the Interface - (*deviceInterface)->Release(deviceInterface); - - // Release the device - (void) IOObjectRelease(device); - } - - uv_mutex_unlock(&list_mutex); - } - } - - // Release the io_service_t now that we are done with it. - (void) IOObjectRelease(modemService); - } - - IOObjectRelease(serialPortIterator); // Release the iterator. - - return devices; -} - -#endif - -void EIO_List(uv_work_t* req) { - ListBaton* data = static_cast(req->data); - -#ifndef __APPLE__ - // This code exists in javascript for other unix platforms - snprintf(data->errorString, sizeof(data->errorString), "List is not Implemented"); - return; -# else - if (!lockInitialised) { - uv_mutex_init(&list_mutex); - lockInitialised = TRUE; - } - - stDeviceListItem* devices = GetSerialDevices(); - if (*(devices->length) > 0) { - stDeviceListItem* next = devices; - - for (int i = 0, len = *(devices->length); i < len; i++) { - stSerialDevice device = (* next).value; - - ListResultItem* resultItem = new ListResultItem(); - resultItem->comName = device.port; - - if (*device.locationId) { - resultItem->locationId = device.locationId; - } - if (*device.vendorId) { - resultItem->vendorId = device.vendorId; - } - if (*device.productId) { - resultItem->productId = device.productId; - } - if (*device.manufacturer) { - resultItem->manufacturer = device.manufacturer; - } - if (*device.serialNumber) { - resultItem->serialNumber = device.serialNumber; - } - data->results.push_back(resultItem); - - stDeviceListItem* current = next; - - if (next->next != NULL) { - next = next->next; - } - - free(current); - } - } -#endif -} - -void EIO_Flush(uv_work_t* req) { - FlushBaton* data = static_cast(req->data); - - data->result = tcflush(data->fd, TCIFLUSH); -} - -void EIO_Set(uv_work_t* req) { - SetBaton* data = static_cast(req->data); - - int bits; - ioctl(data->fd, TIOCMGET, &bits); - - bits &= ~(TIOCM_RTS | TIOCM_CTS | TIOCM_DTR | TIOCM_DSR); - - if (data->rts) { - bits |= TIOCM_RTS; - } - - if (data->cts) { - bits |= TIOCM_CTS; - } - - if (data->dtr) { - bits |= TIOCM_DTR; - } - - if (data->dsr) { - bits |= TIOCM_DSR; - } - - int result = 0; - if (data->brk) { - result = ioctl(data->fd, TIOCSBRK, NULL); - } else { - result = ioctl(data->fd, TIOCCBRK, NULL); - } - - if (-1 == result) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); - return; - } - - if (-1 == ioctl(data->fd, TIOCMSET, &bits)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); - return; - } -} - -void EIO_Drain(uv_work_t* req) { - DrainBaton* data = static_cast(req->data); - - if (-1 == tcdrain(data->fd)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); - return; - } -} +#include "./serialport.h" +#include "./serialport_poller.h" +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#include + +uv_mutex_t list_mutex; +Boolean lockInitialised = FALSE; +#endif + +#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) +#include +#include +#endif + +#if defined(__OpenBSD__) +#include +#endif + +#if defined(__linux__) +#include +#include +#endif + +struct UnixPlatformOptions : OpenBatonPlatformOptions { + uint8_t vmin; + uint8_t vtime; +}; + +OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options) { + Nan::HandleScope scope; + + UnixPlatformOptions* result = new UnixPlatformOptions(); + #if NODE_MAJOR_VERSION >= 10 + result->vmin = Nan::Get(options, Nan::New("vmin").ToLocalChecked()).ToLocalChecked()->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + result->vtime = Nan::Get(options, Nan::New("vtime").ToLocalChecked()).ToLocalChecked()->ToInt32(Nan::GetCurrentContext()).ToLocalChecked()->Value(); + #else + result->vmin = Nan::Get(options, Nan::New("vmin").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); + result->vtime = Nan::Get(options, Nan::New("vtime").ToLocalChecked()).ToLocalChecked()->ToInt32()->Int32Value(); + #endif + + return result; +} + +int ToBaudConstant(int baudRate); +int ToDataBitsConstant(int dataBits); +int ToStopBitsConstant(SerialPortStopBits stopBits); + +void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback) { + delete dataCallback; + delete errorCallback; + delete disconnectedCallback; +} + +int ToBaudConstant(int baudRate) { + switch (baudRate) { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; +#if defined(__linux__) + case 460800: return B460800; + case 500000: return B500000; + case 576000: return B576000; + case 921600: return B921600; + case 1000000: return B1000000; + case 1152000: return B1152000; + case 1500000: return B1500000; + case 2000000: return B2000000; + case 2500000: return B2500000; + case 3000000: return B3000000; + case 3500000: return B3500000; + case 4000000: return B4000000; +#endif + } + return -1; +} + +#ifdef __APPLE__ +typedef struct SerialDevice { + char port[MAXPATHLEN]; + char locationId[MAXPATHLEN]; + char vendorId[MAXPATHLEN]; + char productId[MAXPATHLEN]; + char manufacturer[MAXPATHLEN]; + char serialNumber[MAXPATHLEN]; +} stSerialDevice; + +typedef struct DeviceListItem { + struct SerialDevice value; + struct DeviceListItem *next; + int* length; +} stDeviceListItem; +#endif + +int ToDataBitsConstant(int dataBits) { + switch (dataBits) { + case 8: default: return CS8; + case 7: return CS7; + case 6: return CS6; + case 5: return CS5; + } + return -1; +} + +void EIO_Open(uv_work_t* req) { + OpenBaton* data = static_cast(req->data); + + int flags = (O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC | O_SYNC); + int fd = open(data->path, flags); + + if (-1 == fd) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot open %s", strerror(errno), data->path); + return; + } + + if (-1 == setup(fd, data)) { + close(fd); + return; + } + + data->result = fd; +} + +int setBaudRate(ConnectionOptionsBaton *data) { + // lookup the standard baudrates from the table + int baudRate = ToBaudConstant(data->baudRate); + int fd = data->fd; + + // get port options + struct termios options; + if (tcgetattr(fd, &options)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: tcgetattr encountering %s", strerror(errno)); + return -1; + } + + // If there is a custom baud rate on linux you can do the following trick with B38400 + #if defined(__linux__) && defined(ASYNC_SPD_CUST) + if (baudRate == -1) { + struct serial_struct serinfo; + serinfo.reserved_char[0] = 0; + if (-1 != ioctl(fd, TIOCGSERIAL, &serinfo)) { + serinfo.flags &= ~ASYNC_SPD_MASK; + serinfo.flags |= ASYNC_SPD_CUST; + serinfo.custom_divisor = (serinfo.baud_base + (data->baudRate / 2)) / data->baudRate; + if (serinfo.custom_divisor < 1) + serinfo.custom_divisor = 1; + + ioctl(fd, TIOCSSERIAL, &serinfo); + ioctl(fd, TIOCGSERIAL, &serinfo); + } else { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s setting custom baud rate of %d", strerror(errno), data->baudRate); + return -1; + } + + // Now we use "B38400" to trigger the special baud rate. + baudRate = B38400; + } + #endif + + // On OS X, starting with Tiger, we can set a custom baud rate with ioctl + #if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) + if (-1 == baudRate) { + speed_t speed = data->baudRate; + if (-1 == ioctl(fd, IOSSIOSPEED, &speed)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s calling ioctl(.., IOSSIOSPEED, %ld )", strerror(errno), speed ); + return -1; + } else { + return 1; + } + } + #endif + + // If we have a good baud rate set it and lets go + if (-1 != baudRate) { + cfsetospeed(&options, baudRate); + cfsetispeed(&options, baudRate); + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &options); + return 1; + } + + snprintf(data->errorString, sizeof(data->errorString), "Error baud rate of %d is not supported on your platform", data->baudRate); + return -1; +} + +void EIO_Update(uv_work_t* req) { + ConnectionOptionsBaton* data = static_cast(req->data); + setBaudRate(data); +} + +int setup(int fd, OpenBaton *data) { + UnixPlatformOptions* platformOptions = static_cast(data->platformOptions); + + int dataBits = ToDataBitsConstant(data->dataBits); + if (-1 == dataBits) { + snprintf(data->errorString, sizeof(data->errorString), "Invalid data bits setting %d", data->dataBits); + return -1; + } + + // Snow Leopard doesn't have O_CLOEXEC + if (-1 == fcntl(fd, F_SETFD, FD_CLOEXEC)) { + snprintf(data->errorString, sizeof(data->errorString), "Error %s Cannot open %s", strerror(errno), data->path); + return -1; + } + + // Copy the connection options into the ConnectionOptionsBaton to set the baud rate + ConnectionOptionsBaton* connectionOptions = new ConnectionOptionsBaton(); + memset(connectionOptions, 0, sizeof(ConnectionOptionsBaton)); + connectionOptions->fd = fd; + connectionOptions->baudRate = data->baudRate; + + if (-1 == setBaudRate(connectionOptions)) { + strncpy(data->errorString, connectionOptions->errorString, sizeof(data->errorString)); + delete(connectionOptions); + return -1; + } + delete(connectionOptions); + + // Get port configuration for modification + struct termios options; + if (tcgetattr(fd, &options)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: tcgetattr encountering %s", strerror(errno)); + return -1; + } + + // IGNPAR: ignore bytes with parity errors + options.c_iflag = IGNPAR; + + // ICRNL: map CR to NL (otherwise a CR input on the other computer will not terminate input) + // Future potential option + // options.c_iflag = ICRNL; + // otherwise make device raw (no other input processing) + + // Specify data bits + options.c_cflag &= ~CSIZE; + options.c_cflag |= dataBits; + + options.c_cflag &= ~(CRTSCTS); + + if (data->rtscts) { + options.c_cflag |= CRTSCTS; + // evaluate specific flow control options + } + + options.c_iflag &= ~(IXON | IXOFF | IXANY); + + if (data->xon) { + options.c_iflag |= IXON; + } + + if (data->xoff) { + options.c_iflag |= IXOFF; + } + + if (data->xany) { + options.c_iflag |= IXANY; + } + + switch (data->parity) { + case SERIALPORT_PARITY_NONE: + options.c_cflag &= ~PARENB; + // options.c_cflag &= ~CSTOPB; + // options.c_cflag &= ~CSIZE; + // options.c_cflag |= CS8; + break; + case SERIALPORT_PARITY_ODD: + options.c_cflag |= PARENB; + options.c_cflag |= PARODD; + // options.c_cflag &= ~CSTOPB; + // options.c_cflag &= ~CSIZE; + // options.c_cflag |= CS7; + break; + case SERIALPORT_PARITY_EVEN: + options.c_cflag |= PARENB; + options.c_cflag &= ~PARODD; + // options.c_cflag &= ~CSTOPB; + // options.c_cflag &= ~CSIZE; + // options.c_cflag |= CS7; + break; + default: + snprintf(data->errorString, sizeof(data->errorString), "Invalid parity setting %d", data->parity); + return -1; + } + + switch (data->stopBits) { + case SERIALPORT_STOPBITS_ONE: + options.c_cflag &= ~CSTOPB; + break; + case SERIALPORT_STOPBITS_TWO: + options.c_cflag |= CSTOPB; + break; + default: + snprintf(data->errorString, sizeof(data->errorString), "Invalid stop bits setting %d", data->stopBits); + return -1; + } + + options.c_cflag |= CLOCAL; // ignore status lines + options.c_cflag |= CREAD; // enable receiver + if (data->hupcl) { + options.c_cflag |= HUPCL; // drop DTR (i.e. hangup) on close + } + + // Raw output + options.c_oflag = 0; + + // ICANON makes partial lines not readable. It should be optional. + // It works with ICRNL. + options.c_lflag = 0; // ICANON; + + options.c_cc[VMIN]= platformOptions->vmin; + options.c_cc[VTIME]= platformOptions->vtime; + + // why? + tcflush(fd, TCIFLUSH); + + // check for error? + tcsetattr(fd, TCSANOW, &options); + + if (data->lock){ + if (-1 == flock(fd, LOCK_EX | LOCK_NB)) { + snprintf(data->errorString, sizeof(data->errorString), "Error %s Cannot lock port", strerror(errno)); + return -1; + } + } + + return 1; +} + +void EIO_Write(uv_work_t* req) { + QueuedWrite* queuedWrite = static_cast(req->data); + WriteBaton* data = static_cast(queuedWrite->baton); + int bytesWritten = 0; + + do { + errno = 0; // probably don't need this + bytesWritten = write(data->fd, data->bufferData + data->offset, data->bufferLength - data->offset); + if (-1 != bytesWritten) { + // there wasn't an error, do the math on what we actually wrote and keep writing until finished + data->offset += bytesWritten; + continue; + } + + // The write call was interrupted before anything was written, try again immediately. + if (errno == EINTR) { + // why try again right away instead of in another event loop? + continue; + } + + // Try again in another event loop + if (errno == EAGAIN || errno == EWOULDBLOCK){ + return; + } + + // EBAD would mean we're "disconnected" + + // a real error so lets bail + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, calling write", strerror(errno)); + return; + } while (data->bufferLength > data->offset); +} + +void EIO_Close(uv_work_t* req) { + CloseBaton* data = static_cast(req->data); + if (-1 == close(data->fd)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, unable to close fd %d", strerror(errno), data->fd); + } +} + +#ifdef __APPLE__ + +// Function prototypes +static kern_return_t FindModems(io_iterator_t *matchingServices); +static io_service_t GetUsbDevice(io_service_t service); +static stDeviceListItem* GetSerialDevices(); + + +static kern_return_t FindModems(io_iterator_t *matchingServices) { + kern_return_t kernResult; + CFMutableDictionaryRef classesToMatch; + classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); + if (classesToMatch != NULL) { + CFDictionarySetValue(classesToMatch, + CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDAllTypes)); + } + + kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices); + + return kernResult; +} + +static io_service_t GetUsbDevice(io_service_t service) { + IOReturn status; + io_iterator_t iterator = 0; + io_service_t device = 0; + + if (!service) { + return device; + } + + status = IORegistryEntryCreateIterator(service, + kIOServicePlane, + (kIORegistryIterateParents | kIORegistryIterateRecursively), + &iterator); + + if (status == kIOReturnSuccess) { + io_service_t currentService; + while ((currentService = IOIteratorNext(iterator)) && device == 0) { + io_name_t serviceName; + status = IORegistryEntryGetNameInPlane(currentService, kIOServicePlane, serviceName); + if (status == kIOReturnSuccess && IOObjectConformsTo(currentService, kIOUSBDeviceClassName)) { + device = currentService; + } else { + // Release the service object which is no longer needed + (void) IOObjectRelease(currentService); + } + } + + // Release the iterator + (void) IOObjectRelease(iterator); + } + + return device; +} + +static void ExtractUsbInformation(stSerialDevice *serialDevice, IOUSBDeviceInterface **deviceInterface) { + kern_return_t kernResult; + UInt32 locationID; + kernResult = (*deviceInterface)->GetLocationID(deviceInterface, &locationID); + if (KERN_SUCCESS == kernResult) { + snprintf(serialDevice->locationId, 11, "0x%08x", locationID); + } + + UInt16 vendorID; + kernResult = (*deviceInterface)->GetDeviceVendor(deviceInterface, &vendorID); + if (KERN_SUCCESS == kernResult) { + snprintf(serialDevice->vendorId, 7, "0x%04x", vendorID); + } + + UInt16 productID; + kernResult = (*deviceInterface)->GetDeviceProduct(deviceInterface, &productID); + if (KERN_SUCCESS == kernResult) { + snprintf(serialDevice->productId, 7, "0x%04x", productID); + } +} + +static stDeviceListItem* GetSerialDevices() { + kern_return_t kernResult; + io_iterator_t serialPortIterator; + char bsdPath[MAXPATHLEN]; + + FindModems(&serialPortIterator); + + io_service_t modemService; + kernResult = KERN_FAILURE; + Boolean modemFound = false; + + // Initialize the returned path + *bsdPath = '\0'; + + stDeviceListItem* devices = NULL; + stDeviceListItem* lastDevice = NULL; + int length = 0; + + while ((modemService = IOIteratorNext(serialPortIterator))) { + CFTypeRef bsdPathAsCFString; + bsdPathAsCFString = IORegistryEntrySearchCFProperty( + modemService, + kIOServicePlane, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, + kIORegistryIterateRecursively); + + if (bsdPathAsCFString) { + Boolean result; + + // Convert the path from a CFString to a C (NUL-terminated) + result = CFStringGetCString((CFStringRef) bsdPathAsCFString, + bsdPath, + sizeof(bsdPath), + kCFStringEncodingUTF8); + CFRelease(bsdPathAsCFString); + + if (result) { + stDeviceListItem *deviceListItem = (stDeviceListItem*) malloc(sizeof(stDeviceListItem)); + stSerialDevice *serialDevice = &(deviceListItem->value); + strcpy(serialDevice->port, bsdPath); + memset(serialDevice->locationId, 0, sizeof(serialDevice->locationId)); + memset(serialDevice->vendorId, 0, sizeof(serialDevice->vendorId)); + memset(serialDevice->productId, 0, sizeof(serialDevice->productId)); + serialDevice->manufacturer[0] = '\0'; + serialDevice->serialNumber[0] = '\0'; + deviceListItem->next = NULL; + deviceListItem->length = &length; + + if (devices == NULL) { + devices = deviceListItem; + } else { + lastDevice->next = deviceListItem; + } + + lastDevice = deviceListItem; + length++; + + modemFound = true; + kernResult = KERN_SUCCESS; + + uv_mutex_lock(&list_mutex); + + io_service_t device = GetUsbDevice(modemService); + + if (device) { + CFStringRef manufacturerAsCFString = (CFStringRef) IORegistryEntryCreateCFProperty(device, + CFSTR(kUSBVendorString), + kCFAllocatorDefault, + 0); + + if (manufacturerAsCFString) { + Boolean result; + char manufacturer[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString(manufacturerAsCFString, + manufacturer, + sizeof(manufacturer), + kCFStringEncodingUTF8); + + if (result) { + strcpy(serialDevice->manufacturer, manufacturer); + } + + CFRelease(manufacturerAsCFString); + } + + CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, + kIOServicePlane, + CFSTR(kUSBSerialNumberString), + kCFAllocatorDefault, + kIORegistryIterateRecursively); + + if (serialNumberAsCFString) { + Boolean result; + char serialNumber[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString(serialNumberAsCFString, + serialNumber, + sizeof(serialNumber), + kCFStringEncodingUTF8); + + if (result) { + strcpy(serialDevice->serialNumber, serialNumber); + } + + CFRelease(serialNumberAsCFString); + } + + IOCFPlugInInterface **plugInInterface = NULL; + SInt32 score; + HRESULT res; + + IOUSBDeviceInterface **deviceInterface = NULL; + + kernResult = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, + &plugInInterface, &score); + + if ((kIOReturnSuccess != kernResult) || !plugInInterface) { + continue; + } + + // Use the plugin interface to retrieve the device interface. + res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), + (LPVOID*) &deviceInterface); + + // Now done with the plugin interface. + (*plugInInterface)->Release(plugInInterface); + + if (res || deviceInterface == NULL) { + continue; + } + + // Extract the desired Information + ExtractUsbInformation(serialDevice, deviceInterface); + + // Release the Interface + (*deviceInterface)->Release(deviceInterface); + + // Release the device + (void) IOObjectRelease(device); + } + + uv_mutex_unlock(&list_mutex); + } + } + + // Release the io_service_t now that we are done with it. + (void) IOObjectRelease(modemService); + } + + IOObjectRelease(serialPortIterator); // Release the iterator. + + return devices; +} + +#endif + +void EIO_List(uv_work_t* req) { + ListBaton* data = static_cast(req->data); + +#ifndef __APPLE__ + // This code exists in javascript for other unix platforms + snprintf(data->errorString, sizeof(data->errorString), "List is not Implemented"); + return; +# else + if (!lockInitialised) { + uv_mutex_init(&list_mutex); + lockInitialised = TRUE; + } + + stDeviceListItem* devices = GetSerialDevices(); + if (*(devices->length) > 0) { + stDeviceListItem* next = devices; + + for (int i = 0, len = *(devices->length); i < len; i++) { + stSerialDevice device = (* next).value; + + ListResultItem* resultItem = new ListResultItem(); + resultItem->comName = device.port; + + if (*device.locationId) { + resultItem->locationId = device.locationId; + } + if (*device.vendorId) { + resultItem->vendorId = device.vendorId; + } + if (*device.productId) { + resultItem->productId = device.productId; + } + if (*device.manufacturer) { + resultItem->manufacturer = device.manufacturer; + } + if (*device.serialNumber) { + resultItem->serialNumber = device.serialNumber; + } + data->results.push_back(resultItem); + + stDeviceListItem* current = next; + + if (next->next != NULL) { + next = next->next; + } + + free(current); + } + } +#endif +} + +void EIO_Flush(uv_work_t* req) { + FlushBaton* data = static_cast(req->data); + + data->result = tcflush(data->fd, TCIFLUSH); +} + +void EIO_Set(uv_work_t* req) { + SetBaton* data = static_cast(req->data); + + int bits; + ioctl(data->fd, TIOCMGET, &bits); + + bits &= ~(TIOCM_RTS | TIOCM_CTS | TIOCM_DTR | TIOCM_DSR); + + if (data->rts) { + bits |= TIOCM_RTS; + } + + if (data->cts) { + bits |= TIOCM_CTS; + } + + if (data->dtr) { + bits |= TIOCM_DTR; + } + + if (data->dsr) { + bits |= TIOCM_DSR; + } + + int result = 0; + if (data->brk) { + result = ioctl(data->fd, TIOCSBRK, NULL); + } else { + result = ioctl(data->fd, TIOCCBRK, NULL); + } + + if (-1 == result) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); + return; + } + + if (-1 == ioctl(data->fd, TIOCMSET, &bits)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); + return; + } +} + +void EIO_Drain(uv_work_t* req) { + DrainBaton* data = static_cast(req->data); + + if (-1 == tcdrain(data->fd)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno)); + return; + } +} diff --git a/vendor/node-usb-native/src/serialport_win.cpp b/vendor/node-usb-native/src/serialport_win.cpp index 0440da987..340f72beb 100644 --- a/vendor/node-usb-native/src/serialport_win.cpp +++ b/vendor/node-usb-native/src/serialport_win.cpp @@ -1,582 +1,582 @@ -#include -#include -#include -#include "./serialport.h" -#include -#include -#include -#include -#pragma comment (lib, "setupapi.lib") - -#ifdef WIN32 - -#define MAX_BUFFER_SIZE 1000 - -struct WindowsPlatformOptions : OpenBatonPlatformOptions { -}; - -OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options) { - // currently none - return new WindowsPlatformOptions(); -} - -// Declare type of pointer to CancelIoEx function -typedef BOOL (WINAPI *CancelIoExType)(HANDLE hFile, LPOVERLAPPED lpOverlapped); - -std::list g_closingHandles; -int bufferSize; -void ErrorCodeToString(const char* prefix, int errorCode, char *errorStr) { - switch (errorCode) { - case ERROR_FILE_NOT_FOUND: - _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: File not found", prefix); - break; - case ERROR_INVALID_HANDLE: - _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Invalid handle", prefix); - break; - case ERROR_ACCESS_DENIED: - _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Access denied", prefix); - break; - case ERROR_OPERATION_ABORTED: - _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: operation aborted", prefix); - break; - default: - _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Unknown error code %d", prefix, errorCode); - break; - } -} - -void EIO_Open(uv_work_t* req) { - OpenBaton* data = static_cast(req->data); - - char originalPath[1024]; - strncpy_s(originalPath, sizeof(originalPath), data->path, _TRUNCATE); - // data->path is char[1024] but on Windows it has the form "COMx\0" or "COMxx\0" - // We want to prepend "\\\\.\\" to it before we call CreateFile - strncpy(data->path + 20, data->path, 10); - strncpy(data->path, "\\\\.\\", 4); - strncpy(data->path + 4, data->path + 20, 10); - - int shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - if (data->lock) { - shareMode = 0; - } - - HANDLE file = CreateFile( - data->path, - GENERIC_READ | GENERIC_WRITE, - shareMode, // dwShareMode 0 Prevents other processes from opening if they request delete, read, or write access - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, // allows for reading and writing at the same time and sets the handle for asynchronous I/O - NULL - ); - - if (file == INVALID_HANDLE_VALUE) { - DWORD errorCode = GetLastError(); - char temp[100]; - _snprintf_s(temp, sizeof(temp), _TRUNCATE, "Opening %s", originalPath); - ErrorCodeToString(temp, errorCode, data->errorString); - return; - } - - bufferSize = data->bufferSize; - if (bufferSize > MAX_BUFFER_SIZE) { - bufferSize = MAX_BUFFER_SIZE; - } - - DCB dcb = { 0 }; - SecureZeroMemory(&dcb, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - - if (!GetCommState(file, &dcb)) { - ErrorCodeToString("Open (GetCommState)", GetLastError(), data->errorString); - CloseHandle(file); - return; - } - - if (data->hupcl) { - dcb.fDtrControl = DTR_CONTROL_ENABLE; - } else { - dcb.fDtrControl = DTR_CONTROL_DISABLE; // disable DTR to avoid reset - } - - dcb.Parity = NOPARITY; - dcb.ByteSize = 8; - dcb.StopBits = ONESTOPBIT; - dcb.fInX = FALSE; - dcb.fOutX = FALSE; - dcb.fOutxDsrFlow = FALSE; - dcb.fOutxCtsFlow = FALSE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - - dcb.fBinary = true; - dcb.BaudRate = data->baudRate; - dcb.ByteSize = data->dataBits; - - switch (data->parity) { - case SERIALPORT_PARITY_NONE: - dcb.Parity = NOPARITY; - break; - case SERIALPORT_PARITY_MARK: - dcb.Parity = MARKPARITY; - break; - case SERIALPORT_PARITY_EVEN: - dcb.Parity = EVENPARITY; - break; - case SERIALPORT_PARITY_ODD: - dcb.Parity = ODDPARITY; - break; - case SERIALPORT_PARITY_SPACE: - dcb.Parity = SPACEPARITY; - break; - } - - switch (data->stopBits) { - case SERIALPORT_STOPBITS_ONE: - dcb.StopBits = ONESTOPBIT; - break; - case SERIALPORT_STOPBITS_ONE_FIVE: - dcb.StopBits = ONE5STOPBITS; - break; - case SERIALPORT_STOPBITS_TWO: - dcb.StopBits = TWOSTOPBITS; - break; - } - - if (!SetCommState(file, &dcb)) { - ErrorCodeToString("Open (SetCommState)", GetLastError(), data->errorString); - CloseHandle(file); - return; - } - - // Set the com port read/write timeouts - DWORD serialBitsPerByte = 8/*std data bits*/ + 1/*start bit*/; - serialBitsPerByte += (data->parity == SERIALPORT_PARITY_NONE) ? 0 : 1; - serialBitsPerByte += (data->stopBits == SERIALPORT_STOPBITS_ONE) ? 1 : 2; - DWORD msPerByte = (data->baudRate > 0) ? - ((1000 * serialBitsPerByte + data->baudRate - 1) / data->baudRate) : - 1; - if (msPerByte < 1) { - msPerByte = 1; - } - COMMTIMEOUTS commTimeouts = {0}; - commTimeouts.ReadIntervalTimeout = msPerByte; // Minimize chance of concatenating of separate serial port packets on read - commTimeouts.ReadTotalTimeoutMultiplier = 0; // Do not allow big read timeout when big read buffer used - commTimeouts.ReadTotalTimeoutConstant = 1000; // Total read timeout (period of read loop) - commTimeouts.WriteTotalTimeoutConstant = 1000; // Const part of write timeout - commTimeouts.WriteTotalTimeoutMultiplier = msPerByte; // Variable part of write timeout (per byte) - if (!SetCommTimeouts(file, &commTimeouts)) { - ErrorCodeToString("Open (SetCommTimeouts)", GetLastError(), data->errorString); - CloseHandle(file); - return; - } - - // Remove garbage data in RX/TX queues - PurgeComm(file, PURGE_RXCLEAR); - PurgeComm(file, PURGE_TXCLEAR); - - data->result = (int)file; -} - -struct WatchPortBaton { - HANDLE fd; - DWORD bytesRead; - char buffer[MAX_BUFFER_SIZE]; - char errorString[ERROR_STRING_SIZE]; - DWORD errorCode; - bool disconnected; - Nan::Callback* dataCallback; - Nan::Callback* errorCallback; - Nan::Callback* disconnectedCallback; -}; - -void EIO_Update(uv_work_t* req) { - ConnectionOptionsBaton* data = static_cast(req->data); - - DCB dcb = { 0 }; - SecureZeroMemory(&dcb, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - - if (!GetCommState((HANDLE)data->fd, &dcb)) { - ErrorCodeToString("GetCommState", GetLastError(), data->errorString); - return; - } - - dcb.BaudRate = data->baudRate; - - if (!SetCommState((HANDLE)data->fd, &dcb)) { - ErrorCodeToString("SetCommState", GetLastError(), data->errorString); - return; - } -} - -void EIO_Set(uv_work_t* req) { - SetBaton* data = static_cast(req->data); - - if (data->rts) { - EscapeCommFunction((HANDLE)data->fd, SETRTS); - } else { - EscapeCommFunction((HANDLE)data->fd, CLRRTS); - } - - if (data->dtr) { - EscapeCommFunction((HANDLE)data->fd, SETDTR); - } else { - EscapeCommFunction((HANDLE)data->fd, CLRDTR); - } - - if (data->brk) { - EscapeCommFunction((HANDLE)data->fd, SETBREAK); - } else { - EscapeCommFunction((HANDLE)data->fd, CLRBREAK); - } - - DWORD bits = 0; - - GetCommMask((HANDLE)data->fd, &bits); - - bits &= ~(EV_CTS | EV_DSR); - - if (data->cts) { - bits |= EV_CTS; - } - - if (data->dsr) { - bits |= EV_DSR; - } - - if (!SetCommMask((HANDLE)data->fd, bits)) { - ErrorCodeToString("Setting options on COM port (SetCommMask)", GetLastError(), data->errorString); - return; - } -} - - -void EIO_WatchPort(uv_work_t* req) { - WatchPortBaton* data = static_cast(req->data); - data->bytesRead = 0; - data->disconnected = false; - - // Event used by GetOverlappedResult(..., TRUE) to wait for incoming data or timeout - // Event MUST be used if program has several simultaneous asynchronous operations - // on the same handle (i.e. ReadFile and WriteFile) - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - while (true) { - OVERLAPPED ov = {0}; - ov.hEvent = hEvent; - - // Start read operation - synchrounous or asynchronous - DWORD bytesReadSync = 0; - if (!ReadFile((HANDLE)data->fd, data->buffer, bufferSize, &bytesReadSync, &ov)) { - data->errorCode = GetLastError(); - if (data->errorCode != ERROR_IO_PENDING) { - // Read operation error - if (data->errorCode == ERROR_OPERATION_ABORTED) { - data->disconnected = true; - } else { - ErrorCodeToString("Reading from COM port (ReadFile)", data->errorCode, data->errorString); - CloseHandle(hEvent); - return; - } - break; - } - - // Read operation is asynchronous and is pending - // We MUST wait for operation completion before deallocation of OVERLAPPED struct - // or read data buffer - - // Wait for async read operation completion or timeout - DWORD bytesReadAsync = 0; - if (!GetOverlappedResult((HANDLE)data->fd, &ov, &bytesReadAsync, TRUE)) { - // Read operation error - data->errorCode = GetLastError(); - if (data->errorCode == ERROR_OPERATION_ABORTED) { - data->disconnected = true; - } else { - ErrorCodeToString("Reading from COM port (GetOverlappedResult)", data->errorCode, data->errorString); - CloseHandle(hEvent); - return; - } - break; - } else { - // Read operation completed asynchronously - data->bytesRead = bytesReadAsync; - } - } else { - // Read operation completed synchronously - data->bytesRead = bytesReadSync; - } - - // Return data received if any - if (data->bytesRead > 0) { - break; - } - } - - CloseHandle(hEvent); -} - -bool IsClosingHandle(int fd) { - for (std::list::iterator it = g_closingHandles.begin(); it != g_closingHandles.end(); ++it) { - if (fd == *it) { - g_closingHandles.remove(fd); - return true; - } - } - return false; -} - -void DisposeWatchPortCallbacks(WatchPortBaton* data) { - delete data->dataCallback; - delete data->errorCallback; - delete data->disconnectedCallback; -} - -// FinalizerCallback will prevent WatchPortBaton::buffer from getting -// collected by gc while finalizing v8::ArrayBuffer. The buffer will -// get cleaned up through this callback. -static void FinalizerCallback(char* data, void* hint) { - uv_work_t* req = reinterpret_cast(hint); - WatchPortBaton* wpb = static_cast(req->data); - delete wpb; - delete req; -} - -void EIO_AfterWatchPort(uv_work_t* req) { - Nan::HandleScope scope; - - WatchPortBaton* data = static_cast(req->data); - if (data->disconnected) { - data->disconnectedCallback->Call(0, NULL); - DisposeWatchPortCallbacks(data); - goto cleanup; - } - - bool skipCleanup = false; - if (data->bytesRead > 0) { - v8::Local argv[1]; - argv[0] = Nan::NewBuffer(data->buffer, data->bytesRead, FinalizerCallback, req).ToLocalChecked(); - skipCleanup = true; - data->dataCallback->Call(1, argv); - } else if (data->errorCode > 0) { - if (data->errorCode == ERROR_INVALID_HANDLE && IsClosingHandle((int)data->fd)) { - DisposeWatchPortCallbacks(data); - goto cleanup; - } else { - v8::Local argv[1]; - argv[0] = Nan::Error(data->errorString); - data->errorCallback->Call(1, argv); - Sleep(100); // prevent the errors from occurring too fast - } - } - AfterOpenSuccess((int)data->fd, data->dataCallback, data->disconnectedCallback, data->errorCallback); - -cleanup: - if (!skipCleanup) { - delete data; - delete req; - } -} - -void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback) { - WatchPortBaton* baton = new WatchPortBaton(); - memset(baton, 0, sizeof(WatchPortBaton)); - baton->fd = (HANDLE)fd; - baton->dataCallback = dataCallback; - baton->errorCallback = errorCallback; - baton->disconnectedCallback = disconnectedCallback; - - uv_work_t* req = new uv_work_t(); - req->data = baton; - - uv_queue_work(uv_default_loop(), req, EIO_WatchPort, (uv_after_work_cb)EIO_AfterWatchPort); -} - -void EIO_Write(uv_work_t* req) { - QueuedWrite* queuedWrite = static_cast(req->data); - WriteBaton* data = static_cast(queuedWrite->baton); - data->result = 0; - - do { - OVERLAPPED ov = {0}; - // Event used by GetOverlappedResult(..., TRUE) to wait for outgoing data or timeout - // Event MUST be used if program has several simultaneous asynchronous operations - // on the same handle (i.e. ReadFile and WriteFile) - ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - // Start write operation - synchronous or asynchronous - DWORD bytesWritten = 0; - if (!WriteFile((HANDLE)data->fd, data->bufferData, static_cast(data->bufferLength), &bytesWritten, &ov)) { - DWORD lastError = GetLastError(); - if (lastError != ERROR_IO_PENDING) { - // Write operation error - ErrorCodeToString("Writing to COM port (WriteFile)", lastError, data->errorString); - CloseHandle(ov.hEvent); - return; - } - // Write operation is completing asynchronously - // We MUST wait for the operation completion before deallocation of OVERLAPPED struct - // or write data buffer - - // block for async write operation completion - bytesWritten = 0; - if (!GetOverlappedResult((HANDLE)data->fd, &ov, &bytesWritten, TRUE)) { - // Write operation error - DWORD lastError = GetLastError(); - ErrorCodeToString("Writing to COM port (GetOverlappedResult)", lastError, data->errorString); - CloseHandle(ov.hEvent); - return; - } - } - // Write operation completed synchronously - data->result = bytesWritten; - data->offset += data->result; - CloseHandle(ov.hEvent); - } while (data->bufferLength > data->offset); -} - -void EIO_Close(uv_work_t* req) { - CloseBaton* data = static_cast(req->data); - - g_closingHandles.push_back(data->fd); - - HMODULE hKernel32 = LoadLibrary("kernel32.dll"); - // Look up function address - CancelIoExType pCancelIoEx = (CancelIoExType)GetProcAddress(hKernel32, "CancelIoEx"); - // Do something with it - if (pCancelIoEx) { - // Function exists so call it - // Cancel all pending IO Requests for the current device - pCancelIoEx((HANDLE)data->fd, NULL); - } - if (!CloseHandle((HANDLE)data->fd)) { - ErrorCodeToString("closing connection", GetLastError(), data->errorString); - return; - } -} - -char *copySubstring(char *someString, int n) -{ - char *new_ = (char*)malloc(sizeof(char)*n + 1); - strncpy_s(new_, n + 1, someString, n); - new_[n] = '\0'; - return new_; -} - -void EIO_List(uv_work_t* req) { - ListBaton* data = static_cast(req->data); - - GUID *guidDev = (GUID*)& GUID_DEVCLASS_PORTS; - HDEVINFO hDevInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); - SP_DEVINFO_DATA deviceInfoData; - - int memberIndex = 0; - DWORD dwSize, dwPropertyRegDataType; - char szBuffer[400]; - char *pnpId; - char *vendorId; - char *productId; - char *name; - char *manufacturer; - char *locationId; - bool isCom; - while (true) { - pnpId = NULL; - vendorId = NULL; - productId = NULL; - name = NULL; - manufacturer = NULL; - locationId = NULL; - - ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA)); - deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - - if (SetupDiEnumDeviceInfo(hDevInfo, memberIndex, &deviceInfoData) == FALSE) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) { - break; - } - } - - dwSize = sizeof(szBuffer); - SetupDiGetDeviceInstanceId(hDevInfo, &deviceInfoData, szBuffer, dwSize, &dwSize); - szBuffer[dwSize] = '\0'; - pnpId = strdup(szBuffer); - - vendorId = strstr(szBuffer, "VID_"); - if (vendorId) { - vendorId += 4; - vendorId = copySubstring(vendorId, 4); - } - productId = strstr(szBuffer, "PID_"); - if (productId) { - productId += 4; - productId = copySubstring(productId, 4); - } - - if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_LOCATION_INFORMATION, &dwPropertyRegDataType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize)) { - locationId = strdup(szBuffer); - } - if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_MFG, &dwPropertyRegDataType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize)) { - manufacturer = strdup(szBuffer); - } - - HKEY hkey = SetupDiOpenDevRegKey(hDevInfo, &deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); - if (hkey != INVALID_HANDLE_VALUE) { - dwSize = sizeof(szBuffer); - if (RegQueryValueEx(hkey, "PortName", NULL, NULL, (LPBYTE)&szBuffer, &dwSize) == ERROR_SUCCESS) { - szBuffer[dwSize] = '\0'; - name = strdup(szBuffer); - isCom = strstr(szBuffer, "COM") != NULL; - } - } - if (isCom) { - ListResultItem* resultItem = new ListResultItem(); - resultItem->comName = name; - resultItem->manufacturer = manufacturer; - resultItem->pnpId = pnpId; - if (vendorId) { - resultItem->vendorId = vendorId; - } - if (productId) { - resultItem->productId = productId; - } - if (locationId) { - resultItem->locationId = locationId; - } - data->results.push_back(resultItem); - } - free(pnpId); - free(vendorId); - free(productId); - free(locationId); - free(manufacturer); - free(name); - - RegCloseKey(hkey); - memberIndex++; - } - if (hDevInfo) { - SetupDiDestroyDeviceInfoList(hDevInfo); - } -} - -void EIO_Flush(uv_work_t* req) { - FlushBaton* data = static_cast(req->data); - - if (!FlushFileBuffers((HANDLE)data->fd)) { - ErrorCodeToString("flushing connection (FlushFileBuffers)", GetLastError(), data->errorString); - return; - } -} - -void EIO_Drain(uv_work_t* req) { - DrainBaton* data = static_cast(req->data); - - if (!FlushFileBuffers((HANDLE)data->fd)) { - ErrorCodeToString("draining connection (FlushFileBuffers)", GetLastError(), data->errorString); - return; - } -} - -#endif +#include +#include +#include +#include "./serialport.h" +#include +#include +#include +#include +#pragma comment (lib, "setupapi.lib") + +#ifdef WIN32 + +#define MAX_BUFFER_SIZE 1000 + +struct WindowsPlatformOptions : OpenBatonPlatformOptions { +}; + +OpenBatonPlatformOptions* ParsePlatformOptions(const v8::Local& options) { + // currently none + return new WindowsPlatformOptions(); +} + +// Declare type of pointer to CancelIoEx function +typedef BOOL (WINAPI *CancelIoExType)(HANDLE hFile, LPOVERLAPPED lpOverlapped); + +std::list g_closingHandles; +int bufferSize; +void ErrorCodeToString(const char* prefix, int errorCode, char *errorStr) { + switch (errorCode) { + case ERROR_FILE_NOT_FOUND: + _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: File not found", prefix); + break; + case ERROR_INVALID_HANDLE: + _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Invalid handle", prefix); + break; + case ERROR_ACCESS_DENIED: + _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Access denied", prefix); + break; + case ERROR_OPERATION_ABORTED: + _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: operation aborted", prefix); + break; + default: + _snprintf_s(errorStr, ERROR_STRING_SIZE, _TRUNCATE, "%s: Unknown error code %d", prefix, errorCode); + break; + } +} + +void EIO_Open(uv_work_t* req) { + OpenBaton* data = static_cast(req->data); + + char originalPath[1024]; + strncpy_s(originalPath, sizeof(originalPath), data->path, _TRUNCATE); + // data->path is char[1024] but on Windows it has the form "COMx\0" or "COMxx\0" + // We want to prepend "\\\\.\\" to it before we call CreateFile + strncpy(data->path + 20, data->path, 10); + strncpy(data->path, "\\\\.\\", 4); + strncpy(data->path + 4, data->path + 20, 10); + + int shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + if (data->lock) { + shareMode = 0; + } + + HANDLE file = CreateFile( + data->path, + GENERIC_READ | GENERIC_WRITE, + shareMode, // dwShareMode 0 Prevents other processes from opening if they request delete, read, or write access + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, // allows for reading and writing at the same time and sets the handle for asynchronous I/O + NULL + ); + + if (file == INVALID_HANDLE_VALUE) { + DWORD errorCode = GetLastError(); + char temp[100]; + _snprintf_s(temp, sizeof(temp), _TRUNCATE, "Opening %s", originalPath); + ErrorCodeToString(temp, errorCode, data->errorString); + return; + } + + bufferSize = data->bufferSize; + if (bufferSize > MAX_BUFFER_SIZE) { + bufferSize = MAX_BUFFER_SIZE; + } + + DCB dcb = { 0 }; + SecureZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + + if (!GetCommState(file, &dcb)) { + ErrorCodeToString("Open (GetCommState)", GetLastError(), data->errorString); + CloseHandle(file); + return; + } + + if (data->hupcl) { + dcb.fDtrControl = DTR_CONTROL_ENABLE; + } else { + dcb.fDtrControl = DTR_CONTROL_DISABLE; // disable DTR to avoid reset + } + + dcb.Parity = NOPARITY; + dcb.ByteSize = 8; + dcb.StopBits = ONESTOPBIT; + dcb.fInX = FALSE; + dcb.fOutX = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fOutxCtsFlow = FALSE; + dcb.fRtsControl = RTS_CONTROL_ENABLE; + + dcb.fBinary = true; + dcb.BaudRate = data->baudRate; + dcb.ByteSize = data->dataBits; + + switch (data->parity) { + case SERIALPORT_PARITY_NONE: + dcb.Parity = NOPARITY; + break; + case SERIALPORT_PARITY_MARK: + dcb.Parity = MARKPARITY; + break; + case SERIALPORT_PARITY_EVEN: + dcb.Parity = EVENPARITY; + break; + case SERIALPORT_PARITY_ODD: + dcb.Parity = ODDPARITY; + break; + case SERIALPORT_PARITY_SPACE: + dcb.Parity = SPACEPARITY; + break; + } + + switch (data->stopBits) { + case SERIALPORT_STOPBITS_ONE: + dcb.StopBits = ONESTOPBIT; + break; + case SERIALPORT_STOPBITS_ONE_FIVE: + dcb.StopBits = ONE5STOPBITS; + break; + case SERIALPORT_STOPBITS_TWO: + dcb.StopBits = TWOSTOPBITS; + break; + } + + if (!SetCommState(file, &dcb)) { + ErrorCodeToString("Open (SetCommState)", GetLastError(), data->errorString); + CloseHandle(file); + return; + } + + // Set the com port read/write timeouts + DWORD serialBitsPerByte = 8/*std data bits*/ + 1/*start bit*/; + serialBitsPerByte += (data->parity == SERIALPORT_PARITY_NONE) ? 0 : 1; + serialBitsPerByte += (data->stopBits == SERIALPORT_STOPBITS_ONE) ? 1 : 2; + DWORD msPerByte = (data->baudRate > 0) ? + ((1000 * serialBitsPerByte + data->baudRate - 1) / data->baudRate) : + 1; + if (msPerByte < 1) { + msPerByte = 1; + } + COMMTIMEOUTS commTimeouts = {0}; + commTimeouts.ReadIntervalTimeout = msPerByte; // Minimize chance of concatenating of separate serial port packets on read + commTimeouts.ReadTotalTimeoutMultiplier = 0; // Do not allow big read timeout when big read buffer used + commTimeouts.ReadTotalTimeoutConstant = 1000; // Total read timeout (period of read loop) + commTimeouts.WriteTotalTimeoutConstant = 1000; // Const part of write timeout + commTimeouts.WriteTotalTimeoutMultiplier = msPerByte; // Variable part of write timeout (per byte) + if (!SetCommTimeouts(file, &commTimeouts)) { + ErrorCodeToString("Open (SetCommTimeouts)", GetLastError(), data->errorString); + CloseHandle(file); + return; + } + + // Remove garbage data in RX/TX queues + PurgeComm(file, PURGE_RXCLEAR); + PurgeComm(file, PURGE_TXCLEAR); + + data->result = (int)file; +} + +struct WatchPortBaton { + HANDLE fd; + DWORD bytesRead; + char buffer[MAX_BUFFER_SIZE]; + char errorString[ERROR_STRING_SIZE]; + DWORD errorCode; + bool disconnected; + Nan::Callback* dataCallback; + Nan::Callback* errorCallback; + Nan::Callback* disconnectedCallback; +}; + +void EIO_Update(uv_work_t* req) { + ConnectionOptionsBaton* data = static_cast(req->data); + + DCB dcb = { 0 }; + SecureZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + + if (!GetCommState((HANDLE)data->fd, &dcb)) { + ErrorCodeToString("GetCommState", GetLastError(), data->errorString); + return; + } + + dcb.BaudRate = data->baudRate; + + if (!SetCommState((HANDLE)data->fd, &dcb)) { + ErrorCodeToString("SetCommState", GetLastError(), data->errorString); + return; + } +} + +void EIO_Set(uv_work_t* req) { + SetBaton* data = static_cast(req->data); + + if (data->rts) { + EscapeCommFunction((HANDLE)data->fd, SETRTS); + } else { + EscapeCommFunction((HANDLE)data->fd, CLRRTS); + } + + if (data->dtr) { + EscapeCommFunction((HANDLE)data->fd, SETDTR); + } else { + EscapeCommFunction((HANDLE)data->fd, CLRDTR); + } + + if (data->brk) { + EscapeCommFunction((HANDLE)data->fd, SETBREAK); + } else { + EscapeCommFunction((HANDLE)data->fd, CLRBREAK); + } + + DWORD bits = 0; + + GetCommMask((HANDLE)data->fd, &bits); + + bits &= ~(EV_CTS | EV_DSR); + + if (data->cts) { + bits |= EV_CTS; + } + + if (data->dsr) { + bits |= EV_DSR; + } + + if (!SetCommMask((HANDLE)data->fd, bits)) { + ErrorCodeToString("Setting options on COM port (SetCommMask)", GetLastError(), data->errorString); + return; + } +} + + +void EIO_WatchPort(uv_work_t* req) { + WatchPortBaton* data = static_cast(req->data); + data->bytesRead = 0; + data->disconnected = false; + + // Event used by GetOverlappedResult(..., TRUE) to wait for incoming data or timeout + // Event MUST be used if program has several simultaneous asynchronous operations + // on the same handle (i.e. ReadFile and WriteFile) + HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + while (true) { + OVERLAPPED ov = {0}; + ov.hEvent = hEvent; + + // Start read operation - synchrounous or asynchronous + DWORD bytesReadSync = 0; + if (!ReadFile((HANDLE)data->fd, data->buffer, bufferSize, &bytesReadSync, &ov)) { + data->errorCode = GetLastError(); + if (data->errorCode != ERROR_IO_PENDING) { + // Read operation error + if (data->errorCode == ERROR_OPERATION_ABORTED) { + data->disconnected = true; + } else { + ErrorCodeToString("Reading from COM port (ReadFile)", data->errorCode, data->errorString); + CloseHandle(hEvent); + return; + } + break; + } + + // Read operation is asynchronous and is pending + // We MUST wait for operation completion before deallocation of OVERLAPPED struct + // or read data buffer + + // Wait for async read operation completion or timeout + DWORD bytesReadAsync = 0; + if (!GetOverlappedResult((HANDLE)data->fd, &ov, &bytesReadAsync, TRUE)) { + // Read operation error + data->errorCode = GetLastError(); + if (data->errorCode == ERROR_OPERATION_ABORTED) { + data->disconnected = true; + } else { + ErrorCodeToString("Reading from COM port (GetOverlappedResult)", data->errorCode, data->errorString); + CloseHandle(hEvent); + return; + } + break; + } else { + // Read operation completed asynchronously + data->bytesRead = bytesReadAsync; + } + } else { + // Read operation completed synchronously + data->bytesRead = bytesReadSync; + } + + // Return data received if any + if (data->bytesRead > 0) { + break; + } + } + + CloseHandle(hEvent); +} + +bool IsClosingHandle(int fd) { + for (std::list::iterator it = g_closingHandles.begin(); it != g_closingHandles.end(); ++it) { + if (fd == *it) { + g_closingHandles.remove(fd); + return true; + } + } + return false; +} + +void DisposeWatchPortCallbacks(WatchPortBaton* data) { + delete data->dataCallback; + delete data->errorCallback; + delete data->disconnectedCallback; +} + +// FinalizerCallback will prevent WatchPortBaton::buffer from getting +// collected by gc while finalizing v8::ArrayBuffer. The buffer will +// get cleaned up through this callback. +static void FinalizerCallback(char* data, void* hint) { + uv_work_t* req = reinterpret_cast(hint); + WatchPortBaton* wpb = static_cast(req->data); + delete wpb; + delete req; +} + +void EIO_AfterWatchPort(uv_work_t* req) { + Nan::HandleScope scope; + + WatchPortBaton* data = static_cast(req->data); + if (data->disconnected) { + data->disconnectedCallback->Call(0, NULL); + DisposeWatchPortCallbacks(data); + goto cleanup; + } + + bool skipCleanup = false; + if (data->bytesRead > 0) { + v8::Local argv[1]; + argv[0] = Nan::NewBuffer(data->buffer, data->bytesRead, FinalizerCallback, req).ToLocalChecked(); + skipCleanup = true; + data->dataCallback->Call(1, argv); + } else if (data->errorCode > 0) { + if (data->errorCode == ERROR_INVALID_HANDLE && IsClosingHandle((int)data->fd)) { + DisposeWatchPortCallbacks(data); + goto cleanup; + } else { + v8::Local argv[1]; + argv[0] = Nan::Error(data->errorString); + data->errorCallback->Call(1, argv); + Sleep(100); // prevent the errors from occurring too fast + } + } + AfterOpenSuccess((int)data->fd, data->dataCallback, data->disconnectedCallback, data->errorCallback); + +cleanup: + if (!skipCleanup) { + delete data; + delete req; + } +} + +void AfterOpenSuccess(int fd, Nan::Callback* dataCallback, Nan::Callback* disconnectedCallback, Nan::Callback* errorCallback) { + WatchPortBaton* baton = new WatchPortBaton(); + memset(baton, 0, sizeof(WatchPortBaton)); + baton->fd = (HANDLE)fd; + baton->dataCallback = dataCallback; + baton->errorCallback = errorCallback; + baton->disconnectedCallback = disconnectedCallback; + + uv_work_t* req = new uv_work_t(); + req->data = baton; + + uv_queue_work(uv_default_loop(), req, EIO_WatchPort, (uv_after_work_cb)EIO_AfterWatchPort); +} + +void EIO_Write(uv_work_t* req) { + QueuedWrite* queuedWrite = static_cast(req->data); + WriteBaton* data = static_cast(queuedWrite->baton); + data->result = 0; + + do { + OVERLAPPED ov = {0}; + // Event used by GetOverlappedResult(..., TRUE) to wait for outgoing data or timeout + // Event MUST be used if program has several simultaneous asynchronous operations + // on the same handle (i.e. ReadFile and WriteFile) + ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + // Start write operation - synchronous or asynchronous + DWORD bytesWritten = 0; + if (!WriteFile((HANDLE)data->fd, data->bufferData, static_cast(data->bufferLength), &bytesWritten, &ov)) { + DWORD lastError = GetLastError(); + if (lastError != ERROR_IO_PENDING) { + // Write operation error + ErrorCodeToString("Writing to COM port (WriteFile)", lastError, data->errorString); + CloseHandle(ov.hEvent); + return; + } + // Write operation is completing asynchronously + // We MUST wait for the operation completion before deallocation of OVERLAPPED struct + // or write data buffer + + // block for async write operation completion + bytesWritten = 0; + if (!GetOverlappedResult((HANDLE)data->fd, &ov, &bytesWritten, TRUE)) { + // Write operation error + DWORD lastError = GetLastError(); + ErrorCodeToString("Writing to COM port (GetOverlappedResult)", lastError, data->errorString); + CloseHandle(ov.hEvent); + return; + } + } + // Write operation completed synchronously + data->result = bytesWritten; + data->offset += data->result; + CloseHandle(ov.hEvent); + } while (data->bufferLength > data->offset); +} + +void EIO_Close(uv_work_t* req) { + CloseBaton* data = static_cast(req->data); + + g_closingHandles.push_back(data->fd); + + HMODULE hKernel32 = LoadLibrary("kernel32.dll"); + // Look up function address + CancelIoExType pCancelIoEx = (CancelIoExType)GetProcAddress(hKernel32, "CancelIoEx"); + // Do something with it + if (pCancelIoEx) { + // Function exists so call it + // Cancel all pending IO Requests for the current device + pCancelIoEx((HANDLE)data->fd, NULL); + } + if (!CloseHandle((HANDLE)data->fd)) { + ErrorCodeToString("closing connection", GetLastError(), data->errorString); + return; + } +} + +char *copySubstring(char *someString, int n) +{ + char *new_ = (char*)malloc(sizeof(char)*n + 1); + strncpy_s(new_, n + 1, someString, n); + new_[n] = '\0'; + return new_; +} + +void EIO_List(uv_work_t* req) { + ListBaton* data = static_cast(req->data); + + GUID *guidDev = (GUID*)& GUID_DEVCLASS_PORTS; + HDEVINFO hDevInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); + SP_DEVINFO_DATA deviceInfoData; + + int memberIndex = 0; + DWORD dwSize, dwPropertyRegDataType; + char szBuffer[400]; + char *pnpId; + char *vendorId; + char *productId; + char *name; + char *manufacturer; + char *locationId; + bool isCom; + while (true) { + pnpId = NULL; + vendorId = NULL; + productId = NULL; + name = NULL; + manufacturer = NULL; + locationId = NULL; + + ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA)); + deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + if (SetupDiEnumDeviceInfo(hDevInfo, memberIndex, &deviceInfoData) == FALSE) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + break; + } + } + + dwSize = sizeof(szBuffer); + SetupDiGetDeviceInstanceId(hDevInfo, &deviceInfoData, szBuffer, dwSize, &dwSize); + szBuffer[dwSize] = '\0'; + pnpId = strdup(szBuffer); + + vendorId = strstr(szBuffer, "VID_"); + if (vendorId) { + vendorId += 4; + vendorId = copySubstring(vendorId, 4); + } + productId = strstr(szBuffer, "PID_"); + if (productId) { + productId += 4; + productId = copySubstring(productId, 4); + } + + if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_LOCATION_INFORMATION, &dwPropertyRegDataType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize)) { + locationId = strdup(szBuffer); + } + if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_MFG, &dwPropertyRegDataType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize)) { + manufacturer = strdup(szBuffer); + } + + HKEY hkey = SetupDiOpenDevRegKey(hDevInfo, &deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + if (hkey != INVALID_HANDLE_VALUE) { + dwSize = sizeof(szBuffer); + if (RegQueryValueEx(hkey, "PortName", NULL, NULL, (LPBYTE)&szBuffer, &dwSize) == ERROR_SUCCESS) { + szBuffer[dwSize] = '\0'; + name = strdup(szBuffer); + isCom = strstr(szBuffer, "COM") != NULL; + } + } + if (isCom) { + ListResultItem* resultItem = new ListResultItem(); + resultItem->comName = name; + resultItem->manufacturer = manufacturer; + resultItem->pnpId = pnpId; + if (vendorId) { + resultItem->vendorId = vendorId; + } + if (productId) { + resultItem->productId = productId; + } + if (locationId) { + resultItem->locationId = locationId; + } + data->results.push_back(resultItem); + } + free(pnpId); + free(vendorId); + free(productId); + free(locationId); + free(manufacturer); + free(name); + + RegCloseKey(hkey); + memberIndex++; + } + if (hDevInfo) { + SetupDiDestroyDeviceInfoList(hDevInfo); + } +} + +void EIO_Flush(uv_work_t* req) { + FlushBaton* data = static_cast(req->data); + + if (!FlushFileBuffers((HANDLE)data->fd)) { + ErrorCodeToString("flushing connection (FlushFileBuffers)", GetLastError(), data->errorString); + return; + } +} + +void EIO_Drain(uv_work_t* req) { + DrainBaton* data = static_cast(req->data); + + if (!FlushFileBuffers((HANDLE)data->fd)) { + ErrorCodeToString("draining connection (FlushFileBuffers)", GetLastError(), data->errorString); + return; + } +} + +#endif