diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b8b2ac5a1..7bd16fe97 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,3 @@ # At least one of the code owners below will be required on each PR: -* @markAtMicrosoft @smmatte @adclements @abmahdy @LukeSlev +* @markAtMicrosoft @smmatte @adclements @abmahdy @iennae @nasadigital @isadorasophia @sagarmanchanda diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 46be84230..ef9bbe450 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -25,6 +25,7 @@ Please describe the tests that you ran to verify your changes. Provide instructi # Checklist: - [ ] My code follows the style guidelines of this project +- [ ] My code has been formatted with `npm run format` and passes the checks in `npm run check` - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 000000000..5379f1e00 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,5 @@ +trailingComma: "es5" +tabWidth: 4 +semi: true +endOfLine: auto +printWidth: 80 \ No newline at end of file diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 000000000..5a62b6ca1 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,586 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + deprecated-operator-function, + deprecated-urllib-function, + xreadlines-attribute, + deprecated-sys-function, + exception-escape, + comprehension-escape, + missing-function-docstring, + missing-module-docstring, + too-many-public-methods, + missing-class-docstring, + invalid-name + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'error', 'warning', 'refactor', and 'convention' +# which contain the number of messages in each category, as well as 'statement' +# which is the total number of statements analyzed. This score is used by the +# global evaluation report (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it work, +# install the python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[STRING] + +# This flag controls whether the implicit-str-concat-in-sequence should +# generate a warning on implicit string concatenation in sequences defined over +# several lines. +check-str-concat-over-line-jumps=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "BaseException, Exception". +overgeneral-exceptions=BaseException, + Exception diff --git a/README.md b/README.md index f58a1cde4..9ecc0c8b2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Circuit Playground Express (CPX) projects! Test and debug your code on the devic 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](https://www.microsoft.com/en-us/garage/wp-content/uploads/sites/5/2019/08/cpx.jpg) +CircuitPlayground Express ## Features @@ -29,7 +29,7 @@ monitor allows you to observe the device output. - Temperature sensor - 7 Capacitive Touch sensors -The simulator supports most of the sensors on CPX except **IR transmitter & Receiver**, **Sound Sensor (microphone)**, **Speaker (Play Tone)** and the **“tap” on Motion Sensor**. +The simulator supports most of the sensors on CPX except **IR transmitter & Receiver**, **Sound Sensor (microphone)**, **Speaker (Play Tone)** and the **"tap" on Motion Sensor**. 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! @@ -43,53 +43,49 @@ You will be prompted to install the Python dependencies during the first use. - _**[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. -The following dependecies can be installed for you by the extension by clicking yes when you are prompted to (**except** `pywin32` which is needed only on Windows platform). (2) +- 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` -- _**Playsound**_ - install by typing the following commands in a console: `pip install playsound` - -- _**Pywin 32**_ - install by typing the following commands in a console (only for Windows computers, you must run it manually): `pip install pywin32` -- _**Python-Socketio**_ - install by typing the following commands in a console: `pip install python-socketio` -- _**Requests**_ - install by typing the following commands in a console: `pip install requests` -- _**Application Insights**_ - install by typing the following commands in a console: `pip install applicationinsights` ## 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) - - Adafruit CPX Guided Tour (Intro for the Hardware) (https://learn.adafruit.com/adafruit-circuit-playground-express/guided-tour) + - [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) + - [Adafruit CPX Guided Tour (Intro for the Hardware)](https://learn.adafruit.com/adafruit-circuit-playground-express/guided-tour) - Format Adafruit CPX device: - - 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 (link: https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries) + - [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 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 "New File" Command. -1. Type in Device Simulator Express: New File” in the command palette(`CTRL+SHIFT+P`to open the command palette). - !["New File" animation](https://www.microsoft.com/en-us/garage/wp-content/uploads/sites/5/2019/08/newFile.gif) -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. +1. Type in `"Device Simulator 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. -![How to find example code screenshot](https://www.microsoft.com/en-us/garage/wp-content/uploads/sites/5/2019/08/findExamples.jpg) +How to find example code screenshot ### 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. -### 3. Run your code on the simulator . +### 3. Run your code on the simulator. -![How to run the simulator animation](https://www.microsoft.com/en-us/garage/wp-content/uploads/sites/5/2019/08/run.gif) +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. @@ -100,14 +96,16 @@ Before deploying the python code to your CPX device, you need to format your dev 1. Download the firmware with the .uf2 file (link: https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart) 2. Download the lastest version of the cpx library (link: https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries). - **_Note:_** Make sure you name your file main.py or code.py: the device automatically runs the first file that is likely named. + **_Note:_** Make sure you name your file `main.py` or `code.py`: the device automatically runs the first file that is likely named. This is the convention for CircuitPython ([source](https://learn.adafruit.com/welcome-to-circuitpython/creating-and-editing-code#naming-your-program-file-7-32)). + +Then, if you are on Windows, you will also need to install the Python Pywin32 package. Use the following command in the console: `pip install pywin32` -!["Deploy to Device" example](https://www.microsoft.com/en-us/garage/wp-content/uploads/sites/5/2019/08/deployToBoard.png) +Deploy to Device -### 5. Use the Serial Monitor for your Adafruit CPX device(available 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: 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 @@ -129,10 +127,10 @@ or by using the toolbar. 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 open the simulator. +- `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 Board`: Copies & Pastes the code.py or main.py file to CIRCUITPY drive if detected a CPX is plugged in +- `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. @@ -184,9 +182,8 @@ A `ThirdPartyNotices.txt` file is provided in the extension's source code listin - The first time you install the extension, you'll need to execute the `run` command at least once in order to access auto-completion. - 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 have pylint enabled, it might underline the import of the adafruit_circuitplayground library, but it will work correctly. - 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 @@ -217,6 +214,6 @@ A `ThirdPartyNotices.txt` file is provided in the extension's source code listin ## Notes -(1) Note: the easiest way to do it is to select the "Add to PATH" option directly when you install Python. Otherwise you can search how to insert it manually, but make sure that when you type _python_ in a terminal, the command is recognized and have the correct version. -(2) You can chose to see to see the prompt or not by changing the extension configirations. -(3) To be able to run the file from your physical device, it should either be named code.py or main.py. +1. Make sure that when you type _python_ in a terminal, the command is recognized and you have the correct version. The easiest way to do it is to select the "Add to PATH" option directly when you install Python. Otherwise you can search how to insert it manually. +2. You can choose to see the prompt or not by changing the extension configurations. +3. To be able to run the file on your physical device, it should either be named code.py or main.py. diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index e1c8043aa..26648250b 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -5771,6 +5771,64 @@ Copyright 2018 Kenneth Reitz limitations under the License. +Jest +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +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. + + +Black +The MIT License (MIT) + +Copyright (c) 2018 Łukasz Langa + +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. + + +Prettier +Copyright © James Long and contributors + +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/docs/developers-setup.md b/docs/developers-setup.md index d9eb3a2b1..a31842a89 100644 --- a/docs/developers-setup.md +++ b/docs/developers-setup.md @@ -13,29 +13,23 @@ - **NOTE :** Make sure pip is added to your environment variables as well (for example it could be found at : `c:\users\<...>\appdata\local\programs\python\python37\lib\site-packages\pip`) - Run in a console `python -m pip install --upgrade pip` - + * Python Modules - - - **Note:** On extension activation you will be prompted a popup asking if you want the modules to be automatically installed for you, **except** `pywin32` which is needed only on Windows platform. - - Playsound - - Run the command in a console : `pip install playsound` - - pytest - - Run the command in a console : `pip install pytest` - - Pywin32 - - **Note:** This is only needed for Windows computers. You must install it manually with the above command! - - Run the command in a console : `pip install pywin32` - - Python-Socketio - - Run the command in a console : `pip install python-socketio` - - Requests - - Run the command in a console : `pip install requests` - - Application Insights - - Run the command in a console : `pip install applicationinsights` - + - **Note:** On extension activation, you will be prompted with a popup 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. + - pywin32 **(on Windows only)** + - On Windows, you need to use the following command in the console to manually install pywin32: `pip install pywin32` + - *playsound* + - *pytest* + - *python-socketio* + - *requests* + - *applicationinsights* + + *italics*: used in simulation mode only * VS Code * Python extension for VS Code (download from VS Code market place) -## Steps to Get Started Running the Extension in Debug Mode +## Steps to Get Started Running the Extension Locally 1. Make sure you have all the dependencies installed (Node, Python, Playsound, VS Code, Python VS Code extension) @@ -47,17 +41,30 @@ 5. Run the command : `npm run compile` -6. Start debugging the extension by pressing F5 or going to VS Code Debug menu and select 'Start debugging' +6. Start running the extension locally by pressing F5 or going to VS Code Debug menu and select 'Start debugging' + +## Testing + +- To run unit tests, run the command: `npm run test` in the root level directory. + - You will need Pytest installed for the Python tests to run correctly +- To run just the python tests, run the command: `pytest src` or `python -m pytest src` in the root level directory. ## Notes on how to use it - [Documentation to use the Extension](/docs/how-to-use.md) -- Debugging the extension opens a new VS Code window with the extension installed +- Debugging the extension opens a new VS Code window with the local build of the extension - From the original VS Code window (opened in our repository) you can see outputs in the Debug Console - In the new VS Code window, you can access the commands provided by the extension from the Commands Palette (Ctrl+Shift+P) listed as 'Device Simulator Express : ...' - If you change some files you'll need to run the 'npm run compile' command again and restart debugging +## Formatting + +- We use prettier to format the Typescript and CSS files, and we use black to format the Python files. + - You will need to install them, if they are not installed already. This can be done by running the command: `npm install prettier` and `pip install black` respectively. +- To check that your files are formatted correctly, run the command: `npm run check`. +- To format your files correctly, run the command: `npm run format`. + ## Repository Structure (important files) - src diff --git a/docs/how-to-use.md b/docs/how-to-use.md index 6f6892ab4..09c497710 100644 --- a/docs/how-to-use.md +++ b/docs/how-to-use.md @@ -2,7 +2,7 @@ Commands are accessible through : -- **The command palette** (`Ctrl+shift+P` or `View->Command Palette`) and type 'Device Simulator Express : `command_name`' +- **The command palette** (`Ctrl+Shift+P` or `View->Command Palette`) and type 'Device Simulator Express : `command_name`' - **The extension buttons** available on the top right of the Text Editor Panel when you have a Python file open (1) ## Available commands @@ -12,11 +12,11 @@ Commands are accessible through : - **New File** : opens an unsaved file with links to help you and a code snippet that you can save as `code.py` / `main.py`. _(**Note :** will open the simulator webview if it's not open yet)_. -- **Run Simulator** : run the code you have open on the simulator (make sure you've clicked on a valid code file). +- **Run Simulator** : runs the code you have opened in the simulator (make sure you've clicked on a valid code file). _(**Note :** will open the simulator webview if it's not open yet)_. - **Deploy to Device** : saves the code to a Circuit Playground Express. - _(**Note :** the board needs to be correctly formatted to a `CIRCUITPY` drive first if it's not the case : [Installing CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython))_. + _(**Note :** the board needs to be correctly formatted to a `CIRCUITPY` drive first. If that's not the case check [Installing CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython) to correctly format it)_. * **Select Serial Port** : selects the serial port of the board you want the serial monitor to interact with. (2) _(**Note :** USB detection must be enabled in the extension settings.)_ @@ -82,7 +82,6 @@ Here are the settings you can change in the Device Simulator Express configurati - The first time you install the extension, you'll need to execute the `run` command at least once in order to access auto-completion. - 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 have pylint enabled, it might underline the import of the adafruit_circuitplayground library, but it will work correctly. - 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 you `Settings` and check the port used under `'Device Simulator Express: Debugger Server Port'`. You can either change it (usually ports above 5000 could work) or try to free it, then start debugging again. diff --git a/docs/install.md b/docs/install.md index b0d782d2d..8a8421d6e 100644 --- a/docs/install.md +++ b/docs/install.md @@ -22,15 +22,18 @@ _Note: You need to install all the dependencies in order to use the extension._ _(Note: the easiest way to do it might be when you install Python, you can select the "Add to PATH" option directly. Otherwise you can search how to insert it manually, but make sure that when you type `python` (or `python3.7`) in a terminal, the command is recognized.)_ - [Python VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) - **Note:** This extension is installed automatically from the marketplace when you install our extension -- Python Modules - - **Note:** On extension activation you will be prompted a popup asking if you want the modules to be automatically installed for you, **except** `pywin32` which is needed only on Windows platform. - - Playsound : `pip install playsound` - - Pywin32 : `pip install pywin32` - - **Note:** This is only needed for Windows computers. You must install it manually with the above command! - - Python-Socketio : `pip install python-socketio` - - Requests : `pip install requests` - - Application Insights: `pip install applicationinsights` + +* Python Modules + - **Note:** On extension activation, you will be prompted with a popup 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.** + - pywin32 **(on Windows only)**: `pip install pywin32` + - On Windows, you need to use the above command in the console to manually install pywin32. + - *playsound*: `pip install playsound` + - *pytest*: `pip install pytest` + - *python-socketio*: `pip install python-socketio` + - *requests*: `pip install requests` + - *applicationinsights*: `pip install applicationinsights` + *italics*: used in simulation mode only ## How to use the Extension - [How to use the Extension](/docs/how-to-use.md) diff --git a/gulpfile.js b/gulpfile.js index fdc6fcac2..3c106798d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -25,7 +25,7 @@ const languages = [{ folderName: "en", id: "en" }]; gulp.task("clean", () => { return del( [ - "out/!(python_libs)", + "out/*", "package.nls.*.json", "../../dist/*0.0.0-UNTRACKEDVERSION.vsix" ], @@ -36,7 +36,7 @@ gulp.task("clean", () => { const pythonToMove = [ "./src/adafruit_circuitplayground/*.*", "./src/*.py", - "./src/requirements.txt" + "./src/requirements.txt", ]; gulp.task("python-compile", () => { diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..3d7f4f549 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,28 @@ +module.exports = { + // The root of your source code, typically /src + // `` is a token Jest substitutes + roots: ["/src"], + + // Jest transformations -- this adds support for TypeScript + // using ts-jest + transform: { + '^.+\\.tsx?$': 'ts-jest', + ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css" + }, + + // Runs special logic, such as cleaning up components + // when using React Testing Library and adds special + // extended assertions to Jest + setupFilesAfterEnv: [ + "@testing-library/jest-dom/extend-expect" + ], + + // Test spec file resolution pattern + // Matches parent folder `__tests__` and filename + // should contain `test` or `spec`. + testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$", + + // Module file extensions for importing + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + + }; \ No newline at end of file diff --git a/locales/en/out/constants.i18n.json b/locales/en/out/constants.i18n.json index 40744b520..d805009c8 100644 --- a/locales/en/out/constants.i18n.json +++ b/locales/en/out/constants.i18n.json @@ -9,6 +9,7 @@ "dialogResponses.installNow": "Install Now", "dialogResponses.dontInstall": "Don't Install", "dialogResponses.tutorials": "Tutorials on Adafruit", + "dialogResponses.readInstall": "Read installation docs", "error.debuggerServerInitFailed": "Warning : The Debugger Server cannot be opened. Please try to free the port {0} if it's already in use or select another one in your Settings 'Device Simulator Express: Debugger Server Port' and start another debug session.\n You can still debug your code but you won't be able to use the Simulator.", "error.debuggingSessionInProgress": "[ERROR] A debugging session is currently in progress, please stop it before running your code. \n", "error.incorrectFileNameForDevice": "[ERROR] Can\\'t deploy to your Circuit Playground Express device, please rename your file to \"code.py\" or \"main.py\". \n", @@ -35,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 Adafruit Simulator output tab!\n\n", "label.webviewPanel": "Device Simulator Express", "name": "Device Simulator Express", diff --git a/package-lock.json b/package-lock.json index b0c2c98d8..87a51978c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, "requires": { "@babel/highlight": "^7.0.0" } @@ -17,7 +16,6 @@ "version": "7.4.3", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz", "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.0", @@ -39,7 +37,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, "requires": { "minimist": "^1.2.0" } @@ -47,8 +44,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -56,7 +52,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "dev": true, "requires": { "@babel/types": "^7.4.4", "jsesc": "^2.5.1", @@ -68,14 +63,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "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=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -158,7 +151,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", @@ -169,7 +161,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -227,8 +218,7 @@ "@babel/helper-plugin-utils": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-regex": { "version": "7.4.4", @@ -278,7 +268,6 @@ "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==", - "dev": true, "requires": { "@babel/types": "^7.4.4" } @@ -299,7 +288,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", - "dev": true, "requires": { "@babel/template": "^7.4.4", "@babel/traverse": "^7.4.4", @@ -310,7 +298,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -321,7 +308,6 @@ "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" } @@ -330,7 +316,6 @@ "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", @@ -341,7 +326,6 @@ "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" } @@ -351,8 +335,7 @@ "@babel/parser": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", - "dev": true + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", @@ -467,6 +450,21 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "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", @@ -516,7 +514,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -531,12 +528,18 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", - "integrity": "sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag==", - "dev": true, + "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.0.0" + "@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": { @@ -937,13 +940,192 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz", - "integrity": "sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g==", - "dev": true, + "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-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-typescript": "^7.2.0" + "@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": { @@ -1058,13 +1240,19 @@ } }, "@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==", - "dev": true, + "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.0.0", - "@babel/plugin-transform-typescript": "^7.3.2" + "@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": { @@ -1080,7 +1268,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.4.4", @@ -1091,7 +1278,6 @@ "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", @@ -1108,18 +1294,21 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, "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==", - "dev": true, "requires": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" @@ -1205,6 +1394,59 @@ "@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==", + "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.7.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", @@ -1248,187 +1490,897 @@ } }, "@jest/core": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.8.0.tgz", - "integrity": "sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/reporters": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", + "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.1.15", - "jest-changed-files": "^24.8.0", - "jest-config": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-resolve-dependencies": "^24.8.0", - "jest-runner": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "jest-watcher": "^24.8.0", - "micromatch": "^3.1.10", - "p-each-series": "^1.0.0", - "pirates": "^4.0.1", + "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": "^2.5.4", - "strip-ansi": "^5.0.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==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, + "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": { - "glob": "^7.1.3" + "color-name": "~1.1.4" } }, - "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, + "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": { - "ansi-regex": "^4.1.0" + "to-regex-range": "^5.0.1" } }, - "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, + "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": { - "has-flag": "^3.0.0" + "@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/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.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" - } + }, + "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/reporters": { + "@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" + } + } + } + }, + "@jest/fake-timers": { "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.8.0.tgz", - "integrity": "sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw==", + "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/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/transform": "^24.8.0", "@jest/types": "^24.8.0", - "chalk": "^2.0.1", + "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": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", + "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", + "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": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.1.1", - "jest-haste-map": "^24.8.0", - "jest-resolve": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.2.1", - "slash": "^2.0.0", + "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": "^2.0.0" + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.0.1" }, "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/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": { + "@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-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/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" + } + }, + "@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" + }, + "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" + } + } + } + }, + "@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" + } + }, + "@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-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": "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, + "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" + } + }, + "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==" + }, + "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" + } + }, + "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==" + }, + "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/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": { + "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" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "requires": { - "color-convert": "^1.9.0" + "minimist": "^1.2.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, + "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==" + }, + "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" } }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "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==", "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + "ansi-regex": "^4.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, + "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": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -1461,83 +2413,594 @@ "@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, + "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/test-sequencer": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz", - "integrity": "sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg==", - "dev": true, - "requires": { - "@jest/test-result": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-runner": "^24.8.0", - "jest-runtime": "^24.8.0" + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", + "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", + "requires": { + "@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": { + "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-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" + } + }, + "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==" + }, + "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", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", + "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", + "@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.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", + "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": "^2.0.0", + "slash": "^3.0.0", "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "write-file-atomic": "^3.0.0" }, "dependencies": { + "@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" + }, + "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": { + "@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-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/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" + } + }, + "@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" + }, + "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==" + }, + "@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==", - "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": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.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==", + "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=" + } + } + }, + "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" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" } }, + "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==" + }, "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" } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.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": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } } } }, "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, + "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": "^12.0.9" + "@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==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "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" + } + }, + "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==" + }, + "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" + } + } } }, "@mrmlnc/readdir-enhanced": { @@ -1556,6 +3019,19 @@ "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", @@ -1681,11 +3157,106 @@ "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", + "integrity": "sha512-Pkx9LMIGshyNbfmecjt18rrAp/ayMqGH674jYER0SXj0iG9xZc+zWRjk2Pg9JgPBDvwI//xGrI/oOQkAi4YEew==", + "requires": { + "@babel/runtime": "^7.6.2", + "@sheerun/mutationobserver-shim": "^0.3.2", + "@types/testing-library__dom": "^6.0.0", + "aria-query": "3.0.0", + "pretty-format": "^24.9.0", + "wait-for-expect": "^3.0.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.0.2.tgz", + "integrity": "sha512-Pl3si4eH88+5wlVz6NjecLfeO7PjTbbgWKwVZXUtBfrGuJLjGdUUo+O92XRu/59wft8HAmwvXHeMWpqWTg2Uwg==", + "requires": { + "@babel/runtime": "^7.5.1", + "@types/testing-library__jest-dom": "^5.0.0", + "chalk": "^2.4.1", + "css": "^2.2.3", + "css.escape": "^1.5.1", + "jest-diff": "^24.0.0", + "jest-matcher-utils": "^24.0.0", + "lodash": "^4.17.11", + "pretty-format": "^24.0.0", + "redent": "^3.0.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "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" + } + } + } + }, + "@testing-library/react": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-9.4.0.tgz", + "integrity": "sha512-XdhDWkI4GktUPsz0AYyeQ8M9qS/JFie06kcSnUVcpgOwFjAu9vhwR83qBl+lw9yZWkbECjL8Hd+n5hH6C0oWqg==", + "requires": { + "@babel/runtime": "^7.7.6", + "@testing-library/dom": "^6.11.0", + "@types/testing-library__react": "^9.1.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, "@types/babel__core": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz", - "integrity": "sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg==", - "dev": true, + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", + "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -1695,10 +3266,9 @@ } }, "@types/babel__generator": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz", - "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==", - "dev": true, + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "requires": { "@babel/types": "^7.0.0" } @@ -1707,21 +3277,24 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "dev": true, "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "@types/babel__traverse": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", - "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", - "dev": true, + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", + "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", "requires": { "@babel/types": "^7.3.0" } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -1756,14 +3329,12 @@ "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==" }, "@types/istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "requires": { "@types/istanbul-lib-coverage": "*" } @@ -1772,24 +3343,25 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-dXvuABY9nM1xgsXlOtLQXJKdacxZJd7AtvLsKZ/0b57ruMXDKCOXAC/M75GbllQX6o1pcZ5hAG4JzYy7Z/wM2w==", + "requires": { + "jest-diff": "^24.3.0" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, "@types/node": { "version": "10.14.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.7.tgz", @@ -1827,7 +3399,6 @@ "version": "16.8.4", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.8.4.tgz", "integrity": "sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==", - "dev": true, "requires": { "@types/react": "*" } @@ -1843,8 +3414,32 @@ "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "@types/testing-library__dom": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.11.1.tgz", + "integrity": "sha512-ImChHtQqmjwraRLqBC2sgSQFtczeFvBmBcfhTYZn/3KwXbyD07LQykEQ0xJo7QHc1GbVvf7pRyGaIe6PkCdxEw==", + "requires": { + "pretty-format": "^24.3.0" + } + }, + "@types/testing-library__jest-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.0.0.tgz", + "integrity": "sha512-Pm+2mvqs9sND247oMVJbu3QmPUqMzBuJbY5uHHYQdl9MXq5hwWkTbesw1sPIky52Y0sHksWAZnVvGLbdyFSyrA==", + "requires": { + "@types/jest": "*" + } + }, + "@types/testing-library__react": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-9.1.2.tgz", + "integrity": "sha512-CYaMqrswQ+cJACy268jsLAw355DZtPZGt3Jwmmotlcu8O/tkoXBI6AeZ84oZBJsIsesozPKzWzmv/0TIU+1E9Q==", + "requires": { + "@types/react-dom": "*", + "@types/testing-library__dom": "*" + } }, "@types/unist": { "version": "2.0.3", @@ -1885,6 +3480,11 @@ "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==", "dev": true }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" + }, "@typescript-eslint/eslint-plugin": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz", @@ -2117,8 +3717,7 @@ "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", - "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", - "dev": true + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==" }, "accepts": { "version": "1.3.7", @@ -2132,8 +3731,7 @@ "acorn": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", - "dev": true + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -2145,7 +3743,6 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", - "dev": true, "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" @@ -2160,8 +3757,7 @@ "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", - "dev": true + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" }, "address": { "version": "1.0.3", @@ -2187,7 +3783,6 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -2261,14 +3856,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "ansi-wrap": { "version": "0.1.0", @@ -2280,7 +3873,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -2321,7 +3913,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -2330,7 +3921,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, "requires": { "ast-types-flow": "0.0.7", "commander": "^2.11.0" @@ -2339,8 +3929,7 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-filter": { "version": "1.1.2", @@ -2354,8 +3943,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-map": { "version": "2.0.2", @@ -2369,8 +3957,7 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-differ": { "version": "1.0.0", @@ -2387,8 +3974,7 @@ "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" }, "array-filter": { "version": "0.0.1", @@ -2502,8 +4088,7 @@ "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { "version": "0.0.7", @@ -2526,7 +4111,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -2572,26 +4156,22 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async": { "version": "1.5.2", @@ -2634,14 +4214,12 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { "version": "9.5.1", @@ -2713,14 +4291,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "axobject-query": { "version": "2.0.2", @@ -2798,48 +4374,478 @@ } }, "babel-jest": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.8.0.tgz", - "integrity": "sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", + "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", "requires": { - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.6.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.1.0", + "chalk": "^3.0.0", + "slash": "^3.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==", + "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" + }, + "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": { + "@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-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/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" + } + }, + "@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" + }, + "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==" + }, + "@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" + } + }, + "@jest/transform": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", + "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", + "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" + } + }, "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" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.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" + } + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "optional": 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==" + }, + "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==", + "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=" + } + } + }, + "jest-haste-map": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", + "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", + "requires": { + "@jest/types": "^25.1.0", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.3", + "jest-serializer": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-regex-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", + "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==" + }, + "jest-serializer": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", + "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==" + }, + "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-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==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "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" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "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==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, "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" } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.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": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } } } }, @@ -2876,10 +4882,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz", - "integrity": "sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", + "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", "requires": { "@types/babel__traverse": "^7.0.6" } @@ -2924,13 +4929,13 @@ "dev": true }, "babel-preset-jest": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz", - "integrity": "sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", + "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", "requires": { + "@babel/plugin-syntax-bigint": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.6.0" + "babel-plugin-jest-hoist": "^25.1.0" } }, "babel-preset-react-app": { @@ -3049,6 +5054,16 @@ "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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.3.2" + } } } }, @@ -3119,7 +5134,6 @@ "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -3134,7 +5148,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -3143,7 +5156,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3152,7 +5164,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3161,7 +5172,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -3171,8 +5181,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -3202,7 +5211,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -3227,6 +5235,16 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -3324,7 +5342,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -3342,7 +5359,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -3358,14 +5374,12 @@ "browser-process-hrtime": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", - "dev": true + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" }, "browser-resolve": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, "requires": { "resolve": "1.1.7" }, @@ -3373,8 +5387,7 @@ "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" } } }, @@ -3466,11 +5479,18 @@ "node-releases": "^1.1.21" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", - "dev": true, "requires": { "node-int64": "^0.4.0" } @@ -3501,8 +5521,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-indexof": { "version": "1.1.1", @@ -3571,7 +5590,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -3632,8 +5650,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-api": { "version": "3.0.0", @@ -3657,7 +5674,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, "requires": { "rsvp": "^4.8.4" } @@ -3671,8 +5687,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "ccount": { "version": "1.0.4", @@ -3684,7 +5699,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -3792,8 +5806,7 @@ "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "cipher-base": { "version": "1.0.4", @@ -3809,7 +5822,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -3821,7 +5833,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -3925,8 +5936,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "coa": { "version": "2.0.2", @@ -3976,6 +5986,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "collect-v8-coverage": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz", + "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==" + }, "collection-map": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", @@ -4002,7 +6017,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -4022,7 +6036,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -4030,8 +6043,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.3", @@ -4053,7 +6065,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -4067,14 +6078,12 @@ "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" }, "commondir": { "version": "1.0.1", @@ -4095,8 +6104,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "component-inherit": { "version": "0.0.3", @@ -4213,7 +6221,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -4258,8 +6265,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "copy-props": { "version": "2.0.4", @@ -4305,8 +6311,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "5.2.1", @@ -4361,7 +6366,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -4393,7 +6397,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -4632,6 +6635,57 @@ "source-list-map": "^2.0.0" } }, + "css-modules-loader-core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", + "integrity": "sha1-WQhmgpShvs0mGuCkziGwtVHyHRY=", + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.1", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", + "integrity": "sha1-AA29H47vIXqjaLmiEsX8QLKo8/I=", + "requires": { + "chalk": "^1.1.3", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "requires": { + "postcss": "^6.0.1" + } + }, + "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": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, "css-prefers-color-scheme": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", @@ -4716,7 +6770,6 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", - "dev": true, "requires": { "cssesc": "^0.1.0", "fastparse": "^1.1.1", @@ -4759,6 +6812,11 @@ "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", "dev": true }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=" + }, "cssdb": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", @@ -4768,8 +6826,7 @@ "cssesc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", - "dev": true + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" }, "cssnano": { "version": "4.1.10", @@ -5080,7 +7137,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -5089,7 +7145,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dev": true, "requires": { "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", @@ -5100,7 +7155,6 @@ "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", @@ -5148,14 +7202,12 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { "version": "1.0.1", @@ -5166,8 +7218,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "default-compare": { "version": "1.0.0", @@ -5214,7 +7265,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -5224,7 +7274,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -5233,7 +7282,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -5242,7 +7290,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -5252,8 +7299,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -5313,8 +7359,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "denodeify": { "version": "1.2.1", @@ -5409,10 +7454,9 @@ "dev": true }, "diff-sequences": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.3.0.tgz", - "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", - "dev": true + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" }, "diffie-hellman": { "version": "5.0.3", @@ -5504,7 +7548,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "dev": true, "requires": { "webidl-conversions": "^4.0.2" } @@ -5581,7 +7624,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5623,8 +7665,7 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, "encodeurl": { "version": "1.0.2", @@ -5636,7 +7677,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -5770,7 +7810,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -5866,14 +7905,12 @@ "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 + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", - "dev": true, "requires": { "esprima": "^3.1.3", "estraverse": "^4.2.0", @@ -5885,8 +7922,7 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" } } }, @@ -6348,10 +8384,21 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "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", @@ -6373,8 +8420,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", @@ -6397,14 +8443,12 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.8.1", @@ -6476,14 +8520,12 @@ "exec-sh": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz", - "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==", - "dev": true + "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==" }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -6497,14 +8539,12 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -6519,7 +8559,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -6528,7 +8567,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -6537,7 +8575,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -6545,8 +8582,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -6560,26 +8596,225 @@ } }, "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.1.0.tgz", + "integrity": "sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-regex-util": "^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/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-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, "ansi-styles": { - "version": "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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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==" + }, + "diff-sequences": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==" + }, + "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-diff": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "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-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" + } + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "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" } } } @@ -6654,14 +8889,12 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -6671,7 +8904,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -6693,7 +8925,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -6709,7 +8940,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -6718,7 +8948,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -6727,7 +8956,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -6736,7 +8964,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -6745,7 +8972,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -6755,16 +8981,14 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fancy-log": { "version": "1.3.3", @@ -6781,8 +9005,7 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-glob": { "version": "2.2.7", @@ -6801,20 +9024,17 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" }, "faye-websocket": { "version": "0.11.1", @@ -6829,7 +9049,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", - "dev": true, "requires": { "bser": "^2.0.0" } @@ -6877,6 +9096,13 @@ "schema-utils": "^1.0.0" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filesize": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", @@ -6887,7 +9113,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -6899,7 +9124,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -7076,8 +9300,7 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "for-own": { "version": "0.1.5", @@ -7091,8 +9314,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "fork-ts-checker-webpack-plugin": { "version": "1.1.1", @@ -7145,7 +9367,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -7162,7 +9383,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } @@ -7247,7 +9467,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -7268,12 +9489,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7288,17 +9511,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -7415,7 +9641,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -7427,6 +9654,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7441,6 +9669,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7448,12 +9677,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7472,6 +9703,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -7552,7 +9784,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -7564,6 +9797,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7649,7 +9883,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7685,6 +9920,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7704,6 +9940,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7747,12 +9984,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -7767,6 +10006,42 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "generic-names": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", + "integrity": "sha1-LXhqEhruUIh2eWk56OO/+DbCCRc=", + "requires": { + "loader-utils": "^0.2.16" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -7783,7 +10058,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -7791,14 +10065,12 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -7925,8 +10197,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { "version": "8.0.2", @@ -7981,8 +10252,7 @@ "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, "gulp": { "version": "4.0.2", @@ -8347,29 +10617,15 @@ "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", "dev": true }, - "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -8393,7 +10649,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8421,8 +10676,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.0", @@ -8433,7 +10687,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -8444,7 +10697,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -8453,14 +10705,12 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -8598,7 +10848,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, "requires": { "whatwg-encoding": "^1.0.1" } @@ -8609,6 +10858,11 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, + "html-escaper": { + "version": "2.0.0", + "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", @@ -8752,7 +11006,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -8786,11 +11039,15 @@ } } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -8798,8 +11055,7 @@ "icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" }, "icss-utils": { "version": "2.1.0", @@ -8854,7 +11110,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, "requires": { "import-from": "^2.1.0" } @@ -8873,7 +11128,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, "requires": { "resolve-from": "^3.0.0" } @@ -8891,8 +11145,12 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "indexes-of": { "version": "1.0.1", @@ -9055,8 +11313,7 @@ "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" }, "ipaddr.js": { "version": "1.9.0", @@ -9090,7 +11347,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -9103,8 +11359,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", @@ -9130,7 +11385,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, "requires": { "ci-info": "^2.0.0" } @@ -9153,7 +11407,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -9167,7 +11420,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -9177,22 +11429,19 @@ "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 + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "2.1.1", @@ -9209,8 +11458,7 @@ "is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" }, "is-generator-function": { "version": "1.0.7", @@ -9236,7 +11484,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -9281,7 +11528,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -9330,8 +11576,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-svg": { "version": "3.0.0", @@ -9353,8 +11598,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-unc-path": { "version": "1.0.0", @@ -9380,8 +11624,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-wsl": { "version": "1.1.0", @@ -9391,26 +11634,22 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -9442,219 +11681,630 @@ } }, "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "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==" + }, + "make-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", + "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } }, "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", + "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" }, "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, + "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-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", + "integrity": "sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w==", + "requires": { + "@jest/core": "^25.1.0", + "import-local": "^3.0.2", + "jest-cli": "^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/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-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.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" + } + }, + "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" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "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==" + }, + "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" + } + }, + "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==" + }, + "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==" + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "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==" + }, + "jest-cli": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.1.0.tgz", + "integrity": "sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg==", + "requires": { + "@jest/core": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^15.0.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" + } + }, + "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==" + }, + "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==", + "requires": { + "find-up": "^4.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "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" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", + "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^16.1.0" + } + }, + "yargs-parser": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "requires": { - "glob": "^7.1.3" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, - "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", - "dev": true, - "requires": { - "handlebars": "^4.1.2" - } - }, - "jest": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.7.1.tgz", - "integrity": "sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA==", - "dev": true, + "jest-changed-files": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.1.0.tgz", + "integrity": "sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA==", "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.7.1" + "@jest/types": "^25.1.0", + "execa": "^3.2.0", + "throat": "^5.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, + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", "requires": { - "color-convert": "^1.9.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "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, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" } }, - "jest-cli": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.8.0.tgz", - "integrity": "sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA==", - "dev": true, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "requires": { - "@jest/core": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "import-local": "^2.0.0", - "is-ci": "^2.0.0", - "jest-config": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^12.0.2" + "pump": "^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, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "requires": { - "has-flag": "^3.0.0" + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" } } } }, - "jest-changed-files": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.8.0.tgz", - "integrity": "sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "execa": "^1.0.0", - "throat": "^4.0.0" - } - }, "jest-config": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.8.0.tgz", - "integrity": "sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.1.0.tgz", + "integrity": "sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw==", "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.8.0", - "@jest/types": "^24.8.0", - "babel-jest": "^24.8.0", - "chalk": "^2.0.1", + "@jest/test-sequencer": "^25.1.0", + "@jest/types": "^25.1.0", + "babel-jest": "^25.1.0", + "chalk": "^3.0.0", "glob": "^7.1.1", - "jest-environment-jsdom": "^24.8.0", - "jest-environment-node": "^24.8.0", - "jest-get-type": "^24.8.0", - "jest-jasmine2": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.8.0", + "jest-environment-jsdom": "^25.1.0", + "jest-environment-node": "^25.1.0", + "jest-get-type": "^25.1.0", + "jest-jasmine2": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.1.0", "realpath-native": "^1.1.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-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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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" } }, "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, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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" } }, + "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-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", + "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^25.1.0", "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", + "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" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, "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, + "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": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" } } } }, "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", - "dev": true, + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", "requires": { "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.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" } @@ -9663,7 +12313,6 @@ "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", @@ -9674,7 +12323,6 @@ "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" } @@ -9682,72 +12330,306 @@ } }, "jest-docblock": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", - "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.1.0.tgz", + "integrity": "sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA==", "requires": { - "detect-newline": "^2.1.0" + "detect-newline": "^3.0.0" + }, + "dependencies": { + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + } } }, "jest-each": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz", - "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0" + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", + "integrity": "sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A==", + "requires": { + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.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-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, + "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" + } + }, + "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==" + }, + "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-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "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" + } + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "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-environment-jsdom": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz", + "integrity": "sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ==", + "requires": { + "@jest/environment": "^25.1.0", + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^25.1.0", + "jsdom": "^15.1.1" + }, + "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": { - "color-convert": "^1.9.0" + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1" } }, - "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, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "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": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "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": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" } } } }, - "jest-environment-jsdom": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz", - "integrity": "sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==", - "dev": true, - "requires": { - "@jest/environment": "^24.8.0", - "@jest/fake-timers": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-util": "^24.8.0", - "jsdom": "^11.5.1" - } - }, "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", @@ -9826,125 +12708,647 @@ } }, "jest-environment-node": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.8.0.tgz", - "integrity": "sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q==", - "dev": true, - "requires": { - "@jest/environment": "^24.8.0", - "@jest/fake-timers": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-util": "^24.8.0" + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.1.0.tgz", + "integrity": "sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw==", + "requires": { + "@jest/environment": "^25.1.0", + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^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" + } + } } }, "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" }, "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", + "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", + "@jest/types": "^25.1.0", + "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.3", + "jest-serializer": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" + }, + "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" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "optional": 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==" + }, + "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-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" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "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-jasmine2": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz", - "integrity": "sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz", + "integrity": "sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg==", "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", + "@jest/environment": "^25.1.0", + "@jest/source-map": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^24.8.0", + "expect": "^25.1.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0", - "throat": "^4.0.0" + "jest-each": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0", + "throat": "^5.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-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, "ansi-styles": { - "version": "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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "diff-sequences": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==" + }, + "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-diff": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "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-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" } }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, "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, + "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": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" } } } }, "jest-leak-detector": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz", - "integrity": "sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz", + "integrity": "sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w==", "requires": { - "pretty-format": "^24.8.0" + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.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-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" + } + }, + "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==" + }, + "jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + } } }, "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", - "dev": true, + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", "requires": { "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.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" } @@ -9953,7 +13357,6 @@ "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", @@ -9964,7 +13367,6 @@ "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" } @@ -9987,6 +13389,26 @@ "stack-utils": "^1.0.1" }, "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": "*" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10025,19 +13447,39 @@ "dev": true, "requires": { "@jest/types": "^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-pnp-resolver": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", - "dev": true + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" }, "jest-regex-util": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.3.0.tgz", - "integrity": "sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==", - "dev": true + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", + "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==" }, "jest-resolve": { "version": "24.7.1", @@ -10052,6 +13494,26 @@ "realpath-native": "^1.1.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": "*" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10084,228 +13546,823 @@ } }, "jest-resolve-dependencies": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz", - "integrity": "sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz", + "integrity": "sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw==", "requires": { - "@jest/types": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.8.0" + "@jest/types": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-snapshot": "^25.1.0" } }, "jest-runner": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.8.0.tgz", - "integrity": "sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "chalk": "^2.4.2", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.1.0.tgz", + "integrity": "sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w==", + "requires": { + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.8.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.8.0", - "jest-jasmine2": "^24.8.0", - "jest-leak-detector": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", + "graceful-fs": "^4.2.3", + "jest-config": "^25.1.0", + "jest-docblock": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-jasmine2": "^25.1.0", + "jest-leak-detector": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", "source-map-support": "^0.5.6", - "throat": "^4.0.0" + "throat": "^5.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-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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", + "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^25.1.0", "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", + "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" + } + }, + "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" + } + } + } + }, + "jest-runtime": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.1.0.tgz", + "integrity": "sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA==", + "requires": { + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/source-map": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.3", + "jest-config": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "realpath-native": "^1.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.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" + } + }, + "@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": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.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" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "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==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "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==" + }, + "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-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "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-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" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "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==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "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": "^3.0.0" + "has-flag": "^4.0.0" } - } - } - }, - "jest-runtime": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz", - "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/yargs": "^12.0.2", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^12.0.2" - }, - "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, + }, + "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": { - "color-convert": "^1.9.0" + "is-number": "^7.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, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, + "yargs": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", + "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^16.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, + "yargs-parser": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "requires": { - "has-flag": "^3.0.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, "jest-serializer": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.4.0.tgz", - "integrity": "sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q==", - "dev": true + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", + "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==" }, "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz", + "integrity": "sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A==", "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "expect": "^25.1.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-resolve": "^25.1.0", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" + "pretty-format": "^25.1.0", + "semver": "^7.1.1" }, "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-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, "ansi-styles": { - "version": "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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@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": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "diff-sequences": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==" + }, + "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-diff": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "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": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", + "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^25.1.0", "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", + "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" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "semver": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.1.tgz", + "integrity": "sha512-WfuG+fl6eh3eZ2qAf6goB7nhiCd7NPXhmyFxigB/TOkQyeLP8w8GsVehvtGNtnNmyboz4TgeK40B1Kbql/8c5A==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, "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, + "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": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "jest-transform-css": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jest-transform-css/-/jest-transform-css-2.0.0.tgz", + "integrity": "sha512-KV5pD27qUltAVj0mZEVvqd+Ahe+WNPOVWKA1BRpIhBJ5OeUUOM46ivAznJrC5B1JrVNbMzWjPxnKl6QTsAAT3Q==", + "requires": { + "common-tags": "1.8.0", + "cosmiconfig": "5.0.6", + "cross-spawn": "6.0.5", + "postcss-load-config": "2.0.0", + "postcss-modules": "1.3.2", + "style-inject": "0.3.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz", + "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" } } } @@ -10330,6 +14387,26 @@ "source-map": "^0.6.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": "*" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10368,46 +14445,86 @@ } }, "jest-validate": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.8.0.tgz", - "integrity": "sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.1.0.tgz", + "integrity": "sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA==", "requires": { - "@jest/types": "^24.8.0", - "camelcase": "^5.0.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.8.0", - "leven": "^2.1.0", - "pretty-format": "^24.8.0" + "@jest/types": "^25.1.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.1.0", + "leven": "^3.1.0", + "pretty-format": "^25.1.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-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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, "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, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" + }, + "pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "requires": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, "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, + "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": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -10487,6 +14604,28 @@ "string-length": "^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": { + "@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-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10519,22 +14658,25 @@ } }, "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, + "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": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -10554,7 +14696,6 @@ "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -10563,80 +14704,102 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "dev": true, + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", "requires": { "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", "domexception": "^1.0.1", - "escodegen": "^1.9.1", + "escodegen": "^1.11.1", "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", + "tough-cookie": "^3.0.1", "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.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 + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==" + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", + "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } } } }, "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify": { "version": "1.0.1", @@ -10656,8 +14819,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json3": { "version": "3.3.3", @@ -10693,7 +14855,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -10726,7 +14887,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" }, @@ -10734,16 +14894,14 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" } } }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" }, "last-call-webpack-plugin": { "version": "3.0.0", @@ -10833,16 +14991,14 @@ } }, "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -10980,8 +15136,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -10989,17 +15144,20 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, "lodash.tail": { "version": "4.1.1", @@ -11008,12 +15166,12 @@ "dev": true }, "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0", + "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, @@ -11084,6 +15242,14 @@ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", "dev": true }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -11134,6 +15300,11 @@ } } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -11155,7 +15326,6 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, "requires": { "tmpl": "1.0.x" } @@ -11178,8 +15348,7 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-stream": { "version": "0.0.7", @@ -11191,7 +15360,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "^1.0.0" } @@ -11319,13 +15487,9 @@ "dev": true }, "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { "version": "1.2.3", @@ -11349,7 +15513,6 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -11369,8 +15532,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -11409,6 +15571,11 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "min-indent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", + "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", @@ -11443,8 +15610,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mississippi": { "version": "3.0.0", @@ -11468,7 +15634,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -11478,7 +15643,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -11507,7 +15671,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -11515,8 +15678,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -11733,7 +15895,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -11751,16 +15912,14 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "negotiator": { "version": "0.6.2", @@ -11782,8 +15941,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "no-case": { "version": "2.3.2", @@ -11813,8 +15971,7 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node-libs-browser": { "version": "2.2.0", @@ -11867,20 +16024,33 @@ "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" }, "node-notifier": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", - "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", "shellwords": "^0.1.1", - "which": "^1.3.0" + "which": "^1.3.1" + }, + "dependencies": { + "is-wsl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "optional": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true + } } }, "node-releases": { @@ -11908,7 +16078,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -11986,7 +16155,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -12021,8 +16189,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", @@ -12038,7 +16205,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -12049,7 +16215,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -12071,7 +16236,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" } @@ -12138,7 +16302,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.1" @@ -12169,7 +16332,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -12259,30 +16421,6 @@ "is-wsl": "^1.1.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, "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", @@ -12297,7 +16435,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -12376,19 +16513,14 @@ "dev": true }, "p-each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "dev": true, - "requires": { - "p-reduce": "^1.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "2.1.0", @@ -12400,7 +16532,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -12429,8 +16560,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pako": { "version": "1.0.10", @@ -12504,7 +16634,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -12534,8 +16663,7 @@ "parse5": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "dev": true + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" }, "parseqs": { "version": "0.0.5", @@ -12562,8 +16690,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { "version": "0.0.0", @@ -12597,14 +16724,12 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-root": { "version": "0.1.1", @@ -12667,8 +16792,12 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" }, "pidtree": { "version": "0.3.0", @@ -12701,7 +16830,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, "requires": { "node-modules-regexp": "^1.0.0" } @@ -12824,8 +16952,7 @@ "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, "pnp-webpack-plugin": { "version": "1.2.1", @@ -12867,14 +16994,12 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { "version": "6.0.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, "requires": { "chalk": "^2.4.1", "source-map": "^0.6.1", @@ -12885,7 +17010,6 @@ "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" } @@ -12894,7 +17018,6 @@ "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", @@ -12905,7 +17028,6 @@ "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" } @@ -14745,7 +18867,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", - "dev": true, "requires": { "cosmiconfig": "^4.0.0", "import-cwd": "^2.0.0" @@ -14755,7 +18876,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", - "dev": true, "requires": { "is-directory": "^0.3.1", "js-yaml": "^3.9.0", @@ -15368,6 +19488,66 @@ } } }, + "postcss-modules": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-1.3.2.tgz", + "integrity": "sha512-QujH5ZpPtr1fBWTKDa43Hx45gm7p19aEtHaAtkMCBZZiB/D5za2wXSMtAf94tDUZHF3F5KZcTXISUNqgEQRiDw==", + "requires": { + "css-modules-loader-core": "^1.1.0", + "generic-names": "^1.0.3", + "lodash.camelcase": "^4.3.0", + "postcss": "^7.0.1", + "string-hash": "^1.1.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==", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "postcss": { + "version": "7.0.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", + "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", + "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==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "postcss-modules-extract-imports": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", @@ -15381,7 +19561,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", - "dev": true, "requires": { "css-selector-tokenizer": "^0.7.0", "postcss": "^6.0.1" @@ -15391,7 +19570,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", - "dev": true, "requires": { "css-selector-tokenizer": "^0.7.0", "postcss": "^6.0.1" @@ -15401,7 +19579,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", - "dev": true, "requires": { "icss-replace-symbols": "^1.1.0", "postcss": "^6.0.1" @@ -17087,7 +21264,12 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "pretty-bytes": { @@ -17107,28 +21289,43 @@ } }, "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "ansi-regex": "^4.0.0", "ansi-styles": "^3.2.0", "react-is": "^16.8.4" }, "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==", + "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==", + "requires": { + "@types/yargs-parser": "*" + } + }, "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 + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "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" } @@ -17182,13 +21379,12 @@ "dev": true }, "prompts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", - "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", - "dev": true, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", + "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", "requires": { - "kleur": "^3.0.2", - "sisteransi": "^1.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" } }, "prop-types": { @@ -17235,8 +21431,7 @@ "psl": { "version": "1.1.32", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", - "dev": true + "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" }, "public-encrypt": { "version": "4.0.3", @@ -17256,7 +21451,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -17288,8 +21482,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", @@ -17300,8 +21493,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "querystring": { "version": "0.2.0", @@ -17631,6 +21823,219 @@ "workbox-webpack-plugin": "4.2.0" }, "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==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/core": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "slash": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "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": { + "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/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", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "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/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", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "@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" + } + }, + "@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-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": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -17640,6 +22045,46 @@ "color-convert": "^1.9.0" } }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "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", @@ -17662,6 +22107,17 @@ } } }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, "css-loader": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", @@ -17681,6 +22137,20 @@ "schema-utils": "^1.0.0" } }, + "expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + } + }, "fsevents": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.6.tgz", @@ -17688,6 +22158,12 @@ "dev": true, "optional": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "icss-utils": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.0.tgz", @@ -17697,12 +22173,1113 @@ "postcss": "^7.0.14" } }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "jest": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.7.1.tgz", + "integrity": "sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA==", + "dev": true, + "requires": { + "import-local": "^2.0.0", + "jest-cli": "^24.7.1" + }, + "dependencies": { + "jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "dev": true, + "requires": { + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" + } + } + } + }, + "jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + }, + "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": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "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" + }, + "dependencies": { + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + } + } + }, + "jest-jasmine2": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "throat": "^4.0.0" + } + }, + "jest-leak-detector": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "dev": true, + "requires": { + "jest-get-type": "^24.9.0", + "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", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true + }, + "jest-resolve-dependencies": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.9.0" + } + }, + "jest-runner": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "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": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^13.3.0" + }, + "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": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true + }, + "jest-snapshot": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "mkdirp": "^0.5.1", + "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": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "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", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + } + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + }, + "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==", + "dev": true + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "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 }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "postcss": { "version": "7.0.16", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", @@ -17760,7 +23337,16 @@ "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "path-parse": "^1.0.6" + } + }, + "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" } }, "semver": { @@ -17769,6 +23355,26 @@ "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", "dev": true }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, "style-loader": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", @@ -17788,6 +23394,12 @@ "has-flag": "^3.0.0" } }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, "webpack": { "version": "4.29.6", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.6.tgz", @@ -17819,6 +23431,65 @@ "watchpack": "^1.5.0", "webpack-sources": "^1.3.0" } + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "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" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yargs": { + "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": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + } + }, + "yargs-parser": { + "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": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -17882,7 +23553,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "dev": true, "requires": { "util.promisify": "^1.0.0" } @@ -17905,11 +23575,19 @@ "minimatch": "3.0.4" } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { "version": "8.1.0", @@ -17923,8 +23601,7 @@ "regenerator-runtime": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", - "dev": true + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" }, "regenerator-transform": { "version": "0.14.0", @@ -17939,7 +23616,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -17961,7 +23637,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", - "dev": true, "requires": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", @@ -17971,14 +23646,12 @@ "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" }, "regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, "requires": { "jsesc": "~0.5.0" } @@ -18032,8 +23705,7 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "renderkid": { "version": "2.0.3", @@ -18075,14 +23747,12 @@ "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "replace-ext": { "version": "1.0.0", @@ -18105,7 +23775,6 @@ "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -18133,7 +23802,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", - "dev": true, "requires": { "lodash": "^4.17.11" } @@ -18142,7 +23810,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", - "dev": true, "requires": { "request-promise-core": "1.1.2", "stealthy-require": "^1.1.1", @@ -18152,20 +23819,17 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "requireindex": { "version": "1.2.0", @@ -18183,7 +23847,6 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -18236,8 +23899,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" }, "resolve-options": { "version": "1.1.0", @@ -18251,8 +23913,7 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "restore-cursor": { "version": "2.0.0", @@ -18267,8 +23928,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "rgb-regex": { "version": "1.0.1", @@ -18282,6 +23942,14 @@ "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "dev": true }, + "rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -18295,8 +23963,7 @@ "rsvp": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", - "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==", - "dev": true + "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==" }, "run-async": { "version": "2.3.0", @@ -18334,7 +24001,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -18342,14 +24008,12 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sane": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, "requires": { "@cnakazawa/watch": "^1.0.3", "anymatch": "^2.0.0", @@ -18434,7 +24098,6 @@ "version": "3.1.9", "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz", "integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==", - "dev": true, "requires": { "xmlchars": "^1.3.1" } @@ -18599,14 +24262,12 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -18618,7 +24279,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -18691,7 +24351,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -18699,8 +24358,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shell-quote": { "version": "1.6.1", @@ -18728,14 +24386,12 @@ "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-swizzle": { "version": "0.2.2", @@ -18755,10 +24411,9 @@ } }, "sisteransi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", + "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==" }, "slash": { "version": "2.0.0", @@ -18792,7 +24447,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -18808,7 +24462,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -18817,7 +24470,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -18826,7 +24478,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -18834,14 +24485,12 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -18849,7 +24498,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -18860,7 +24508,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -18869,7 +24516,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -18878,7 +24524,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -18887,7 +24532,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -18897,8 +24541,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -18906,7 +24549,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" } @@ -19060,14 +24702,12 @@ "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 + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -19080,7 +24720,6 @@ "version": "0.5.12", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -19089,8 +24728,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "space-separated-tokens": { "version": "1.1.4", @@ -19189,7 +24827,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -19197,14 +24834,12 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -19241,14 +24876,12 @@ "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -19258,7 +24891,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -19274,8 +24906,7 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "stream-browserify": { "version": "2.0.2", @@ -19341,6 +24972,11 @@ "readable-stream": "^2.0.2" } }, + "string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=" + }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", @@ -19430,7 +25066,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -19460,8 +25095,20 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } }, "strip-json-comments": { "version": "2.0.1", @@ -19469,6 +25116,11 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "style-inject": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz", + "integrity": "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==" + }, "style-loader": { "version": "0.21.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", @@ -19569,8 +25221,31 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "supports-hyperlinks": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.0.0.tgz", + "integrity": "sha512-bFhn0MQ8qefLyJ3K7PpHiPUTuTVPWw6RXfaMeV6xgJLXtBbszyboz1bvGTVv4R0YpQm2DqlXXn0fFHhxUHVE5w==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "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" + } + } + } }, "sver-compat": { "version": "1.5.0", @@ -19646,8 +25321,7 @@ "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, "table": { "version": "5.4.0", @@ -19695,6 +25369,25 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, "terser": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", @@ -19741,10 +25434,9 @@ "dev": true }, "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, "through": { "version": "2.3.8", @@ -19821,8 +25513,7 @@ "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" }, "to-absolute-glob": { "version": "2.0.2", @@ -19848,14 +25539,12 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" } @@ -19864,7 +25553,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -19876,7 +25564,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -19901,7 +25588,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -19910,8 +25596,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" } } }, @@ -19919,7 +25604,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -19927,8 +25611,7 @@ "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, "trough": { "version": "1.0.4", @@ -19945,6 +25628,46 @@ "tslib": "^1.9.2" } }, + "ts-jest": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.0.0.tgz", + "integrity": "sha512-F+hZg3j7XYOFpXJteXb4lnqy7vQzTmpTmX7AJT6pvSGeZejyXj1Lk0ArpnrEPOpv6Zu/NugHc5W7FINngC9WZQ==", + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "10.x" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "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==", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "ts-loader": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.5.0.tgz", @@ -20139,7 +25862,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -20147,8 +25869,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type": { "version": "1.0.1", @@ -20160,11 +25881,20 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -20191,6 +25921,14 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", @@ -20335,7 +26073,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -20411,7 +26148,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -20421,7 +26157,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -20432,7 +26167,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -20442,8 +26176,7 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" } } }, @@ -20463,7 +26196,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -20471,8 +26203,7 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", @@ -20530,8 +26261,7 @@ "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { "version": "0.12.1", @@ -20555,7 +26285,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" @@ -20576,8 +26305,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { "version": "2.0.3", @@ -20585,6 +26313,23 @@ "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", "dev": true }, + "v8-to-istanbul": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.0.1.tgz", + "integrity": "sha512-x0yZvZAkjJwdD3fPiJzYP37aod0ati4LlmD2RmpKjqewjKAov/u/ytZ8ViIZb07cN4cePKzl9ijiUi7C1LQ8hQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, "v8flags": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", @@ -20626,7 +26371,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -21102,7 +26846,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "dev": true, "requires": { "browser-process-hrtime": "^0.1.2" } @@ -21111,18 +26854,21 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "dev": true, "requires": { "domexception": "^1.0.1", "webidl-conversions": "^4.0.2", "xml-name-validator": "^3.0.0" } }, + "wait-for-expect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.1.tgz", + "integrity": "sha512-3Ha7lu+zshEG/CeHdcpmQsZnnZpPj/UsG3DuKO8FskjuDbkx3jE3845H+CuwZjA2YWYDfKMU2KhnCaXMLd3wVw==" + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, "requires": { "makeerror": "1.0.x" } @@ -21156,8 +26902,7 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" }, "webpack": { "version": "4.32.2", @@ -21520,7 +27265,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, "requires": { "iconv-lite": "0.4.24" } @@ -21534,14 +27278,12 @@ "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "dev": true, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -21552,7 +27294,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -21560,8 +27301,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "wide-align": { "version": "1.1.3", @@ -21575,8 +27315,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "workbox-background-sync": { "version": "4.3.1", @@ -21832,13 +27571,9 @@ } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" }, "x-is-string": { "version": "0.1.0", @@ -21849,8 +27584,7 @@ "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==", - "dev": true + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xml2js": { "version": "0.4.19", @@ -21871,8 +27605,7 @@ "xmlchars": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", - "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==", - "dev": true + "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==" }, "xmlhttprequest-ssl": { "version": "1.5.5", @@ -21894,8 +27627,7 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "3.0.3", diff --git a/package.json b/package.json index b08e76cf1..730019a8e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,19 @@ ], "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", @@ -161,13 +174,12 @@ "default": true, "scope": "resource" }, - "pacifica.showNewFilePopup": { + "deviceSimulatorExpress.showNewFilePopup": { "type": "boolean", "default": true, "scope": "resource" }, "deviceSimulatorExpress.debuggerServerPort": { - "type": "number", "default": 5577, "description": "%deviceSimulatorExpressExtension.configuration.properties.debuggerPort%", @@ -266,15 +278,21 @@ "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": "tslint -c tslint.json src/**/*.{ts,tsx}", - "format": "prettier --write src/**/*.{ts,tsx}", - "tslint-check": "tslint-config-prettier-check ./tslint.json", + "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/mocha": "^5.2.6", "@types/node": "^10.12.21", "@types/react": "16.8.18", "@types/react-dom": "16.8.4", @@ -291,6 +309,7 @@ "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", @@ -310,18 +329,26 @@ "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", - "open": "^6.4.0", "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" diff --git a/src/adafruit_circuitplayground/__init__.py b/src/adafruit_circuitplayground/__init__.py index e69de29bb..b4bc33da8 100644 --- a/src/adafruit_circuitplayground/__init__.py +++ b/src/adafruit_circuitplayground/__init__.py @@ -0,0 +1,4 @@ +# added compatibility for new import structure in CircuitPython +# https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/pull/79 + +from .express import cpx as cp diff --git a/src/adafruit_circuitplayground/constants.py b/src/adafruit_circuitplayground/constants.py index 4474dc46b..26642a710 100644 --- a/src/adafruit_circuitplayground/constants.py +++ b/src/adafruit_circuitplayground/constants.py @@ -1,32 +1,40 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. -ASSIGN_PIXEL_TYPE_ERROR = "The pixel color value type should be tuple, list or hexadecimal." +ASSIGN_PIXEL_TYPE_ERROR = ( + "The pixel color value type should be tuple, list or hexadecimal." +) BRIGHTNESS_RANGE_ERROR = "The brightness value should be a number between 0 and 1." -INDEX_ERROR = "The index is not a valid number, you can access the Neopixels from 0 to 9." +INDEX_ERROR = ( + "The index is not a valid number, you can access the Neopixels from 0 to 9." +) MAC_OS = "darwin" NOT_IMPLEMENTED_ERROR = "This method is not implemented by the simulator" -NOT_SUITABLE_FILE_ERROR = "Your .wav file is not suitable for the Circuit Playground Express." +NOT_SUITABLE_FILE_ERROR = ( + "Your .wav file is not suitable for the Circuit Playground Express." +) -PIXEL_RANGE_ERROR = "The pixel hexadicimal color value should be in range #000000 and #FFFFFF." +PIXEL_RANGE_ERROR = ( + "The pixel hexadicimal color value should be in range #000000 and #FFFFFF." +) 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" + "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 : " @@ -35,6 +43,5 @@ DEFAULT_PORT = "5577" -EVENTS_BUTTON_PRESS = ['button_a', 'button_b', 'switch'] -EVENTS_SENSOR_CHANGED = ['temperature', - 'light', 'motion_x', 'motion_y', 'motion_z'] +EVENTS_BUTTON_PRESS = ["button_a", "button_b", "switch"] +EVENTS_SENSOR_CHANGED = ["temperature", "light", "motion_x", "motion_y", "motion_z"] diff --git a/src/adafruit_circuitplayground/debugger_communication_client.py b/src/adafruit_circuitplayground/debugger_communication_client.py index b2867c53d..0536550ea 100644 --- a/src/adafruit_circuitplayground/debugger_communication_client.py +++ b/src/adafruit_circuitplayground/debugger_communication_client.py @@ -16,7 +16,7 @@ # Initialize connection def init_connection(port=CONSTANTS.DEFAULT_PORT): - sio.connect('http://localhost:{}'.format(port)) + sio.connect("http://localhost:{}".format(port)) # Transfer the user's inputs to the API @@ -25,27 +25,27 @@ def __update_api_state(data, expected_events): event_state = json.loads(data) for event in expected_events: express.cpx._Express__state[event] = event_state.get( - event, express.cpx._Express__state[event]) + event, express.cpx._Express__state[event] + ) except Exception as e: - print(CONSTANTS.ERROR_SENDING_EVENT, - e, file=sys.stderr, flush=True) + print(CONSTANTS.ERROR_SENDING_EVENT, e, file=sys.stderr, flush=True) # Method : Update State def update_state(state): - sio.emit('updateState', state) + sio.emit("updateState", state) ## Events Handlers ## # Event : Button pressed (A, B, A+B, Switch) -@sio.on('button_press') +@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 button_press(data): +@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 9ceff5131..f08e1b65c 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -4,7 +4,7 @@ import json import sys import os -from playsound import playsound +import playsound from .pixel import Pixel from . import utils from . import constants as CONSTANTS @@ -12,17 +12,18 @@ from applicationinsights import TelemetryClient from .telemetry import telemetry_py -Acceleration = namedtuple('acceleration', ['x', 'y', 'z']) +Acceleration = namedtuple("acceleration", ["x", "y", "z"]) class Express: def __init__(self): # State in the Python process self.__state = { - 'brightness': 1.0, - 'button_a': False, - 'button_b': False, - 'pixels': [ + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [ + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), @@ -32,44 +33,46 @@ def __init__(self): (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, + "red_led": False, + "switch": False, + "temperature": 0, + "light": 0, + "motion_x": 0, + "motion_y": 0, + "motion_z": 0, + "touch": [False] * 7, + "shake": False, } self.__debug_mode = False - self.__abs_path_to_code_file = '' + self.__abs_path_to_code_file = "" self.pixels = Pixel(self.__state, self.__debug_mode) @property def acceleration(self): - return Acceleration(self.__state['motion_x'], self.__state['motion_y'], self.__state['motion_z']) + return Acceleration( + self.__state["motion_x"], self.__state["motion_y"], self.__state["motion_z"] + ) @property def button_a(self): - return self.__state['button_a'] + return self.__state["button_a"] @property def button_b(self): - return self.__state['button_b'] + return self.__state["button_b"] @property def detect_taps(self): telemetry_py.send_telemetry("DETECT_TAPS") - return self.__state['detect_taps'] + return self.__state["detect_taps"] @detect_taps.setter def detect_taps(self, value): value_int = int(value) - self.__state['detect_taps'] = value_int if ( - value_int == 1 or value_int == 2) else 1 + self.__state["detect_taps"] = ( + value_int if (value_int == 1 or value_int == 2) else 1 + ) @property def tapped(self): @@ -81,31 +84,31 @@ def tapped(self): @property def red_led(self): telemetry_py.send_telemetry("RED_LED") - return self.__state['red_led'] + return self.__state["red_led"] @red_led.setter def red_led(self, value): telemetry_py.send_telemetry("RED_LED") - self.__state['red_led'] = bool(value) + self.__state["red_led"] = bool(value) self.__show() @property def switch(self): - return self.__state['switch'] + return self.__state["switch"] @property def temperature(self): - return self.__state['temperature'] + return self.__state["temperature"] @property def light(self): - return self.__state['light'] + return self.__state["light"] def __show(self): utils.show(self.__state, self.__debug_mode) def __touch(self, i): - return self.__state['touch'][i-1] + return self.__state["touch"][i - 1] @property def touch_A1(self): @@ -137,28 +140,29 @@ def touch_A7(self): def adjust_touch_threshold(self, adjustement): """Not implemented! - The Pacifica Simulator doesn't use capacitive touch threshold. + The CPX Simulator doesn't use capacitive touch threshold. """ telemetry_py.send_telemetry("ADJUST_THRESHOLD") - raise NotImplementedError( - CONSTANTS.NOT_IMPLEMENTED_ERROR) + raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def shake(self, shake_threshold=30): - return self.__state['shake'] + return self.__state["shake"] def play_file(self, file_name): telemetry_py.send_telemetry("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)) + os.path.join(self.__abs_path_to_code_file, os.pardir) + ) abs_path_wav_file = os.path.normpath( - os.path.join(abs_path_parent_dir, file_name)) + os.path.join(abs_path_parent_dir, file_name) + ) abs_path_wav_file = utils.escape_if_OSX(abs_path_wav_file) if sys.implementation.version[0] >= 3: if file_name.endswith(".wav"): try: - playsound(abs_path_wav_file) + playsound.playsound(abs_path_wav_file) except: # TODO TASK: 29054 Verfication of a "valid" .wav file raise EnvironmentError(CONSTANTS.NOT_SUITABLE_FILE_ERROR) @@ -171,22 +175,19 @@ def play_tone(self, frequency, duration): """ Not Implemented! """ telemetry_py.send_telemetry("PLAY_TONE") - raise NotImplementedError( - CONSTANTS.NOT_IMPLEMENTED_ERROR) + raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def start_tone(self, frequency): """ Not Implemented! """ telemetry_py.send_telemetry("START_TONE") - raise NotImplementedError( - CONSTANTS.NOT_IMPLEMENTED_ERROR) + raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def stop_tone(self): """ Not Implemented! """ telemetry_py.send_telemetry("STOP_TONE") - raise NotImplementedError( - CONSTANTS.NOT_IMPLEMENTED_ERROR) + raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) cpx = Express() diff --git a/src/adafruit_circuitplayground/pixel.py b/src/adafruit_circuitplayground/pixel.py index 530dbd48b..3833de2f7 100644 --- a/src/adafruit_circuitplayground/pixel.py +++ b/src/adafruit_circuitplayground/pixel.py @@ -33,7 +33,7 @@ def __getitem__(self, index): if not self.__valid_index(index): raise IndexError(CONSTANTS.INDEX_ERROR) telemetry_py.send_telemetry("PIXELS") - return self.__state['pixels'][index] + return self.__state["pixels"][index] def __setitem__(self, index, val): telemetry_py.send_telemetry("PIXELS") @@ -43,8 +43,7 @@ def __setitem__(self, index, val): else: if not self.__valid_index(index): raise IndexError(CONSTANTS.INDEX_ERROR) - self.__state['pixels'][index] = self.__extract_pixel_value( - val, is_slice) + self.__state["pixels"][index] = self.__extract_pixel_value(val, is_slice) self.__show_if_auto_write() def __iter__(self): @@ -60,11 +59,15 @@ def __len__(self): return len(self.__state["pixels"]) def __valid_index(self, index): - return type(index) is int and index >= -len(self.__state['pixels']) and index < len(self.__state['pixels']) + return ( + type(index) is int + and index >= -len(self.__state["pixels"]) + and index < len(self.__state["pixels"]) + ) def fill(self, val): - for index in range(len(self.__state['pixels'])): - self.__state['pixels'][index] = self.__extract_pixel_value(val) + for index in range(len(self.__state["pixels"])): + self.__state["pixels"][index] = self.__extract_pixel_value(val) self.__show_if_auto_write() def __extract_pixel_value(self, val, is_slice=False): @@ -83,13 +86,15 @@ def __extract_pixel_value(self, val, is_slice=False): else: raise ValueError(CONSTANTS.ASSIGN_PIXEL_TYPE_ERROR) # Values validation - if len(rgb_value) != 3 or any(not self.__valid_rgb_value(pix) for pix in rgb_value): + if len(rgb_value) != 3 or any( + not self.__valid_rgb_value(pix) for pix in rgb_value + ): raise ValueError(CONSTANTS.VALID_PIXEL_ASSIGN_ERROR) extracted_values.append(rgb_value) return rgb_value if not is_slice else extracted_values def __hex_to_rgb(self, hexValue): - if hexValue[0:2] == '0x' and len(hexValue) <= 8: + if hexValue[0:2] == "0x" and len(hexValue) <= 8: hexToRgbValue = [0, 0, 0] hexColor = hexValue[2:].zfill(6) hexToRgbValue[0] = int(hexColor[0:2], 16) # R @@ -104,14 +109,16 @@ def __valid_rgb_value(self, pixValue): @property def brightness(self): - return self.__state['brightness'] + return self.__state["brightness"] @brightness.setter def brightness(self, brightness): if not self.__valid_brightness(brightness): raise ValueError(CONSTANTS.BRIGHTNESS_RANGE_ERROR) - self.__state['brightness'] = brightness + self.__state["brightness"] = brightness self.__show_if_auto_write() def __valid_brightness(self, brightness): - return (type(brightness) is float or type(brightness) is int) and (brightness >= 0 and brightness <= 1) + return (type(brightness) is float or type(brightness) is int) and ( + brightness >= 0 and brightness <= 1 + ) diff --git a/src/adafruit_circuitplayground/telemetry.py b/src/adafruit_circuitplayground/telemetry.py index 98156469c..9fd1edb1c 100644 --- a/src/adafruit_circuitplayground/telemetry.py +++ b/src/adafruit_circuitplayground/telemetry.py @@ -15,20 +15,27 @@ def __init__(self): "PLAY_TONE": False, "START_TONE": False, "STOP_TONE": False, - "PIXELS": False + "PIXELS": False, } - self.telemetry_client = TelemetryClient('__AIKEY__') - self.extension_name = '__EXTENSIONNAME__' + 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]: + 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])) + "{}/{}".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__' + 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 new file mode 100644 index 000000000..b25e27eb8 --- /dev/null +++ b/src/adafruit_circuitplayground/test/test_debugger_communication_client.py @@ -0,0 +1,63 @@ +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_express.py b/src/adafruit_circuitplayground/test/test_express.py index a360aa4fb..b83ba3a23 100644 --- a/src/adafruit_circuitplayground/test/test_express.py +++ b/src/adafruit_circuitplayground/test/test_express.py @@ -1,123 +1,115 @@ import pytest +from unittest import mock +import playsound from ..express import Express from ..pixel import Pixel class TestExpress(object): - def setup_method(self): self.cpx = Express() self.__state = { - 'brightness': 1.0, - 'button_a': False, - 'button_b': False, - 'pixels': [(255, 0, 0)] * 10, - 'red_led': False, - 'switch': False + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [(255, 0, 0)] * 10, + "red_led": False, + "switch": False, } self.pixels = Pixel(self.__state) self.__speaker_enabled = False + def test_acceleration(self): + mock_motion_x = 10 + mock_motion_y = -10 + mock_motion_z = -20 + self.cpx._Express__state["motion_x"] = mock_motion_x + self.cpx._Express__state["motion_y"] = mock_motion_y + self.cpx._Express__state["motion_z"] = mock_motion_z + accel = self.cpx.acceleration + assert accel[0] == 10 + assert accel[1] == -10 + assert accel[2] == -20 + def test_button_a(self): - self.cpx._Express__state['button_a'] = True - assert True == self.cpx.button_a + self.cpx._Express__state["button_a"] = True + assert self.cpx.button_a def test_button_b(self): - self.cpx._Express__state['button_b'] = True - assert True == self.cpx.button_b + self.cpx._Express__state["button_b"] = True + assert self.cpx.button_b + + def test_taps(self): + self.cpx._Express__state["detect_taps"] = 2 + assert 2 == self.cpx.detect_taps + + @pytest.mark.parametrize("taps, expected", [(1, 1), (2, 2), (3, 1)]) + def test_taps_setter(self, taps, expected): + self.cpx.detect_taps = taps + assert expected == self.cpx.detect_taps def test_red_led(self): - self.cpx._Express__state['red_led'] = True - assert True == self.cpx.red_led + self.cpx._Express__state["red_led"] = True + assert self.cpx.red_led def test_red_led_int(self): self.cpx.red_led = 3 - assert True == self.cpx.red_led + assert self.cpx.red_led def test_red_led_string(self): - self.cpx.red_led = 'foo' - assert True == self.cpx.red_led + self.cpx.red_led = "foo" + assert self.cpx.red_led def test_switch(self): - self.cpx._Express__state['switch'] = True - assert True == self.cpx.switch + self.cpx._Express__state["switch"] = True + assert self.cpx.switch - def test_set_item_tuple(self): - self.cpx.pixels[0] = (255, 255, 255) - assert (255, 255, 255) == self.cpx._Express__state['pixels'][0] + def test_temperature(self): + self.cpx._Express__state["temperature"] = 31 + assert 31 == self.cpx.temperature - def test_set_item_list(self): - self.cpx.pixels[0] = [255, 255, 255] - assert (255, 255, 255) == self.cpx._Express__state['pixels'][0] - - def test_set_item_hex(self): - self.cpx.pixels[0] = 0xFFFFFF - assert (255, 255, 255) == self.cpx._Express__state['pixels'][0] - - def test_set_item_invalid(self): - with pytest.raises(ValueError): - self.cpx.pixels[0] = "hello" + def test_light(self): + self.cpx._Express__state["light"] = 255 + assert 255 == self.cpx.light def test_shake(self): - self.cpx._Express__state['shake'] = True - assert True == self.cpx.shake() + self.cpx._Express__state["shake"] = True + assert self.cpx.shake() def test_touch_A1(self): - self.cpx._Express__state['touch'][0] = True - assert True == self.cpx.touch_A1 + self.cpx._Express__state["touch"][0] = True + assert self.cpx.touch_A1 def test_touch_A2(self): - self.cpx._Express__state['touch'][1] = True - assert True == self.cpx.touch_A2 + self.cpx._Express__state["touch"][1] = True + assert self.cpx.touch_A2 def test_touch_A3(self): - self.cpx._Express__state['touch'][2] = True - assert True == self.cpx.touch_A3 - + self.cpx._Express__state["touch"][2] = True + assert self.cpx.touch_A3 + def test_touch_A4(self): - self.cpx._Express__state['touch'][3] = True - assert True == self.cpx.touch_A4 + self.cpx._Express__state["touch"][3] = True + assert self.cpx.touch_A4 def test_touch_A5(self): - self.cpx._Express__state['touch'][4] = True - assert True == self.cpx.touch_A5 - + self.cpx._Express__state["touch"][4] = True + assert self.cpx.touch_A5 + def test_touch_A6(self): - self.cpx._Express__state['touch'][5] = True - assert True == self.cpx.touch_A6 + self.cpx._Express__state["touch"][5] = True + assert self.cpx.touch_A6 def test_touch_A7(self): - self.cpx._Express__state['touch'][6] = True - assert True == self.cpx.touch_A7 + self.cpx._Express__state["touch"][6] = True + assert self.cpx.touch_A7 - def test_play_file_mp4(self): + def test_play_file_mp4_wrong_type(self): with pytest.raises(TypeError): - self.cpx.play_file('sample.mp4') - - def test_fill(self): - self.cpx.pixels.fill((0, 255, 0)) - expected_pixels = [(0, 255, 0)] * 10 - assert expected_pixels == self.cpx._Express__state['pixels'] - - def test_extract_pixel_value_list(self): - assert (0, 255, 0) == self.cpx.pixels._Pixel__extract_pixel_value((0, 255, 0)) - - def test_extract_pixel_value_list1(self): - assert (123, 123, 123) == self.cpx.pixels._Pixel__extract_pixel_value( - [123, 123, 123]) + self.cpx.play_file("sample.mp4") - def test_extract_pixel_value_int(self): - assert (0, 0, 255) == self.cpx.pixels._Pixel__extract_pixel_value(255) - - def test_extract_pixel_value_tuple(self): - assert (0, 255, 0) == self.cpx.pixels._Pixel__extract_pixel_value( - (0, 255, 0)) - - def test_extract_pixel_value_invalid_length(self): - with pytest.raises(ValueError): - self.cpx.pixels._Pixel__extract_pixel_value((1, 2, 3, 4)) - - def test_extract_pixel_value_invalid_tuple_value(self): - with pytest.raises(ValueError): - self.cpx.pixels._Pixel__extract_pixel_value((0, 222, "hello")) + def test_play_file_mp4(self): + playsound.playsound = mock.Mock() + self.cpx.play_file("sample.wav") + playsound.playsound.assert_called_once() diff --git a/src/adafruit_circuitplayground/test/test_pixel.py b/src/adafruit_circuitplayground/test/test_pixel.py new file mode 100644 index 000000000..2532611db --- /dev/null +++ b/src/adafruit_circuitplayground/test/test_pixel.py @@ -0,0 +1,120 @@ +import pytest + +from ..pixel import Pixel + + +class TestPixel(object): + def setup_method(self): + self.pixel = Pixel( + { + "brightness": 1.0, + "button_a": False, + "button_b": False, + "pixels": [(255, 0, 0), (0, 255, 0), (0, 0, 255)], + "red_led": False, + "switch": False, + } + ) + + @pytest.mark.parametrize("debug_mode", [True, False]) + def test_set_debug_mode(self, debug_mode): + self.pixel._Pixel__set_debug_mode(debug_mode) + assert debug_mode == self.pixel._Pixel__debug_mode + + def test_get_item_out_of_bounds(self): + with pytest.raises(IndexError): + p = self.pixel[3] + + def test_get_item(self): + assert (0, 0, 255) == self.pixel[2] + + def test_get_item_splice(self): + assert [(255, 0, 0), (0, 255, 0)] == self.pixel[0:2] + + def test_set_item(self): + self.pixel[1] = (50, 50, 50) + assert (50, 50, 50) == self.pixel[1] + + def test_set_item_splice(self): + self.pixel[0:1] = [(100, 100, 100), (0, 0, 100)] + assert (100, 100, 100) == self.pixel[0] + assert (0, 0, 100) == self.pixel[1] + + def test_set_item_out_of_bounds(self): + with pytest.raises(IndexError): + self.pixel[3] = (0, 0, 0) + + def test_set_item_invalid(self): + with pytest.raises(ValueError): + self.pixel[0] = "hello" + + def test_len(self): + assert 3 == len(self.pixel) + + @pytest.mark.parametrize("index, expected", [(0, True), (3, False)]) + def test_valid_index(self, index, expected): + assert self.pixel._Pixel__valid_index(index) == expected + + def test_fill(self): + self.pixel.fill((123, 123, 123)) + assert all(p == (123, 123, 123) for p in self.pixel._Pixel__state["pixels"]) + + @pytest.mark.parametrize( + "val, expected", + [([3, 4, 5], (3, 4, 5)), (432, (0, 1, 176)), ((1, 2, 3), (1, 2, 3))], + ) + def test_extract_pixel_values_not_slice(self, val, expected): + assert expected == self.pixel._Pixel__extract_pixel_value(val) + + @pytest.mark.parametrize( + "val, expected", + [ + ([[3, 4, 5], [6, 7, 8]], [(3, 4, 5), (6, 7, 8)]), + ([444555, 666777], [(6, 200, 139), (10, 44, 153)]), + ([(10, 10, 10), (20, 20, 20)], [(10, 10, 10), (20, 20, 20)]), + ], + ) + def test_extract_pixel_values_slice(self, val, expected): + assert expected == self.pixel._Pixel__extract_pixel_value(val, is_slice=True) + + @pytest.mark.parametrize("val", [[1, 2, 3, 4], [1, 2], 0.3]) + def test_extract_pixel_values_fail(self, val): + with pytest.raises(ValueError): + self.pixel._Pixel__extract_pixel_value(val) + + def test_hex_to_rgb_fail(self): + with pytest.raises(ValueError): + self.pixel._Pixel__hex_to_rgb("x") + + @pytest.mark.parametrize( + "hex, expected", + [ + ("0xffffff", (255, 255, 255)), + ("0x0", (0, 0, 0)), + ("0xff0000", (255, 0, 0)), + ("0xabcdef", (171, 205, 239)), + ], + ) + def test_hex_to_rgb(self, hex, expected): + assert expected == self.pixel._Pixel__hex_to_rgb(hex) + + @pytest.mark.parametrize( + "pixValue, expected", + [(0, True), (200, True), (255, True), (-1, False), (256, False), ("1", False)], + ) + def test_valid_rgb_value(self, pixValue, expected): + assert expected == self.pixel._Pixel__valid_rgb_value(pixValue) + + def test_get_brightness(self): + self.pixel._Pixel__state["brightness"] = 0.4 + assert 0.4 == pytest.approx(self.pixel.brightness) + + @pytest.mark.parametrize("brightness", [-0.1, 1.1]) + def test_set_brightness_fail(self, brightness): + with pytest.raises(ValueError): + self.pixel.brightness = brightness + + @pytest.mark.parametrize("brightness", [0, 1, 0.4, 0.333]) + def test_set_brightness(self, brightness): + self.pixel.brightness = brightness + assert self.pixel._Pixel__valid_brightness(brightness) diff --git a/src/adafruit_circuitplayground/test/test_utils.py b/src/adafruit_circuitplayground/test/test_utils.py new file mode 100644 index 000000000..3c25128e6 --- /dev/null +++ b/src/adafruit_circuitplayground/test/test_utils.py @@ -0,0 +1,28 @@ +import sys + +from unittest import mock + +from .. import constants as CONSTANTS +from .. import utils + + +class TestUtils(object): + def test_remove_leading_slashes(self): + original = "///a//b/" + expected = "a//b/" + assert expected == utils.remove_leading_slashes(original) + + def test_escape_notOSX(self): + if sys.platform.startswith(CONSTANTS.MAC_OS): + utils.sys = mock.MagicMock() + utils.sys.configure_mock(platform="win32") + original = "a b" + assert original == utils.escape_if_OSX(original) + + def test_escape_isOSX(self): + if not sys.platform.startswith(CONSTANTS.MAC_OS): + utils.sys = mock.MagicMock() + utils.sys.configure_mock(platform="darwin") + original = "a b" + expected = "a%20b" + assert expected == utils.escape_if_OSX(original) diff --git a/src/adafruit_circuitplayground/utils.py b/src/adafruit_circuitplayground/utils.py index 83a595d3b..14fddf227 100644 --- a/src/adafruit_circuitplayground/utils.py +++ b/src/adafruit_circuitplayground/utils.py @@ -16,21 +16,20 @@ 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)} + 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) + print(json.dumps(message) + "\0", end="", file=sys.__stdout__, flush=True) time.sleep(CONSTANTS.TIME_DELAY) def remove_leading_slashes(string): - string = string.lstrip('\\/') + 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 \ No newline at end of file + return file_name diff --git a/src/constants.ts b/src/constants.ts index 692d13f55..0a2db62dc 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,377 +1,400 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as nls from "vscode-nls"; import * as path from "path"; import { MessageItem } from "vscode"; +import * as nls from "vscode-nls"; // Debugger Server export const SERVER_INFO = { - DEFAULT_SERVER_PORT: 5577, - ERROR_CODE_INIT_SERVER: "ERROR_INIT_SERVER", - SERVER_PORT_CONFIGURATION: "deviceSimulatorExpress.debuggerServerPort" + DEFAULT_SERVER_PORT: 5577, + ERROR_CODE_INIT_SERVER: "ERROR_INIT_SERVER", + SERVER_PORT_CONFIGURATION: "deviceSimulatorExpress.debuggerServerPort", }; const localize: nls.LocalizeFunc = nls.config({ - messageFormat: nls.MessageFormat.file + messageFormat: nls.MessageFormat.file, })(); export const CONFIG = { - SHOW_DEPENDENCY_INSTALL: "deviceSimulatorExpress.showDependencyInstall", - SHOW_NEW_FILE_POPUP: "pacifica.showNewFilePopup" + 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", - }, - ERROR: { - COMPORT_UNKNOWN_ERROR: - "Writing to COM port (GetOverlappedResult): Unknown error code 121", - CPX_FILE_ERROR: localize( - "error.cpxFileFormat", - "The cpx.json file format is not correct." - ), - DEBUGGER_SERVER_INIT_FAILED: (port: number) => { - return localize( - "error.debuggerServerInitFailed", - `Warning : The Debugger Server cannot be opened. Please try to free the port ${port} if it's already in use or select another one in your Settings 'Device Simulator Express: Debugger Server Port' and start another debug session.\n You can still debug your code but you won't be able to use the Simulator.` - ); - }, - DEBUGGING_SESSION_IN_PROGESS: localize( - "error.debuggingSessionInProgress", - "[ERROR] A debugging session is currently in progress, please stop it before running your code. \n" - ), - FAILED_TO_OPEN_SERIAL_PORT: (port: string): string => { - return localize( - "error.failedToOpenSerialPort", - `[ERROR] Failed to open serial port ${port}.` - ); + DEBUG_CONFIGURATION_TYPE: "deviceSimulatorExpress", + DEPENDENCY_CHECKER: { + PIP3: "pip3", + PYTHON: "python", + PYTHON3: "python3.7", }, - FAILED_TO_OPEN_SERIAL_PORT_DUE_TO: (port: string, error: any) => { - return localize( - "error.failedToOpenSerialPortDueTo", - `[ERROR] Failed to open serial port ${port} due to error: ${error}. \n` - ); + ERROR: { + COMPORT_UNKNOWN_ERROR: + "Writing to COM port (GetOverlappedResult): Unknown error code 121", + CPX_FILE_ERROR: localize( + "error.cpxFileFormat", + "The cpx.json file format is not correct." + ), + DEBUGGER_SERVER_INIT_FAILED: (port: number) => { + return localize( + "error.debuggerServerInitFailed", + `Warning : The Debugger Server cannot be opened. Please try to free the port ${port} if it's already in use or select another one in your Settings 'Device Simulator Express: Debugger Server Port' and start another debug session.\n You can still debug your code but you won't be able to use the Simulator.` + ); + }, + DEBUGGING_SESSION_IN_PROGESS: localize( + "error.debuggingSessionInProgress", + "[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.", + FAILED_TO_OPEN_SERIAL_PORT: (port: string): string => { + return localize( + "error.failedToOpenSerialPort", + `[ERROR] Failed to open serial port ${port}.` + ); + }, + FAILED_TO_OPEN_SERIAL_PORT_DUE_TO: (port: string, error: any) => { + return localize( + "error.failedToOpenSerialPortDueTo", + `[ERROR] Failed to open serial port ${port} due to error: ${error}. \n` + ); + }, + INCORRECT_FILE_NAME_FOR_DEVICE: localize( + "error.incorrectFileNameForDevice", + '[ERROR] Can\'t deploy to your Circuit Playground Express device, please rename your file to "code.py" or "main.py". \n' + ), + INCORRECT_FILE_NAME_FOR_DEVICE_POPUP: localize( + "error.incorrectFileNameForDevicePopup", + 'Seems like you have a different file name than what CPX requires, please rename it to "code.py" or "main.py".' + ), + INVALID_FILE_EXTENSION_DEBUG: localize( + "error.invalidFileExtensionDebug", + "The file you tried to run isn't a Python file." + ), + NO_DEVICE: localize( + "error.noDevice", + "No plugged in boards detected. Please double check if your board is connected and/or properly formatted" + ), + NO_FILE_TO_RUN: localize( + "error.noFileToRun", + '[ERROR] We can\'t find a Python file to run. Please make sure you select or open a new ".py" code file, or use the "New File" command to get started and see useful links.\n' + ), + NO_FOLDER_OPENED: localize( + "error.noFolderCreated", + "In order to use the Serial Monitor, you need to open a folder and reload VS Code." + ), + NO_PROGRAM_FOUND_DEBUG: localize( + "error.noProgramFoundDebug", + "Cannot find a program to debug." + ), + 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." + ), + RECONNECT_DEVICE: localize( + "error.reconnectDevice", + "Please disconnect your Circuit Playground Express and try again." + ), + STDERR: (data: string) => { + return localize("error.stderr", `\n[ERROR] ${data} \n`); + }, + UNEXPECTED_MESSAGE: localize( + "error.unexpectedMessage", + "Webview sent an unexpected message" + ), }, - INCORRECT_FILE_NAME_FOR_DEVICE: localize( - "error.incorrectFileNameForDevice", - '[ERROR] Can\'t deploy to your Circuit Playground Express device, please rename your file to "code.py" or "main.py". \n' - ), - INCORRECT_FILE_NAME_FOR_DEVICE_POPUP: localize( - "error.incorrectFileNameForDevicePopup", - 'Seems like you have a different file name than what CPX requires, please rename it to "code.py" or "main.py".' - ), - INVALID_FILE_EXTENSION_DEBUG: localize( - "error.invalidFileExtensionDebug", - "The file you tried to run isn't a Python file." - ), - NO_DEVICE: localize( - "error.noDevice", - "No plugged in boards detected. Please double check if your board is connected and/or properly formatted" - ), - NO_FILE_TO_RUN: localize( - "error.noFileToRun", - '[ERROR] We can\'t find a Python file to run. Please make sure you select or open a new ".py" code file, or use the "New File" command to get started and see useful links.\n' - ), - NO_FOLDER_OPENED: localize( - "error.noFolderCreated", - "In order to use the Serial Monitor, you need to open a folder and reload VS Code." - ), - NO_PROGRAM_FOUND_DEBUG: localize( - "error.noProgramFoundDebug", - "Cannot find a program to debug." - ), - 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." - ), - RECONNECT_DEVICE: localize( - "error.reconnectDevice", - "Please disconnect your Circuit Playground Express and try again." - ), - STDERR: (data: string) => { - return localize("error.stderr", `\n[ERROR] ${data} \n`); + FILESYSTEM: { + OUTPUT_DIRECTORY: "out", + PYTHON_LIBS_DIR: "python_libs", }, - UNEXPECTED_MESSAGE: localize( - "error.unexpectedMessage", - "Webview sent an unexpected message" - ) - }, - INFO: { - 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" - ), - CLOSED_SERIAL_PORT: (port: string) => { - return localize( - "info.closedSerialPort", - `[DONE] Closed the serial port - ${port} \n` - ); + INFO: { + 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" + ), + CLOSED_SERIAL_PORT: (port: string) => { + return localize( + "info.closedSerialPort", + `[DONE] Closed the serial port - ${port} \n` + ); + }, + COMPLETED_MESSAGE: "Completed", + CPX_JSON_ALREADY_GENERATED: localize( + "info.cpxJsonAlreadyGenerated", + "cpx.json has already been generated." + ), + DEPLOY_DEVICE: localize( + "info.deployDevice", + "\n[INFO] Deploying code to the device...\n" + ), + DEPLOY_SIMULATOR: localize( + "info.deploySimulator", + "\n[INFO] Deploying code to the simulator...\n" + ), + DEPLOY_SUCCESS: localize( + "info.deploySuccess", + "\n[INFO] Code successfully copied! Your Circuit Playground Express should be loading and ready to go shortly.\n" + ), + EXTENSION_ACTIVATED: localize( + "info.extensionActivated", + "Congratulations, your extension Adafruit_Simulator is now active!" + ), + FILE_SELECTED: (filePath: string) => { + return localize( + "info.fileSelected", + `[INFO] File selected : ${filePath} \n` + ); + }, + 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.' + ), + 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." + ), + INSTALL_PYTHON_DEPENDENCIES: localize( + "info.installPythonDependencies", + "Do you want us to try and install this extensions dependencies for you?" + ), + INVALID_FILE_NAME_DEBUG: localize( + "info.invalidFileNameDebug", + 'The file you tried to debug isn\'t named "code.py" or "main.py". Rename your file if you want your code to work on your actual device.' + ), + NEW_FILE: localize( + "info.newFile", + "New to Python or the Circuit Playground Express? We are here to help!" + ), + OPENED_SERIAL_PORT: (port: string) => { + return localize( + "info.openedSerialPort", + `[INFO] Opened the serial port - ${port} \n` + ); + }, + OPENING_SERIAL_PORT: (port: string) => { + return localize( + "info.openingSerialPort", + `[STARTING] Opening the serial port - ${port} \n` + ); + }, + PLEASE_OPEN_FOLDER: localize( + "info.pleaseOpenFolder", + "Please open a folder first." + ), + REDIRECT: localize("info.redirect", "You are being redirected."), + RUNNING_CODE: localize("info.runningCode", "Running user code"), + SUCCESSFUL_INSTALL: localize( + "info.successfulInstall", + "Successfully installed Python dependencies." + ), + THIRD_PARTY_WEBSITE: localize( + "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' + ), + WELCOME_OUTPUT_TAB: localize( + "info.welcomeOutputTab", + "Welcome to the Adafruit Simulator output tab!\n\n" + ), }, - COMPLETED_MESSAGE: "Completed", - CPX_JSON_ALREADY_GENERATED: localize( - "info.cpxJsonAlreadyGenerated", - "cpx.json has already been generated." - ), - DEPLOY_DEVICE: localize( - "info.deployDevice", - "\n[INFO] Deploying code to the device...\n" - ), - DEPLOY_SIMULATOR: localize( - "info.deploySimulator", - "\n[INFO] Deploying code to the simulator...\n" - ), - DEPLOY_SUCCESS: localize( - "info.deploySuccess", - "\n[INFO] Code successfully copied! Your Circuit Playground Express should be loading and ready to go shortly.\n" - ), - EXTENSION_ACTIVATED: localize( - "info.extensionActivated", - "Congratulations, your extension Adafruit_Simulator is now active!" - ), - FILE_SELECTED: (filePath: string) => { - return localize( - "info.fileSelected", - `[INFO] File selected : ${filePath} \n` - ); + LABEL: { + WEBVIEW_PANEL: localize( + "label.webviewPanel", + "Device Simulator Express" + ), }, - 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.' - ), - 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." - ), - INSTALL_PYTHON_DEPENDENCIES: localize( - "info.installPythonDependencies", - "Do you want us to try and install this extensions dependencies for you?" - ), - INVALID_FILE_NAME_DEBUG: localize( - "info.invalidFileNameDebug", - 'The file you tried to debug isn\'t named "code.py" or "main.py". Rename your file if you want your code to work on your actual device.' - ), - NEW_FILE: localize( - "info.newFile", - "New to Python or the Circuit Playground Express? We are here to help!" - ), - OPENED_SERIAL_PORT: (port: string) => { - return localize( - "info.openedSerialPort", - `[INFO] Opened the serial port - ${port} \n` - ); + LINKS: { + DOWNLOAD_PYTHON: "https://www.python.org/downloads/", + EXAMPLE_CODE: + "https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples", + HELP: + "https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart", + INSTALL: + "https://github.com/microsoft/vscode-python-devicesimulator/blob/dev/docs/install.md", + PRIVACY: "https://www.adafruit.com/privacy", + TUTORIALS: + "https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library", }, - OPENING_SERIAL_PORT: (port: string) => { - return localize( - "info.openingSerialPort", - `[STARTING] Opening the serial port - ${port} \n` - ); + MISC: { + SELECT_PORT_PLACEHOLDER: localize( + "misc.selectPortPlaceholder", + "Select a serial port" + ), + SERIAL_MONITOR_NAME: localize( + "misc.serialMonitorName", + "Device Simulator Express Serial Monitor" + ), + SERIAL_MONITOR_TEST_IF_OPEN: localize( + "misc.testIfPortOpen", + "Test if serial port is open" + ), }, - PLEASE_OPEN_FOLDER: localize( - "info.pleaseOpenFolder", - "Please open a folder first." - ), - REDIRECT: localize("info.redirect", "You are being redirected."), - RUNNING_CODE: localize("info.runningCode", "Running user code"), - SUCCESSFUL_INSTALL: localize( - "info.successfulInstall", - "Successfully installed Python dependencies." - ), - THIRD_PARTY_WEBSITE: localize( - "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' - ), - WELCOME_OUTPUT_TAB: localize( - "info.welcomeOutputTab", - "Welcome to the Adafruit Simulator output tab !\n\n" - ) - }, - LABEL: { - WEBVIEW_PANEL: localize("label.webviewPanel", "Device Simulator Express") - }, - LINKS: { - DOWNLOAD_PYTHON: "https://www.python.org/downloads/", - EXAMPLE_CODE: - "https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples", - HELP: - "https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart", - PRIVACY: "https://www.adafruit.com/privacy", - TUTORIALS: - "https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library" - }, - MISC: { - SELECT_PORT_PLACEHOLDER: localize( - "misc.selectPortPlaceholder", - "Select a serial port" - ), - SERIAL_MONITOR_NAME: localize( - "misc.serialMonitorName", - "Device Simulator Express Serial Monitor" - ), - SERIAL_MONITOR_TEST_IF_OPEN: localize( - "misc.testIfPortOpen", - "Test if serial port is open" - ) - }, - NAME: localize("name", "Device Simulator Express"), - WARNING: { - ACCEPT_AND_RUN: localize( - "warning.agreeAndRun", - "By selecting ‘Agree and Run’, you understand the extension executes Python code on your local computer, which may be a potential security risk." - ), - INVALID_BAUD_RATE: localize( - "warning.invalidBaudRate", - "Invalid baud rate, keep baud rate unchanged." - ), - NO_RATE_SELECTED: localize( - "warning.noRateSelected", - "No rate is selected, keep baud rate unchanged." - ), - NO_SERIAL_PORT_SELECTED: localize( - "warning.noSerialPortSelected", - "No serial port was selected, please select a serial port first" - ), - SERIAL_MONITOR_ALREADY_OPENED: (port: string) => { - return localize( - "warning.serialMonitorAlreadyOpened", - `Serial monitor is already opened for ${port} \n` - ); + NAME: localize("name", "Device Simulator Express"), + WARNING: { + ACCEPT_AND_RUN: localize( + "warning.agreeAndRun", + "By selecting ‘Agree and Run’, you understand the extension executes Python code on your local computer, which may be a potential security risk." + ), + INVALID_BAUD_RATE: localize( + "warning.invalidBaudRate", + "Invalid baud rate, keep baud rate unchanged." + ), + NO_RATE_SELECTED: localize( + "warning.noRateSelected", + "No rate is selected, keep baud rate unchanged." + ), + NO_SERIAL_PORT_SELECTED: localize( + "warning.noSerialPortSelected", + "No serial port was selected, please select a serial port first" + ), + SERIAL_MONITOR_ALREADY_OPENED: (port: string) => { + return localize( + "warning.serialMonitorAlreadyOpened", + `Serial monitor is already opened for ${port} \n` + ); + }, + SERIAL_MONITOR_NOT_STARTED: localize( + "warning.serialMonitorNotStarted", + "Serial monitor has not been started." + ), + SERIAL_PORT_NOT_STARTED: localize( + "warning.serialPortNotStarted", + "Serial port has not been started.\n" + ), }, - SERIAL_MONITOR_NOT_STARTED: localize( - "warning.serialMonitorNotStarted", - "Serial monitor has not been started." - ), - SERIAL_PORT_NOT_STARTED: localize( - "warning.serialPortNotStarted", - "Serial port has not been started.\n" - ) - } }; export enum CONFIG_KEYS { - ENABLE_USB_DETECTION = "deviceSimulatorExpress.enableUSBDetection" + ENABLE_USB_DETECTION = "deviceSimulatorExpress.enableUSBDetection", } export enum TelemetryEventName { - FAILED_TO_OPEN_SIMULATOR = "SIMULATOR.FAILED_TO_OPEN", + FAILED_TO_OPEN_SIMULATOR = "SIMULATOR.FAILED_TO_OPEN", - // 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", + // 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", - // Simulator interaction - SIMULATOR_BUTTON_A = "SIMULATOR.BUTTON.A", - SIMULATOR_BUTTON_B = "SIMULATOR.BUTTON.B", - SIMULATOR_BUTTON_AB = "SIMULATOR.BUTTON.AB", - SIMULATOR_SWITCH = "SIMULATOR.SWITCH", + // Simulator interaction + SIMULATOR_BUTTON_A = "SIMULATOR.BUTTON.A", + SIMULATOR_BUTTON_B = "SIMULATOR.BUTTON.B", + SIMULATOR_BUTTON_AB = "SIMULATOR.BUTTON.AB", + SIMULATOR_SWITCH = "SIMULATOR.SWITCH", - //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", + // 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", - // 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", + // 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", - 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", + 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", - SUCCESS_COMMAND_DEPLOY_DEVICE = "SUCCESS.COMMAND.DEPLOY.DEVICE", + SUCCESS_COMMAND_DEPLOY_DEVICE = "SUCCESS.COMMAND.DEPLOY.DEVICE", - // Performance - PERFORMANCE_DEPLOY_DEVICE = "PERFORMANCE.DEPLOY.DEVICE", - PERFORMANCE_NEW_FILE = "PERFORMANCE.NEW.FILE", - PERFORMANCE_OPEN_SIMULATOR = "PERFORMANCE.OPEN.SIMULATOR" + // Performance + PERFORMANCE_DEPLOY_DEVICE = "PERFORMANCE.DEPLOY.DEVICE", + PERFORMANCE_NEW_FILE = "PERFORMANCE.NEW.FILE", + PERFORMANCE_OPEN_SIMULATOR = "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" + BUTTON_PRESS = "button-press", + PLAY_SIMULATOR = "play-simulator", + SENSOR_CHANGED = "sensor-changed", + REFRESH_SIMULATOR = "refresh-simulator", + SLIDER_TELEMETRY = "slider-telemetry", } // tslint:disable-next-line: no-namespace export namespace DialogResponses { - export const ACCEPT_AND_RUN: MessageItem = { - title: localize("dialogResponses.agreeAndRun", "Agree and Run") - }; - export const AGREE_AND_PROCEED: MessageItem = { - title: localize("dialogResponses.agreeAndProceed", "Agree and Proceed") - }; - export const CANCEL: MessageItem = { - title: localize("dialogResponses.cancel", "Cancel") - }; - export const HELP: MessageItem = { - title: localize("dialogResponses.help", "I need help") - }; - export const DONT_SHOW: MessageItem = { - title: localize("dialogResponses.dontShowAgain", "Don't Show Again") - }; - export const NO: MessageItem = { - title: localize("dialogResponses.No", "No") - }; - export const INSTALL_NOW: MessageItem = { - title: localize("dialogResponses.installNow", "Install Now") - }; - export const DONT_INSTALL: MessageItem = { - title: localize("dialogResponses.dontInstall", "Don't Install") - }; - export const PRIVACY_STATEMENT: MessageItem = { - title: localize("info.privacyStatement", "Privacy Statement") - }; - export const TUTORIALS: MessageItem = { - title: localize("dialogResponses.tutorials", "Tutorials on Adafruit") - }; - export const EXAMPLE_CODE: MessageItem = { - title: localize("dialogResponses.exampleCode", "Example Code on GitHub") - }; - export const MESSAGE_UNDERSTOOD: MessageItem = { - title: localize("dialogResponses.messageUnderstood", "Got It") - }; - export const INSTALL_PYTHON: MessageItem = { - title: localize("dialogResponses.installPython", "Install from python.org") - }; - export const YES: MessageItem = { - title: localize("dialogResponses.Yes", "Yes") - }; + export const ACCEPT_AND_RUN: MessageItem = { + title: localize("dialogResponses.agreeAndRun", "Agree and Run"), + }; + export const AGREE_AND_PROCEED: MessageItem = { + title: localize("dialogResponses.agreeAndProceed", "Agree and Proceed"), + }; + export const CANCEL: MessageItem = { + title: localize("dialogResponses.cancel", "Cancel"), + }; + export const HELP: MessageItem = { + title: localize("dialogResponses.help", "I need help"), + }; + export const DONT_SHOW: MessageItem = { + title: localize("dialogResponses.dontShowAgain", "Don't Show Again"), + }; + export const NO: MessageItem = { + title: localize("dialogResponses.No", "No"), + }; + export const INSTALL_NOW: MessageItem = { + title: localize("dialogResponses.installNow", "Install Now"), + }; + export const DONT_INSTALL: MessageItem = { + title: localize("dialogResponses.dontInstall", "Don't Install"), + }; + export const PRIVACY_STATEMENT: MessageItem = { + title: localize("info.privacyStatement", "Privacy Statement"), + }; + export const TUTORIALS: MessageItem = { + title: localize("dialogResponses.tutorials", "Tutorials on Adafruit"), + }; + export const EXAMPLE_CODE: MessageItem = { + title: localize( + "dialogResponses.exampleCode", + "Example Code on GitHub" + ), + }; + export const MESSAGE_UNDERSTOOD: MessageItem = { + title: localize("dialogResponses.messageUnderstood", "Got It"), + }; + export const INSTALL_PYTHON: MessageItem = { + title: localize( + "dialogResponses.installPython", + "Install from python.org" + ), + }; + export const YES: MessageItem = { + title: localize("dialogResponses.Yes", "Yes"), + }; + export const READ_INSTALL_MD: MessageItem = { + title: localize( + "dialogResponses.readInstall", + "Read installation docs" + ), + }; } export const CPX_CONFIG_FILE = path.join(".vscode", "cpx.json"); export const USER_CODE_NAMES = { - CODE_PY: "code.py", - MAIN_PY: "main.py" + CODE_PY: "code.py", + MAIN_PY: "main.py", }; export const STATUS_BAR_PRIORITY = { - PORT: 20, - OPEN_PORT: 30, - BAUD_RATE: 40 + PORT: 20, + OPEN_PORT: 30, + BAUD_RATE: 40, }; export default CONSTANTS; diff --git a/src/cpxWorkspace.ts b/src/cpxWorkspace.ts index b1276a35b..47239a79a 100644 --- a/src/cpxWorkspace.ts +++ b/src/cpxWorkspace.ts @@ -3,7 +3,7 @@ import * as path from "path"; import * as vscode from "vscode"; export class CPXWorkspace { - static get rootPath(): string|undefined { + static get rootPath(): string | undefined { const workspaceFolders = vscode.workspace.workspaceFolders; if (!workspaceFolders || workspaceFolders.length === 0) { return undefined; @@ -11,7 +11,11 @@ export class CPXWorkspace { for (const workspaceFolder of workspaceFolders) { const workspaceFolderPath = workspaceFolder.uri.fsPath; - const cpxConfigPath = path.join(workspaceFolderPath, ".vscode", "cpx.json"); + const cpxConfigPath = path.join( + workspaceFolderPath, + ".vscode", + "cpx.json" + ); if (fs.existsSync(cpxConfigPath)) { return workspaceFolderPath; } diff --git a/src/debug_user_code.py b/src/debug_user_code.py index 3a5297c21..8d5b57873 100644 --- a/src/debug_user_code.py +++ b/src/debug_user_code.py @@ -8,7 +8,6 @@ import python_constants as CONSTANTS - # Insert absolute path to Adafruit library 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.LIBRARY_NAME) @@ -16,8 +15,7 @@ # 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) +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 @@ -29,7 +27,7 @@ # Get user's code path -abs_path_to_code_file = '' +abs_path_to_code_file = "" if len(sys.argv) > 1 and sys.argv[1]: abs_path_to_code_file = sys.argv[1] else: @@ -52,16 +50,14 @@ with open(abs_path_to_code_file) as user_code_file: user_code = user_code_file.read() try: - codeObj = compile(user_code, abs_path_to_code_file, - CONSTANTS.EXEC_COMMAND) + codeObj = compile(user_code, abs_path_to_code_file, CONSTANTS.EXEC_COMMAND) exec(codeObj, {}) sys.stdout.flush() except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() errorMessage = CONSTANTS.ERROR_TRACEBACK - stackTrace = traceback.format_exception( - exc_type, exc_value, exc_traceback) + stackTrace = traceback.format_exception(exc_type, exc_value, exc_traceback) for frameIndex in range(2, len(stackTrace) - 1): - errorMessage += '\t' + str(stackTrace[frameIndex]) + errorMessage += "\t" + str(stackTrace[frameIndex]) print(e, errorMessage, file=sys.stderr, flush=True) diff --git a/src/debuggerCommunicationServer.ts b/src/debuggerCommunicationServer.ts index 23d429475..76eb02f42 100644 --- a/src/debuggerCommunicationServer.ts +++ b/src/debuggerCommunicationServer.ts @@ -7,85 +7,87 @@ import { WebviewPanel } from "vscode"; import { SERVER_INFO } from "./constants"; export class DebuggerCommunicationServer { - private port: number; - private serverHttp: http.Server; - private serverIo: socketio.Server; - private simulatorWebview: WebviewPanel | undefined; + private port: number; + private serverHttp: http.Server; + private serverIo: socketio.Server; + private simulatorWebview: WebviewPanel | undefined; - constructor( - webviewPanel: WebviewPanel | undefined, - port = SERVER_INFO.DEFAULT_SERVER_PORT - ) { - this.port = port; - this.serverHttp = new http.Server(); - this.initHttpServer(); + constructor( + webviewPanel: WebviewPanel | undefined, + port = SERVER_INFO.DEFAULT_SERVER_PORT + ) { + this.port = port; + this.serverHttp = new http.Server(); + this.initHttpServer(); - this.serverIo = socketio(this.serverHttp); - this.simulatorWebview = webviewPanel; - this.initEventsHandlers(); - console.info(`Server running on port ${this.port}`); - } + this.serverIo = socketio(this.serverHttp); + this.simulatorWebview = webviewPanel; + this.initEventsHandlers(); + console.info(`Server running on port ${this.port}`); + } - public closeConnection(): void { - this.serverIo.close(); - this.serverHttp.close(); - console.info("Closing the server"); - } + public closeConnection(): void { + this.serverIo.close(); + this.serverHttp.close(); + console.info("Closing the server"); + } - public setWebview(webviewPanel: WebviewPanel | undefined) { - this.simulatorWebview = webviewPanel; - } + 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); - } + // Emit Buttons Inputs Events + public emitButtonPress(newState: string): void { + console.log(`Emit Button Press: ${newState} \n`); + this.serverIo.emit("button_press", newState); + } - // Emit Sensors Inputs Events - public emitSensorChanged(newState: string): void { - console.log(`Emit Sensor Changed: ${newState} \n`); - this.serverIo.emit("sensor_changed", newState); - } + // Emit Sensors Inputs Events + public emitSensorChanged(newState: string): void { + console.log(`Emit Sensor Changed: ${newState} \n`); + this.serverIo.emit("sensor_changed", newState); + } - private initHttpServer(): void { - this.serverHttp.listen(this.port); - if (!this.serverHttp.listening) { - throw new Error(SERVER_INFO.ERROR_CODE_INIT_SERVER); + private initHttpServer(): void { + this.serverHttp.listen(this.port); + if (!this.serverHttp.listening) { + throw new Error(SERVER_INFO.ERROR_CODE_INIT_SERVER); + } } - } - private initEventsHandlers(): void { - this.serverIo.on("connection", (socket: any) => { - console.log("Connection received"); + private initEventsHandlers(): void { + this.serverIo.on("connection", (socket: any) => { + console.log("Connection received"); - socket.on("updateState", (data: any) => { - this.handleState(data); - }); + socket.on("updateState", (data: any) => { + this.handleState(data); + }); - socket.on("disconnect", () => { - console.log("Socket disconnected"); - if (this.simulatorWebview) { - this.simulatorWebview.webview.postMessage({ command: "reset-state" }); - } - }); - }); - } + socket.on("disconnect", () => { + console.log("Socket disconnected"); + if (this.simulatorWebview) { + this.simulatorWebview.webview.postMessage({ + command: "reset-state", + }); + } + }); + }); + } - private handleState(data: any): void { - try { - const messageToWebview = JSON.parse(data); - if (messageToWebview.type === "state") { - console.log(`State recieved: ${messageToWebview.data}`); - if (this.simulatorWebview) { - this.simulatorWebview.webview.postMessage({ - command: "set-state", - state: JSON.parse(messageToWebview.data) - }); + private handleState(data: any): void { + try { + const messageToWebview = JSON.parse(data); + if (messageToWebview.type === "state") { + console.log(`State recieved: ${messageToWebview.data}`); + if (this.simulatorWebview) { + this.simulatorWebview.webview.postMessage({ + command: "set-state", + state: JSON.parse(messageToWebview.data), + }); + } + } + } catch (err) { + console.error(`Error: Non-JSON output from the process : ${data}`); } - } - } catch (err) { - console.error(`Error: Non-JSON output from the process : ${data}`); } - } } diff --git a/src/device.py b/src/device.py index 5eca629ee..60b081b50 100644 --- a/src/device.py +++ b/src/device.py @@ -7,6 +7,7 @@ import sys import json import python_constants as CONSTANTS + if sys.platform == "win32": # pylint: disable=import-error import win32api @@ -23,10 +24,15 @@ def find_device_directory(self): """ found_directory = None - if sys.platform.startswith(CONSTANTS.LINUX_OS) or sys.platform.startswith(CONSTANTS.MAC_OS): + if sys.platform.startswith(CONSTANTS.LINUX_OS) or sys.platform.startswith( + CONSTANTS.MAC_OS + ): # Mac or Linux - mounted = check_output(CONSTANTS.MOUNT_COMMAND).decode( - CONSTANTS.UTF_FORMAT).split('\n') + mounted = ( + check_output(CONSTANTS.MOUNT_COMMAND) + .decode(CONSTANTS.UTF_FORMAT) + .split("\n") + ) for mount in mounted: drive_path = mount.split()[2] if mount else "" if drive_path.endswith(CONSTANTS.CPX_DRIVE_NAME): @@ -36,19 +42,20 @@ def find_device_directory(self): # Windows for drive_letter in string.ascii_uppercase: drive_path = "{}:{}".format(drive_letter, os.sep) - if (os.path.exists(drive_path)): + if os.path.exists(drive_path): drive_name = win32api.GetVolumeInformation(drive_path)[0] if drive_name == CONSTANTS.CPX_DRIVE_NAME: found_directory = drive_path break else: - raise NotImplementedError( - CONSTANTS.NOT_SUPPORTED_OS.format(sys.platform)) + raise NotImplementedError(CONSTANTS.NOT_SUPPORTED_OS.format(sys.platform)) if not found_directory: self.connected = False - self.error_message = (CONSTANTS.NO_CPX_DETECTED_ERROR_TITLE, - CONSTANTS.NO_CPX_DETECTED_ERROR_DETAIL.format(sys.platform)) + self.error_message = ( + CONSTANTS.NO_CPX_DETECTED_ERROR_TITLE, + CONSTANTS.NO_CPX_DETECTED_ERROR_DETAIL.format(sys.platform), + ) else: self.connected = True self.error_message = None @@ -61,13 +68,15 @@ def find_device_directory(self): cpx = Device() device_directory = cpx.find_device_directory() if cpx.error_message: - print("{}:\t{}".format( - cpx.error_message[0], cpx.error_message[1]), file=sys.stderr, flush=True) + print( + "{}:\t{}".format(cpx.error_message[0], cpx.error_message[1]), + file=sys.stderr, + flush=True, + ) if cpx.connected: - dest_path = os.path.join( - device_directory, sys.argv[1].rsplit(os.sep, 1)[-1]) + dest_path = os.path.join(device_directory, sys.argv[1].rsplit(os.sep, 1)[-1]) shutil.copyfile(sys.argv[1], dest_path) - message = {'type': 'complete'} + message = {"type": "complete"} else: - message = {'type': 'no-device'} + message = {"type": "no-device"} print(json.dumps(message), flush=True) diff --git a/src/deviceContext.ts b/src/deviceContext.ts index ebcb25814..a4f0afd2e 100644 --- a/src/deviceContext.ts +++ b/src/deviceContext.ts @@ -5,10 +5,10 @@ import * as fs from "fs"; import * as path from "path"; -import * as utils from "./extension_utils/utils"; import * as vscode from "vscode"; -import { CPXWorkspace } from "./cpxWorkspace"; import CONSTANTS, { CPX_CONFIG_FILE } from "./constants"; +import { CPXWorkspace } from "./cpxWorkspace"; +import * as utils from "./extension_utils/utils"; export class DeviceContext implements vscode.Disposable { public static getInstance(): DeviceContext { @@ -21,11 +21,18 @@ export class DeviceContext implements vscode.Disposable { private _watcher: vscode.FileSystemWatcher; private _vscodeWatcher: vscode.FileSystemWatcher; private _port!: string; - + private constructor() { if (vscode.workspace && CPXWorkspace.rootPath) { - this._watcher = vscode.workspace.createFileSystemWatcher(path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE)); - this._vscodeWatcher = vscode.workspace.createFileSystemWatcher(path.join(CPXWorkspace.rootPath, ".vscode"), true, true, false); + this._watcher = vscode.workspace.createFileSystemWatcher( + path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE) + ); + this._vscodeWatcher = vscode.workspace.createFileSystemWatcher( + path.join(CPXWorkspace.rootPath, ".vscode"), + true, + true, + false + ); // Reloads the config into the code if the cpx config file has changed this._watcher.onDidCreate(() => this.loadContext()); @@ -37,12 +44,14 @@ export class DeviceContext implements vscode.Disposable { } public loadContext(): Thenable { - return vscode.workspace.findFiles(CPX_CONFIG_FILE, null, 1) - .then((files) => { + return vscode.workspace.findFiles(CPX_CONFIG_FILE, null, 1).then( + files => { let cpxConfigJson: any = {}; if (files && files.length > 0) { const configFile = files[0]; - cpxConfigJson = utils.tryParseJSON(fs.readFileSync(configFile.fsPath, "utf8")); + cpxConfigJson = utils.tryParseJSON( + fs.readFileSync(configFile.fsPath, "utf8") + ); if (cpxConfigJson) { this._port = cpxConfigJson.port; this._onDidChange.fire(); @@ -54,11 +63,13 @@ export class DeviceContext implements vscode.Disposable { this._onDidChange.fire(); } return this; - }, (reason) => { + }, + reason => { this._port = null; this._onDidChange.fire(); return this; - }); + } + ); } public saveContext() { @@ -68,7 +79,9 @@ export class DeviceContext implements vscode.Disposable { const cpxConfigFile = path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE); let cpxConfigJson: any = {}; if (utils.fileExistsSync(cpxConfigFile)) { - cpxConfigJson = utils.tryParseJSON(fs.readFileSync(cpxConfigFile, "utf8")); + cpxConfigJson = utils.tryParseJSON( + fs.readFileSync(cpxConfigFile, "utf8") + ); } if (!cpxConfigJson) { // log and notify user error @@ -77,31 +90,47 @@ export class DeviceContext implements vscode.Disposable { cpxConfigJson.port = this.port; utils.mkdirRecursivelySync(path.dirname(cpxConfigFile)); - fs.writeFileSync(cpxConfigFile, JSON.stringify(cpxConfigJson, (key, value) => { - if (value === null) { - return undefined; - } - return value; - }, 4)); + fs.writeFileSync( + cpxConfigFile, + JSON.stringify( + cpxConfigJson, + (key, value) => { + if (value === null) { + return undefined; + } + return value; + }, + 4 + ) + ); } public dispose() { if (this._watcher) { this._watcher.dispose(); } - + if (this._vscodeWatcher) { this._vscodeWatcher.dispose(); } } public async initialize() { - if (CPXWorkspace.rootPath && utils.fileExistsSync(path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE))) { - vscode.window.showInformationMessage(CONSTANTS.INFO.CPX_JSON_ALREADY_GENERATED); + if ( + CPXWorkspace.rootPath && + utils.fileExistsSync( + path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE) + ) + ) { + vscode.window.showInformationMessage( + CONSTANTS.INFO.CPX_JSON_ALREADY_GENERATED + ); return; } else { if (!CPXWorkspace.rootPath) { - vscode.window.showInformationMessage(CONSTANTS.INFO.PLEASE_OPEN_FOLDER); + vscode.window.showInformationMessage( + CONSTANTS.INFO.PLEASE_OPEN_FOLDER + ); return; } } @@ -119,4 +148,4 @@ export class DeviceContext implements vscode.Disposable { this._port = value; this.saveContext(); } -} \ No newline at end of file +} diff --git a/src/extension.ts b/src/extension.ts index 0a523c3f8..888015803 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,23 +5,23 @@ import * as cp from "child_process"; import * as fs from "fs"; import * as open from "open"; import * as path from "path"; -import * as utils from "./extension_utils/utils"; import * as vscode from "vscode"; import { - CONFIG, - CONSTANTS, - CPX_CONFIG_FILE, - DialogResponses, - TelemetryEventName, - WebviewMessages, - SERVER_INFO + CONFIG, + CONSTANTS, + CPX_CONFIG_FILE, + DialogResponses, + SERVER_INFO, + TelemetryEventName, + WebviewMessages, } from "./constants"; import { CPXWorkspace } from "./cpxWorkspace"; -import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurationProvider"; +import { DebuggerCommunicationServer } from "./debuggerCommunicationServer"; +import * as utils from "./extension_utils/utils"; import { SerialMonitor } from "./serialMonitor"; +import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurationProvider"; import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; -import { DebuggerCommunicationServer } from "./debuggerCommunicationServer"; let currentFileAbsPath: string = ""; let currentTextDocument: vscode.TextDocument; @@ -37,867 +37,1002 @@ let shouldShowRunCodePopup: boolean = true; export let outChannel: vscode.OutputChannel | undefined; function loadScript(context: vscode.ExtensionContext, scriptPath: string) { - return ``; + return ``; } const setPathAndSendMessage = ( - currentPanel: vscode.WebviewPanel, - newFilePath: string + currentPanel: vscode.WebviewPanel, + newFilePath: string ) => { - currentFileAbsPath = newFilePath; - if (currentPanel) { - currentPanel.webview.postMessage({ - command: "current-file", - state: { running_file: newFilePath } - }); - } + currentFileAbsPath = newFilePath; + if (currentPanel) { + currentPanel.webview.postMessage({ + command: "current-file", + state: { running_file: newFilePath }, + }); + } }; // Extension activation export async function activate(context: vscode.ExtensionContext) { - console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED); + console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED); - telemetryAI = new TelemetryAI(context); - let currentPanel: vscode.WebviewPanel | undefined; - let childProcess: cp.ChildProcess | undefined; - let messageListener: vscode.Disposable; - let activeEditorListener: vscode.Disposable; + telemetryAI = new TelemetryAI(context); + let currentPanel: vscode.WebviewPanel | undefined; + let childProcess: cp.ChildProcess | undefined; + let messageListener: vscode.Disposable; + let activeEditorListener: vscode.Disposable; - // Add our library path to settings.json for autocomplete functionality - updatePythonExtraPaths(); + // Add our library path to settings.json for autocomplete functionality + updatePythonExtraPaths(); - pythonExecutableName = await utils.setPythonExectuableName(); + // ignore import errors so that adafruit_circuitplayground library + // doesn't trigger lint errors + updatePylintArgs(context); - await utils.checkPythonDependencies(context, pythonExecutableName) + pythonExecutableName = await utils.setPythonExectuableName(); - // Generate cpx.json - try { - utils.generateCPXConfig(); - configFileCreated = true; - } catch (err) { - console.info("Failed to create the CPX config file."); - configFileCreated = false; - } + await utils.checkPythonDependencies(context, pythonExecutableName); + // Generate cpx.json + try { + utils.generateCPXConfig(); + configFileCreated = true; + } catch (err) { + console.info("Failed to create the CPX config file."); + configFileCreated = false; + } - if (pythonExecutableName === "") { - return; - } - - if (outChannel === undefined) { - outChannel = vscode.window.createOutputChannel(CONSTANTS.NAME); - utils.logToOutputChannel(outChannel, CONSTANTS.INFO.WELCOME_OUTPUT_TAB); - } + if (pythonExecutableName === "") { + return; + } - vscode.workspace.onDidSaveTextDocument( - async (document: vscode.TextDocument) => { - await updateCurrentFileIfPython(document, currentPanel); + if (outChannel === undefined) { + outChannel = vscode.window.createOutputChannel(CONSTANTS.NAME); + utils.logToOutputChannel(outChannel, CONSTANTS.INFO.WELCOME_OUTPUT_TAB); } - ); - const openWebview = () => { - if (currentPanel) { - currentPanel.reveal(vscode.ViewColumn.Beside); - } else { - currentPanel = vscode.window.createWebviewPanel( - "adafruitSimulator", - CONSTANTS.LABEL.WEBVIEW_PANEL, - { preserveFocus: true, viewColumn: vscode.ViewColumn.Beside }, - { - // Only allow the webview to access resources in our extension's media directory - localResourceRoots: [ - vscode.Uri.file(path.join(context.extensionPath, "out")) - ], - enableScripts: true + vscode.workspace.onDidSaveTextDocument( + async (document: vscode.TextDocument) => { + await updateCurrentFileIfPython(document, currentPanel); } - ); + ); - currentPanel.webview.html = getWebviewContent(context); + const openWebview = () => { + if (currentPanel) { + currentPanel.reveal(vscode.ViewColumn.Beside); + } else { + currentPanel = vscode.window.createWebviewPanel( + "adafruitSimulator", + CONSTANTS.LABEL.WEBVIEW_PANEL, + { preserveFocus: true, viewColumn: vscode.ViewColumn.Beside }, + { + // Only allow the webview to access resources in our extension's media directory + localResourceRoots: [ + vscode.Uri.file( + path.join( + context.extensionPath, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY + ) + ), + ], + enableScripts: true, + } + ); - if (messageListener !== undefined) { - messageListener.dispose(); - const index = context.subscriptions.indexOf(messageListener); - if (index > -1) { - context.subscriptions.splice(index, 1); - } - } + currentPanel.webview.html = getWebviewContent(context); - if (activeEditorListener !== undefined) { - activeEditorListener.dispose(); - const index = context.subscriptions.indexOf(activeEditorListener); - if (index > -1) { - context.subscriptions.splice(index, 1); - } - } - - if (currentPanel) { - // Handle messages from webview - messageListener = currentPanel.webview.onDidReceiveMessage( - message => { - const messageJson = JSON.stringify(message.text); - switch (message.command) { - case WebviewMessages.BUTTON_PRESS: - // Send input to the Python process - handleButtonPressTelemetry(message.text); - console.log(`About to write ${messageJson} \n`); - if (inDebugMode && debuggerCommunicationHandler) { - debuggerCommunicationHandler.emitButtonPress(messageJson); - } else if (childProcess) { - childProcess.stdin.write(messageJson + "\n"); - } - break; - case WebviewMessages.PLAY_SIMULATOR: - console.log(`Play button ${messageJson} \n`); - if (message.text.state as boolean) { - setPathAndSendMessage( - currentPanel, - message.text.selected_file - ); - if (currentFileAbsPath) { - const foundDocument = utils.getActiveEditorFromPath( - currentFileAbsPath - ); - if (foundDocument !== undefined) { - currentTextDocument = foundDocument; - } - } - telemetryAI.trackFeatureUsage( - TelemetryEventName.COMMAND_RUN_SIMULATOR_BUTTON - ); - runSimulatorCommand(); - } else { - killProcessIfRunning(); + if (messageListener !== undefined) { + messageListener.dispose(); + const index = context.subscriptions.indexOf(messageListener); + if (index > -1) { + context.subscriptions.splice(index, 1); } - break; - case WebviewMessages.SENSOR_CHANGED: - checkForTelemetry(message.text); - console.log(`Sensor changed ${messageJson} \n`); - if (inDebugMode && debuggerCommunicationHandler) { - debuggerCommunicationHandler.emitSensorChanged(messageJson); - } else if (childProcess) { - childProcess.stdin.write(messageJson + "\n"); + } + + if (activeEditorListener !== undefined) { + activeEditorListener.dispose(); + const index = context.subscriptions.indexOf( + activeEditorListener + ); + if (index > -1) { + context.subscriptions.splice(index, 1); } - break; - case WebviewMessages.REFRESH_SIMULATOR: - console.log("Refresh button"); - runSimulatorCommand(); - break; - case WebviewMessages.SLIDER_TELEMETRY: - handleSensorTelemetry(message.text); - break; - default: - vscode.window.showInformationMessage( - CONSTANTS.ERROR.UNEXPECTED_MESSAGE + } + + if (currentPanel) { + // Handle messages from webview + messageListener = currentPanel.webview.onDidReceiveMessage( + message => { + const messageJson = JSON.stringify(message.text); + switch (message.command) { + case WebviewMessages.BUTTON_PRESS: + // Send input to the Python process + handleButtonPressTelemetry(message.text); + console.log(`About to write ${messageJson} \n`); + if ( + inDebugMode && + debuggerCommunicationHandler + ) { + debuggerCommunicationHandler.emitButtonPress( + messageJson + ); + } else if (childProcess) { + childProcess.stdin.write( + messageJson + "\n" + ); + } + break; + case WebviewMessages.PLAY_SIMULATOR: + console.log(`Play button ${messageJson} \n`); + if (message.text.state as boolean) { + setPathAndSendMessage( + currentPanel, + message.text.selected_file + ); + if (currentFileAbsPath) { + const foundDocument = utils.getActiveEditorFromPath( + currentFileAbsPath + ); + if (foundDocument !== undefined) { + currentTextDocument = foundDocument; + } + } + telemetryAI.trackFeatureUsage( + TelemetryEventName.COMMAND_RUN_SIMULATOR_BUTTON + ); + runSimulatorCommand(); + } else { + killProcessIfRunning(); + } + break; + case WebviewMessages.SENSOR_CHANGED: + checkForTelemetry(message.text); + console.log(`Sensor changed ${messageJson} \n`); + if ( + inDebugMode && + debuggerCommunicationHandler + ) { + debuggerCommunicationHandler.emitSensorChanged( + messageJson + ); + } else if (childProcess) { + childProcess.stdin.write( + messageJson + "\n" + ); + } + break; + case WebviewMessages.REFRESH_SIMULATOR: + console.log("Refresh button"); + runSimulatorCommand(); + break; + case WebviewMessages.SLIDER_TELEMETRY: + handleSensorTelemetry(message.text); + break; + default: + vscode.window.showInformationMessage( + CONSTANTS.ERROR.UNEXPECTED_MESSAGE + ); + break; + } + }, + undefined, + context.subscriptions ); - break; + + activeEditorListener = utils.addVisibleTextEditorCallback( + currentPanel, + context + ); + console.log("sent"); } - }, - undefined, - context.subscriptions - ); - activeEditorListener = utils.addVisibleTextEditorCallback( - currentPanel, - context - ); - console.log("sent"); - } + currentPanel.onDidDispose( + () => { + currentPanel = undefined; + if (debuggerCommunicationHandler) { + debuggerCommunicationHandler.setWebview(undefined); + } + killProcessIfRunning(); + if (firstTimeClosed) { + vscode.window.showInformationMessage( + CONSTANTS.INFO.FIRST_TIME_WEBVIEW + ); + firstTimeClosed = false; + } + }, + undefined, + context.subscriptions + ); + } + }; - currentPanel.onDidDispose( + // Open Simulator on the webview + const openSimulator: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.openSimulator", () => { - currentPanel = undefined; - if (debuggerCommunicationHandler) { - debuggerCommunicationHandler.setWebview(undefined); - } - killProcessIfRunning(); - if (firstTimeClosed) { - vscode.window.showInformationMessage( - CONSTANTS.INFO.FIRST_TIME_WEBVIEW - ); - firstTimeClosed = false; - } - }, - undefined, - context.subscriptions - ); - } - }; - - // Open Simulator on the webview - const openSimulator: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.openSimulator", - () => { - telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_OPEN_SIMULATOR); - telemetryAI.runWithLatencyMeasure( - openWebview, - TelemetryEventName.PERFORMANCE_OPEN_SIMULATOR - ); - } - ); - - const openTemplateFile = () => { - const fileName = "template.py"; - const filePath = __dirname + path.sep + fileName; - const file = fs.readFileSync(filePath, "utf8"); - const showNewFilePopup: boolean = vscode.workspace.getConfiguration().get(CONFIG.SHOW_NEW_FILE_POPUP); - - if (showNewFilePopup) { - vscode.window - .showInformationMessage( - CONSTANTS.INFO.NEW_FILE, - DialogResponses.DONT_SHOW, - DialogResponses.EXAMPLE_CODE, - DialogResponses.TUTORIALS - ) - .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.DONT_SHOW) { - vscode.workspace.getConfiguration().update(CONFIG.SHOW_NEW_FILE_POPUP, false); telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_DONT_SHOW + TelemetryEventName.COMMAND_OPEN_SIMULATOR ); - } else if (selection === DialogResponses.EXAMPLE_CODE) { - open(CONSTANTS.LINKS.EXAMPLE_CODE); - telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_EXAMPLE_CODE + telemetryAI.runWithLatencyMeasure( + openWebview, + TelemetryEventName.PERFORMANCE_OPEN_SIMULATOR ); - } else if (selection === DialogResponses.TUTORIALS) { - const okAction = () => { - open(CONSTANTS.LINKS.TUTORIALS); - telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_TUTORIALS - ); - }; - utils.showPrivacyModal(okAction); - } - }); - } + } + ); - // tslint:disable-next-line: ban-comma-operator - vscode.workspace - .openTextDocument({ content: file, language: "python" }) - .then((template: vscode.TextDocument) => { - vscode.window.showTextDocument(template, 1, false).then(() => { - openWebview(); - }); - }), - // tslint:disable-next-line: no-unused-expression - (error: any) => { - telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_COMMAND_NEW_FILE - ); - console.error(`Failed to open a new text document: ${error}`); - }; - }; - - const newFile: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.newFile", - () => { - telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_NEW_FILE); - telemetryAI.runWithLatencyMeasure( - openTemplateFile, - TelemetryEventName.PERFORMANCE_NEW_FILE - ); - } - ); - - const killProcessIfRunning = () => { - if (childProcess !== undefined) { - if (currentPanel) { - console.info("Sending clearing state command"); - currentPanel.webview.postMessage({ command: "reset-state" }); - } - // TODO: We need to check the process was correctly killed - childProcess.kill(); - childProcess = undefined; - } - }; - - const runSimulatorCommand = async () => { - // Prevent running new code if a debug session is active - if (inDebugMode) { - vscode.window.showErrorMessage( - CONSTANTS.ERROR.DEBUGGING_SESSION_IN_PROGESS - ); - return; - } - if (shouldShowRunCodePopup) { - const shouldExitCommand = await vscode.window - .showWarningMessage( - CONSTANTS.WARNING.ACCEPT_AND_RUN, - DialogResponses.ACCEPT_AND_RUN, - DialogResponses.CANCEL - ) - .then((selection: vscode.MessageItem | undefined) => { - let hasAccepted = true; - if (selection === DialogResponses.ACCEPT_AND_RUN) { - shouldShowRunCodePopup = false; - hasAccepted = false; - } - return hasAccepted; - }); - // Don't run users code if they don't accept - if (shouldExitCommand) { - return; - } - } + const openTemplateFile = () => { + const fileName = "template.py"; + const filePath = __dirname + path.sep + fileName; + const file = fs.readFileSync(filePath, "utf8"); + const showNewFilePopup: boolean = vscode.workspace + .getConfiguration() + .get(CONFIG.SHOW_NEW_FILE_POPUP); + + if (showNewFilePopup) { + vscode.window + .showInformationMessage( + CONSTANTS.INFO.NEW_FILE, + DialogResponses.DONT_SHOW, + DialogResponses.EXAMPLE_CODE, + DialogResponses.TUTORIALS + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.DONT_SHOW) { + vscode.workspace + .getConfiguration() + .update(CONFIG.SHOW_NEW_FILE_POPUP, false); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CLICK_DIALOG_DONT_SHOW + ); + } else if (selection === DialogResponses.EXAMPLE_CODE) { + open(CONSTANTS.LINKS.EXAMPLE_CODE); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CLICK_DIALOG_EXAMPLE_CODE + ); + } else if (selection === DialogResponses.TUTORIALS) { + const okAction = () => { + open(CONSTANTS.LINKS.TUTORIALS); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CLICK_DIALOG_TUTORIALS + ); + }; + utils.showPrivacyModal(okAction); + } + }); + } + + // tslint:disable-next-line: ban-comma-operator + vscode.workspace + .openTextDocument({ content: file, language: "python" }) + .then((template: vscode.TextDocument) => { + vscode.window.showTextDocument(template, 1, false).then(() => { + openWebview(); + }); + }), + // tslint:disable-next-line: no-unused-expression + (error: any) => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.ERROR_COMMAND_NEW_FILE + ); + console.error(`Failed to open a new text document: ${error}`); + }; + }; - openWebview(); + const newFile: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.newFile", + () => { + telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_NEW_FILE); + telemetryAI.runWithLatencyMeasure( + openTemplateFile, + TelemetryEventName.PERFORMANCE_NEW_FILE + ); + } + ); - if (!currentPanel) { - return; - } + const killProcessIfRunning = () => { + if (childProcess !== undefined) { + if (currentPanel) { + console.info("Sending clearing state command"); + currentPanel.webview.postMessage({ command: "reset-state" }); + } + // TODO: We need to check the process was correctly killed + childProcess.kill(); + childProcess = undefined; + } + }; - console.info(CONSTANTS.INFO.RUNNING_CODE); + const runSimulatorCommand = async () => { + // Prevent running new code if a debug session is active + if (inDebugMode) { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.DEBUGGING_SESSION_IN_PROGESS + ); + return; + } + if (shouldShowRunCodePopup) { + const shouldExitCommand = await vscode.window + .showWarningMessage( + CONSTANTS.WARNING.ACCEPT_AND_RUN, + DialogResponses.ACCEPT_AND_RUN, + DialogResponses.CANCEL + ) + .then((selection: vscode.MessageItem | undefined) => { + let hasAccepted = true; + if (selection === DialogResponses.ACCEPT_AND_RUN) { + shouldShowRunCodePopup = false; + hasAccepted = false; + } + return hasAccepted; + }); + // Don't run users code if they don't accept + if (shouldExitCommand) { + return; + } + } - utils.logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_SIMULATOR, true); + openWebview(); - killProcessIfRunning(); + if (!currentPanel) { + return; + } - await updateCurrentFileIfPython( - vscode.window.activeTextEditor!.document, - currentPanel - ); + console.info(CONSTANTS.INFO.RUNNING_CODE); - if (currentFileAbsPath === "") { - utils.logToOutputChannel( - outChannel, - CONSTANTS.ERROR.NO_FILE_TO_RUN, - true - ); - vscode.window.showErrorMessage( - CONSTANTS.ERROR.NO_FILE_TO_RUN, - DialogResponses.MESSAGE_UNDERSTOOD - ); - } else { - // Save on run - await currentTextDocument.save(); - - if (!currentTextDocument.fileName.endsWith(".py")) { utils.logToOutputChannel( - outChannel, - CONSTANTS.ERROR.NO_FILE_TO_RUN, - true + outChannel, + CONSTANTS.INFO.DEPLOY_SIMULATOR, + true ); - return; - } - utils.logToOutputChannel( - outChannel, - CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath) - ); - - if ( - !utils.validCodeFileName(currentFileAbsPath) && - shouldShowInvalidFileNamePopup - ) { - // to the popup - vscode.window - .showInformationMessage( - CONSTANTS.INFO.INCORRECT_FILE_NAME_FOR_SIMULATOR_POPUP, - DialogResponses.DONT_SHOW, - DialogResponses.MESSAGE_UNDERSTOOD - ) - .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.DONT_SHOW) { - shouldShowInvalidFileNamePopup = false; - telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_DONT_SHOW - ); - } - }); - } - // Activate the run webview button - currentPanel.webview.postMessage({ command: "activate-play" }); + killProcessIfRunning(); - childProcess = cp.spawn(pythonExecutableName, [ - utils.getPathToScript(context, "out", "process_user_code.py"), - currentFileAbsPath, - JSON.stringify({ enable_telemetry: utils.getTelemetryState() }) - ]); + await updateCurrentFileIfPython( + vscode.window.activeTextEditor!.document, + currentPanel + ); - let dataFromTheProcess = ""; - let oldMessage = ""; + if (currentFileAbsPath === "") { + utils.logToOutputChannel( + outChannel, + CONSTANTS.ERROR.NO_FILE_TO_RUN, + true + ); + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FILE_TO_RUN, + DialogResponses.MESSAGE_UNDERSTOOD + ); + } else { + // Save on run + await currentTextDocument.save(); + + if (!currentTextDocument.fileName.endsWith(".py")) { + utils.logToOutputChannel( + outChannel, + CONSTANTS.ERROR.NO_FILE_TO_RUN, + true + ); + return; + } + utils.logToOutputChannel( + outChannel, + CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath) + ); - // Data received from Python process - childProcess.stdout.on("data", data => { - dataFromTheProcess = data.toString(); - if (currentPanel) { - // Process the data from the process and send one state at a time - dataFromTheProcess.split("\0").forEach(message => { - if (currentPanel && message.length > 0 && message !== oldMessage) { - oldMessage = message; - let messageToWebview; - // Check the message is a JSON - try { - messageToWebview = JSON.parse(message); - // Check the JSON is a state - switch (messageToWebview.type) { - case "state": - console.log( - `Process state output = ${messageToWebview.data}` - ); - currentPanel.webview.postMessage({ - command: "set-state", - state: JSON.parse(messageToWebview.data) + if ( + !utils.validCodeFileName(currentFileAbsPath) && + shouldShowInvalidFileNamePopup + ) { + // to the popup + vscode.window + .showInformationMessage( + CONSTANTS.INFO.INCORRECT_FILE_NAME_FOR_SIMULATOR_POPUP, + DialogResponses.DONT_SHOW, + DialogResponses.MESSAGE_UNDERSTOOD + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.DONT_SHOW) { + shouldShowInvalidFileNamePopup = false; + telemetryAI.trackFeatureUsage( + TelemetryEventName.CLICK_DIALOG_DONT_SHOW + ); + } }); - break; + } - case "print": - console.log( - `Process print statement output = ${ - messageToWebview.data - }` - ); - utils.logToOutputChannel( - outChannel, - `[PRINT] ${messageToWebview.data}` - ); - break; + // Activate the run webview button + currentPanel.webview.postMessage({ command: "activate-play" }); + + childProcess = cp.spawn(pythonExecutableName, [ + utils.getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + "process_user_code.py" + ), + currentFileAbsPath, + JSON.stringify({ enable_telemetry: utils.getTelemetryState() }), + ]); + + let dataFromTheProcess = ""; + let oldMessage = ""; + + // Data received from Python process + childProcess.stdout.on("data", data => { + dataFromTheProcess = data.toString(); + if (currentPanel) { + // Process the data from the process and send one state at a time + dataFromTheProcess.split("\0").forEach(message => { + if ( + currentPanel && + message.length > 0 && + message !== oldMessage + ) { + oldMessage = message; + let messageToWebview; + // Check the message is a JSON + try { + messageToWebview = JSON.parse(message); + // Check the JSON is a state + switch (messageToWebview.type) { + case "state": + console.log( + `Process state output = ${messageToWebview.data}` + ); + currentPanel.webview.postMessage({ + command: "set-state", + state: JSON.parse( + messageToWebview.data + ), + }); + break; + + case "print": + console.log( + `Process print statement output = ${messageToWebview.data}` + ); + utils.logToOutputChannel( + outChannel, + `[PRINT] ${messageToWebview.data}` + ); + break; + + default: + console.log( + `Non-state JSON output from the process : ${messageToWebview}` + ); + break; + } + } catch (err) { + console.log( + `Non-JSON output from the process : ${message}` + ); + } + } + }); + } + }); - default: - console.log( - `Non-state JSON output from the process : ${messageToWebview}` - ); - break; + // Std error output + childProcess.stderr.on("data", data => { + console.error( + `Error from the Python process through stderr: ${data}` + ); + telemetryAI.trackFeatureUsage( + TelemetryEventName.ERROR_PYTHON_PROCESS + ); + utils.logToOutputChannel( + outChannel, + CONSTANTS.ERROR.STDERR(data), + true + ); + if (currentPanel) { + console.log("Sending clearing state command"); + currentPanel.webview.postMessage({ + command: "reset-state", + }); } - } catch (err) { - console.log(`Non-JSON output from the process : ${message}`); - } - } - }); + }); + + // When the process is done + childProcess.on("end", (code: number) => { + console.info(`Command execution exited with code: ${code}`); + }); + } + }; + + 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", + () => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.COMMAND_RUN_PALETTE + ); + runSimulatorCommand(); + } + ); + + const deployCodeToDevice = async () => { + console.info("Sending code to device"); - // Std error output - childProcess.stderr.on("data", data => { - console.error(`Error from the Python process through stderr: ${data}`); - telemetryAI.trackFeatureUsage(TelemetryEventName.ERROR_PYTHON_PROCESS); utils.logToOutputChannel( - outChannel, - CONSTANTS.ERROR.STDERR(data), - true + outChannel, + CONSTANTS.INFO.DEPLOY_DEVICE, + true ); - if (currentPanel) { - console.log("Sending clearing state command"); - currentPanel.webview.postMessage({ command: "reset-state" }); + + await updateCurrentFileIfPython( + vscode.window.activeTextEditor!.document, + currentPanel + ); + + if (currentFileAbsPath === "") { + utils.logToOutputChannel( + outChannel, + CONSTANTS.ERROR.NO_FILE_TO_RUN, + true + ); + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FILE_TO_RUN, + DialogResponses.MESSAGE_UNDERSTOOD + ); + } else if (!utils.validCodeFileName(currentFileAbsPath)) { + // Save on run + await currentTextDocument.save(); + // Output panel + utils.logToOutputChannel( + outChannel, + CONSTANTS.ERROR.INCORRECT_FILE_NAME_FOR_DEVICE, + true + ); + // Popup + vscode.window.showErrorMessage( + CONSTANTS.ERROR.INCORRECT_FILE_NAME_FOR_DEVICE_POPUP + ); + } else { + utils.logToOutputChannel( + outChannel, + CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath) + ); + + const deviceProcess = cp.spawn(pythonExecutableName, [ + utils.getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + "device.py" + ), + currentFileAbsPath, + ]); + + let dataFromTheProcess = ""; + + // Data received from Python process + deviceProcess.stdout.on("data", data => { + dataFromTheProcess = data.toString(); + console.log(`Device output = ${dataFromTheProcess}`); + let messageToWebview; + try { + messageToWebview = JSON.parse(dataFromTheProcess); + // Check the JSON is a state + switch (messageToWebview.type) { + case "complete": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SUCCESS_COMMAND_DEPLOY_DEVICE + ); + utils.logToOutputChannel( + outChannel, + CONSTANTS.INFO.DEPLOY_SUCCESS + ); + break; + + case "no-device": + telemetryAI.trackFeatureUsage( + TelemetryEventName.ERROR_DEPLOY_WITHOUT_DEVICE + ); + vscode.window + .showErrorMessage( + CONSTANTS.ERROR.NO_DEVICE, + DialogResponses.HELP + ) + .then( + ( + selection: + | vscode.MessageItem + | undefined + ) => { + if ( + selection === DialogResponses.HELP + ) { + const okAction = () => { + open(CONSTANTS.LINKS.HELP); + telemetryAI.trackFeatureUsage( + TelemetryEventName.CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE + ); + }; + utils.showPrivacyModal(okAction); + } + } + ); + break; + + default: + console.log( + `Non-state JSON output from the process : ${messageToWebview}` + ); + break; + } + } catch (err) { + console.log( + `Non-JSON output from the process : ${dataFromTheProcess}` + ); + } + }); + + // Std error output + deviceProcess.stderr.on("data", data => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS, + { error: `${data}` } + ); + console.error( + `Error from the Python device process through stderr: ${data}` + ); + utils.logToOutputChannel( + outChannel, + `[ERROR] ${data} \n`, + true + ); + }); + + // When the process is done + deviceProcess.on("end", (code: number) => { + console.info(`Command execution exited with code: ${code}`); + }); } - }); + }; - // When the process is done - childProcess.on("end", (code: number) => { - console.info(`Command execution exited with code: ${code}`); - }); - } - }; + const runDevice: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.runDevice", + () => { + telemetryAI.trackFeatureUsage( + TelemetryEventName.COMMAND_DEPLOY_DEVICE + ); + telemetryAI.runWithLatencyMeasure( + deployCodeToDevice, + TelemetryEventName.PERFORMANCE_DEPLOY_DEVICE + ); + } + ); - 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", - () => { - telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_RUN_PALETTE); - runSimulatorCommand(); + let serialMonitor: SerialMonitor | undefined; + if (configFileCreated) { + serialMonitor = SerialMonitor.getInstance(); + context.subscriptions.push(serialMonitor); } - ); - const deployCodeToDevice = async () => { - console.info("Sending code to device"); - - utils.logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_DEVICE, true); + const selectSerialPort: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.selectSerialPort", + () => { + if (serialMonitor) { + telemetryAI.runWithLatencyMeasure(() => { + serialMonitor.selectSerialPort(null, null); + }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CHOOSE_PORT); + } else { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FOLDER_OPENED + ); + console.info("Serial monitor is not defined."); + } + } + ); - await updateCurrentFileIfPython( - vscode.window.activeTextEditor!.document, - currentPanel + const openSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.openSerialMonitor", + () => { + if (serialMonitor) { + telemetryAI.runWithLatencyMeasure( + serialMonitor.openSerialMonitor.bind(serialMonitor), + TelemetryEventName.COMMAND_SERIAL_MONITOR_OPEN + ); + } else { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FOLDER_OPENED + ); + console.info("Serial monitor is not defined."); + } + } ); - if (currentFileAbsPath === "") { - utils.logToOutputChannel( - outChannel, - CONSTANTS.ERROR.NO_FILE_TO_RUN, - true - ); - vscode.window.showErrorMessage( - CONSTANTS.ERROR.NO_FILE_TO_RUN, - DialogResponses.MESSAGE_UNDERSTOOD - ); - } else if (!utils.validCodeFileName(currentFileAbsPath)) { - // Save on run - await currentTextDocument.save(); - // Output panel - utils.logToOutputChannel( - outChannel, - CONSTANTS.ERROR.INCORRECT_FILE_NAME_FOR_DEVICE, - true - ); - // Popup - vscode.window.showErrorMessage( - CONSTANTS.ERROR.INCORRECT_FILE_NAME_FOR_DEVICE_POPUP - ); - } else { - utils.logToOutputChannel( - outChannel, - CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath) - ); - - const deviceProcess = cp.spawn(pythonExecutableName, [ - utils.getPathToScript(context, "out", "device.py"), - currentFileAbsPath - ]); - - let dataFromTheProcess = ""; - - // Data received from Python process - deviceProcess.stdout.on("data", data => { - dataFromTheProcess = data.toString(); - console.log(`Device output = ${dataFromTheProcess}`); - let messageToWebview; - try { - messageToWebview = JSON.parse(dataFromTheProcess); - // Check the JSON is a state - switch (messageToWebview.type) { - case "complete": - telemetryAI.trackFeatureUsage( - TelemetryEventName.SUCCESS_COMMAND_DEPLOY_DEVICE - ); - utils.logToOutputChannel( - outChannel, - CONSTANTS.INFO.DEPLOY_SUCCESS - ); - break; - - case "no-device": - telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_DEPLOY_WITHOUT_DEVICE - ); - vscode.window - .showErrorMessage( - CONSTANTS.ERROR.NO_DEVICE, - DialogResponses.HELP - ) - .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.HELP) { - const okAction = () => { - open(CONSTANTS.LINKS.HELP); - telemetryAI.trackFeatureUsage( - TelemetryEventName.CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE - ); - }; - utils.showPrivacyModal(okAction); - } - }); - break; - - default: - console.log( - `Non-state JSON output from the process : ${messageToWebview}` - ); - break; - } - } catch (err) { - console.log( - `Non-JSON output from the process : ${dataFromTheProcess}` - ); + const changeBaudRate: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.changeBaudRate", + () => { + if (serialMonitor) { + telemetryAI.runWithLatencyMeasure( + serialMonitor.changeBaudRate.bind(serialMonitor), + TelemetryEventName.COMMAND_SERIAL_MONITOR_BAUD_RATE + ); + } else { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FOLDER_OPENED + ); + console.info("Serial monitor is not defined."); + } } - }); + ); - // Std error output - deviceProcess.stderr.on("data", data => { - telemetryAI.trackFeatureUsage( - TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS, - { error: `${data}` } - ); - console.error( - `Error from the Python device process through stderr: ${data}` - ); - utils.logToOutputChannel(outChannel, `[ERROR] ${data} \n`, true); - }); + const closeSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( + "deviceSimulatorExpress.closeSerialMonitor", + (port, showWarning = true) => { + if (serialMonitor) { + telemetryAI.runWithLatencyMeasure(() => { + serialMonitor.closeSerialMonitor(port, showWarning); + }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CLOSE); + } else { + vscode.window.showErrorMessage( + CONSTANTS.ERROR.NO_FOLDER_OPENED + ); + console.info("Serial monitor is not defined."); + } + } + ); - // When the process is done - deviceProcess.on("end", (code: number) => { - console.info(`Command execution exited with code: ${code}`); - }); - } - }; - - const runDevice: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.runDevice", - () => { - telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_DEPLOY_DEVICE); - telemetryAI.runWithLatencyMeasure( - deployCodeToDevice, - TelemetryEventName.PERFORMANCE_DEPLOY_DEVICE - ); - } - ); - - let serialMonitor: SerialMonitor | undefined; - if (configFileCreated) { - serialMonitor = SerialMonitor.getInstance(); - context.subscriptions.push(serialMonitor); - } - - const selectSerialPort: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.selectSerialPort", - () => { - if (serialMonitor) { - telemetryAI.runWithLatencyMeasure(() => { - serialMonitor.selectSerialPort(null, null); - }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CHOOSE_PORT); - } else { - vscode.window.showErrorMessage(CONSTANTS.ERROR.NO_FOLDER_OPENED); - console.info("Serial monitor is not defined."); - } - } - ); - - const openSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.openSerialMonitor", - () => { - if (serialMonitor) { - telemetryAI.runWithLatencyMeasure( - serialMonitor.openSerialMonitor.bind(serialMonitor), - TelemetryEventName.COMMAND_SERIAL_MONITOR_OPEN - ); - } else { - vscode.window.showErrorMessage(CONSTANTS.ERROR.NO_FOLDER_OPENED); - console.info("Serial monitor is not defined."); - } - } - ); - - const changeBaudRate: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.changeBaudRate", - () => { - if (serialMonitor) { - telemetryAI.runWithLatencyMeasure( - serialMonitor.changeBaudRate.bind(serialMonitor), - TelemetryEventName.COMMAND_SERIAL_MONITOR_BAUD_RATE - ); - } else { - vscode.window.showErrorMessage(CONSTANTS.ERROR.NO_FOLDER_OPENED); - console.info("Serial monitor is not defined."); - } - } - ); - - const closeSerialMonitor: vscode.Disposable = vscode.commands.registerCommand( - "deviceSimulatorExpress.closeSerialMonitor", - (port, showWarning = true) => { - if (serialMonitor) { - telemetryAI.runWithLatencyMeasure(() => { - serialMonitor.closeSerialMonitor(port, showWarning); - }, TelemetryEventName.COMMAND_SERIAL_MONITOR_CLOSE); - } else { - vscode.window.showErrorMessage(CONSTANTS.ERROR.NO_FOLDER_OPENED); - console.info("Serial monitor is not defined."); - } + UsbDetector.getInstance().initialize(context.extensionPath); + UsbDetector.getInstance().startListening(); + + if ( + CPXWorkspace.rootPath && + (utils.fileExistsSync( + path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE) + ) || + vscode.window.activeTextEditor) + ) { + (() => { + if (!SerialMonitor.getInstance().initialized) { + SerialMonitor.getInstance().initialize(); + } + })(); } - ); - - UsbDetector.getInstance().initialize(context.extensionPath); - UsbDetector.getInstance().startListening(); - - if ( - CPXWorkspace.rootPath && - (utils.fileExistsSync(path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE)) || - vscode.window.activeTextEditor) - ) { - (() => { - if (!SerialMonitor.getInstance().initialized) { - SerialMonitor.getInstance().initialize(); - } - })(); - } - - // Debugger configuration - const simulatorDebugConfiguration = new SimulatorDebugConfigurationProvider( - utils.getPathToScript(context, "out/", "debug_user_code.py") - ); - - // 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; - } - debuggerCommunicationHandler = new DebuggerCommunicationServer( - currentPanel, - utils.getServerPortConfig() - ); - openWebview(); - if (currentPanel) { - debuggerCommunicationHandler.setWebview(currentPanel); - currentPanel.webview.postMessage({ command: "activate-play" }); + // Debugger configuration + const simulatorDebugConfiguration = new SimulatorDebugConfigurationProvider( + utils.getPathToScript(context, "out/", "debug_user_code.py") + ); + + // 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; + } + + debuggerCommunicationHandler = new DebuggerCommunicationServer( + currentPanel, + utils.getServerPortConfig() + ); + openWebview(); + if (currentPanel) { + debuggerCommunicationHandler.setWebview(currentPanel); + currentPanel.webview.postMessage({ + command: "activate-play", + }); + } + } catch (err) { + if (err.message === SERVER_INFO.ERROR_CODE_INIT_SERVER) { + console.error( + `Error trying to init the server on port ${utils.getServerPortConfig()}` + ); + vscode.window.showErrorMessage( + CONSTANTS.ERROR.DEBUGGER_SERVER_INIT_FAILED( + utils.getServerPortConfig() + ) + ); + } + } } - } catch (err) { - if (err.message === SERVER_INFO.ERROR_CODE_INIT_SERVER) { - console.error( - `Error trying to init the server on port ${utils.getServerPortConfig()}` - ); - vscode.window.showErrorMessage( - CONSTANTS.ERROR.DEBUGGER_SERVER_INIT_FAILED( - utils.getServerPortConfig() - ) - ); + }); + + // 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 (currentPanel) { + currentPanel.webview.postMessage({ command: "reset-state" }); + } } - } - } - }); - - // 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 (currentPanel) { - currentPanel.webview.postMessage({ command: "reset-state" }); - } - } - }); - - context.subscriptions.push( - changeBaudRate, - closeSerialMonitor, - openSerialMonitor, - openSimulator, - newFile, - runSimulator, - runSimulatorEditorButton, - runDevice, - selectSerialPort, - vscode.debug.registerDebugConfigurationProvider( - CONSTANTS.DEBUG_CONFIGURATION_TYPE, - simulatorDebugConfiguration - ), - debugSessionsStarted, - debugSessionStopped - ); + }); + + context.subscriptions.push( + changeBaudRate, + closeSerialMonitor, + openSerialMonitor, + openSimulator, + newFile, + runSimulator, + runSimulatorEditorButton, + runDevice, + selectSerialPort, + vscode.debug.registerDebugConfigurationProvider( + CONSTANTS.DEBUG_CONFIGURATION_TYPE, + simulatorDebugConfiguration + ), + debugSessionsStarted, + debugSessionStopped + ); } const getActivePythonFile = () => { - const editors: vscode.TextEditor[] = vscode.window.visibleTextEditors; - const activeEditor = editors.find( - editor => editor.document.languageId === "python" - ); - if (activeEditor) { - currentTextDocument = activeEditor.document; - } - return activeEditor ? activeEditor.document.fileName : ""; + const editors: vscode.TextEditor[] = vscode.window.visibleTextEditors; + const activeEditor = editors.find( + editor => editor.document.languageId === "python" + ); + if (activeEditor) { + currentTextDocument = activeEditor.document; + } + return activeEditor ? activeEditor.document.fileName : ""; }; const updateCurrentFileIfPython = async ( - activeTextDocument: vscode.TextDocument | undefined, - currentPanel: vscode.WebviewPanel + activeTextDocument: vscode.TextDocument | undefined, + currentPanel: vscode.WebviewPanel ) => { - if (activeTextDocument && activeTextDocument.languageId === "python") { - setPathAndSendMessage(currentPanel, activeTextDocument.fileName); - currentTextDocument = activeTextDocument; - } else if (currentFileAbsPath === "") { - setPathAndSendMessage(currentPanel, getActivePythonFile() || ""); - } - if ( - currentTextDocument && - utils.getActiveEditorFromPath(currentTextDocument.fileName) === undefined - ) { - await vscode.window.showTextDocument( - currentTextDocument, - vscode.ViewColumn.One - ); - } + if (activeTextDocument && activeTextDocument.languageId === "python") { + setPathAndSendMessage(currentPanel, activeTextDocument.fileName); + currentTextDocument = activeTextDocument; + } else if (currentFileAbsPath === "") { + setPathAndSendMessage(currentPanel, getActivePythonFile() || ""); + } + if ( + currentTextDocument && + utils.getActiveEditorFromPath(currentTextDocument.fileName) === + undefined + ) { + await vscode.window.showTextDocument( + currentTextDocument, + vscode.ViewColumn.One + ); + } }; const handleButtonPressTelemetry = (buttonState: any) => { - if (buttonState["button_a"] && buttonState["button_b"]) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_AB); - } else if (buttonState["button_a"]) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_A); - } else if (buttonState["button_b"]) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_B); - } else if (buttonState["switch"]) { - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SWITCH); - } + if (buttonState.button_a && buttonState.button_b) { + telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_AB); + } else if (buttonState.button_a) { + telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_A); + } else if (buttonState.button_b) { + telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_BUTTON_B); + } else if (buttonState.switch) { + telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SWITCH); + } }; const handleSensorTelemetry = (sensor: string) => { - switch (sensor) { - case "temperature": - telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_TEMPERATURE_SENSOR - ); - break; - case "light": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_LIGHT_SENSOR); - break; - case "motion_x": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_MOTION_SENSOR); - break; - case "motion_y": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_MOTION_SENSOR); - break; - case "motion_z": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_MOTION_SENSOR); - break; - case "shake": - telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SHAKE); - break; - case "touch": - telemetryAI.trackFeatureUsage( - TelemetryEventName.SIMULATOR_CAPACITIVE_TOUCH - ); - break; - } + switch (sensor) { + case "temperature": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_TEMPERATURE_SENSOR + ); + break; + case "light": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_LIGHT_SENSOR + ); + break; + case "motion_x": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_MOTION_SENSOR + ); + break; + case "motion_y": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_MOTION_SENSOR + ); + break; + case "motion_z": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_MOTION_SENSOR + ); + break; + case "shake": + telemetryAI.trackFeatureUsage(TelemetryEventName.SIMULATOR_SHAKE); + break; + case "touch": + telemetryAI.trackFeatureUsage( + TelemetryEventName.SIMULATOR_CAPACITIVE_TOUCH + ); + break; + } }; const checkForTelemetry = (sensorState: any) => { - if (sensorState["shake"]) { - handleSensorTelemetry("shake"); - } else if (sensorState["touch"]) { - handleSensorTelemetry("touch"); - } + if (sensorState.shake) { + handleSensorTelemetry("shake"); + } else if (sensorState.touch) { + handleSensorTelemetry("touch"); + } }; const updatePythonExtraPaths = () => { - const pathToLib: string = __dirname; - const currentExtraPaths: string[] = - vscode.workspace.getConfiguration().get("python.autoComplete.extraPaths") || - []; - if (!currentExtraPaths.includes(pathToLib)) { - currentExtraPaths.push(pathToLib); - } - vscode.workspace - .getConfiguration() - .update( - "python.autoComplete.extraPaths", - currentExtraPaths, - vscode.ConfigurationTarget.Global + updateConfigLists( + "python.autoComplete.extraPaths", + [__dirname], + vscode.ConfigurationTarget.Global ); }; +const updatePylintArgs = (context: vscode.ExtensionContext) => { + const outPath: string = 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}\"])`, + ], + 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[], + scope: vscode.ConfigurationTarget +) => { + // function for adding elements to configuration arrays + const currentExtraItems: string[] = + vscode.workspace.getConfiguration().get(section) || []; + const extraItemsSet: Set = new Set( + currentExtraItems.concat(newItems) + ); + + vscode.workspace + .getConfiguration() + .update(section, Array.from(extraItemsSet), scope); +}; + function getWebviewContent(context: vscode.ExtensionContext) { - return ` + return ` @@ -918,7 +1053,7 @@ function getWebviewContent(context: vscode.ExtensionContext) { // this method is called when your extension is deactivated export async function deactivate() { - const monitor: SerialMonitor = SerialMonitor.getInstance(); - await monitor.closeSerialMonitor(null, false); - UsbDetector.getInstance().stopListening(); + const monitor: SerialMonitor = SerialMonitor.getInstance(); + await monitor.closeSerialMonitor(null, false); + UsbDetector.getInstance().stopListening(); } diff --git a/src/extension_utils/dependencyChecker.ts b/src/extension_utils/dependencyChecker.ts index 4881dc8e8..de18806cc 100644 --- a/src/extension_utils/dependencyChecker.ts +++ b/src/extension_utils/dependencyChecker.ts @@ -1,13 +1,12 @@ -import { CONSTANTS } from "../constants"; import * as cp from "child_process"; +import * as compareVersions from "compare-versions"; import * as os from "os"; -import * as compareVersions from 'compare-versions'; import * as util from "util"; +import { CONSTANTS } from "../constants"; const exec = util.promisify(cp.exec); interface IPayloadResponse { payload: IDependency; - } interface IDependency { @@ -16,22 +15,29 @@ interface IDependency { } const PYTHON3_REGEX = RegExp("^(Python )(3\\.[0-9]+\\.[0-9]+)"); -const MINIMUM_PYTHON_VERSION = "3.7.0" +const MINIMUM_PYTHON_VERSION = "3.7.0"; export class DependencyChecker { - constructor() { } + constructor() {} - public async checkDependency(dependencyName: string): Promise { + 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) + 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) + await this.runCommandVersion( + CONSTANTS.DEPENDENCY_CHECKER.PYTHON, + MINIMUM_PYTHON_VERSION + ) ) { state = true; dependencyName = CONSTANTS.DEPENDENCY_CHECKER.PYTHON; @@ -42,20 +48,25 @@ export class DependencyChecker { return { payload: { dependency: dependencyName, - installed: state - } + installed: state, + }, }; } - private async runCommandVersion(command: string, versionDependency?: string) { + 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; + installed = matches + ? compareVersions(matches[2], versionDependency) >= 0 + : false; } else { - installed = true + installed = true; } } catch (err) { installed = false; diff --git a/src/extension_utils/utils.ts b/src/extension_utils/utils.ts index 546bb8538..a9c61a37f 100644 --- a/src/extension_utils/utils.ts +++ b/src/extension_utils/utils.ts @@ -1,114 +1,116 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import * as cp from "child_process"; import * as fs from "fs"; -import * as path from "path"; +import * as open from "open"; import * as os from "os"; -import { DependencyChecker } from "./dependencyChecker"; -import { DeviceContext } from "../deviceContext"; +import * as path from "path"; +import * as util from "util"; import * as vscode from "vscode"; import { - CONFIG, - CONSTANTS, - CPX_CONFIG_FILE, - DialogResponses, - USER_CODE_NAMES, - SERVER_INFO + CONFIG, + CONSTANTS, + CPX_CONFIG_FILE, + DialogResponses, + SERVER_INFO, + USER_CODE_NAMES, } from "../constants"; import { CPXWorkspace } from "../cpxWorkspace"; -import * as cp from "child_process"; -import * as util from "util"; +import { DeviceContext } from "../deviceContext"; +import { DependencyChecker } from "./dependencyChecker"; + const exec = util.promisify(cp.exec); // tslint:disable-next-line: export-name export const getPathToScript = ( - context: vscode.ExtensionContext, - folderName: string, - fileName: string + context: vscode.ExtensionContext, + folderName: string, + fileName: string ) => { - const onDiskPath = vscode.Uri.file( - path.join(context.extensionPath, folderName, fileName) - ); - const scriptPath = onDiskPath.with({ scheme: "vscode-resource" }); - return scriptPath.fsPath; + const onDiskPath = vscode.Uri.file( + path.join(context.extensionPath, folderName, fileName) + ); + const scriptPath = onDiskPath.with({ scheme: "vscode-resource" }); + return scriptPath.fsPath; }; export const validCodeFileName = (filePath: string) => { - return ( - filePath.endsWith(USER_CODE_NAMES.CODE_PY) || - filePath.endsWith(USER_CODE_NAMES.MAIN_PY) - ); + return ( + filePath.endsWith(USER_CODE_NAMES.CODE_PY) || + filePath.endsWith(USER_CODE_NAMES.MAIN_PY) + ); }; export const showPrivacyModal = (okAction: () => void) => { - vscode.window - .showInformationMessage( - `${CONSTANTS.INFO.THIRD_PARTY_WEBSITE}: ${CONSTANTS.LINKS.PRIVACY}`, - DialogResponses.AGREE_AND_PROCEED, - DialogResponses.CANCEL - ) - .then((privacySelection: vscode.MessageItem | undefined) => { - if (privacySelection === DialogResponses.AGREE_AND_PROCEED) { - okAction(); - } else if (privacySelection === DialogResponses.CANCEL) { - // do nothing - } - }); + vscode.window + .showInformationMessage( + `${CONSTANTS.INFO.THIRD_PARTY_WEBSITE}: ${CONSTANTS.LINKS.PRIVACY}`, + DialogResponses.AGREE_AND_PROCEED, + DialogResponses.CANCEL + ) + .then((privacySelection: vscode.MessageItem | undefined) => { + if (privacySelection === DialogResponses.AGREE_AND_PROCEED) { + okAction(); + } else if (privacySelection === DialogResponses.CANCEL) { + // do nothing + } + }); }; export const logToOutputChannel = ( - outChannel: vscode.OutputChannel | undefined, - message: string, - show: boolean = false + outChannel: vscode.OutputChannel | undefined, + message: string, + show: boolean = false ): void => { - if (outChannel) { - if (show) { - outChannel.show(true); + if (outChannel) { + if (show) { + outChannel.show(true); + } + outChannel.append(message); } - outChannel.append(message); - } }; export function tryParseJSON(jsonString: string): any | boolean { - try { - const jsonObj = JSON.parse(jsonString); - if (jsonObj && typeof jsonObj === "object") { - return jsonObj; - } - } catch (exception) {} + try { + const jsonObj = JSON.parse(jsonString); + if (jsonObj && typeof jsonObj === "object") { + return jsonObj; + } + } catch (exception) {} - return false; + return false; } export function fileExistsSync(filePath: string): boolean { - try { - return fs.statSync(filePath).isFile(); - } catch (error) { - return false; - } + try { + return fs.statSync(filePath).isFile(); + } catch (error) { + return false; + } } export function mkdirRecursivelySync(dirPath: string): void { - if (directoryExistsSync(dirPath)) { - return; - } - const dirname = path.dirname(dirPath); - if (path.normalize(dirname) === path.normalize(dirPath)) { - fs.mkdirSync(dirPath); - } else if (directoryExistsSync(dirname)) { - fs.mkdirSync(dirPath); - } else { - mkdirRecursivelySync(dirname); - fs.mkdirSync(dirPath); - } + if (directoryExistsSync(dirPath)) { + return; + } + const dirname = path.dirname(dirPath); + if (path.normalize(dirname) === path.normalize(dirPath)) { + fs.mkdirSync(dirPath); + } else if (directoryExistsSync(dirname)) { + fs.mkdirSync(dirPath); + } else { + mkdirRecursivelySync(dirname); + fs.mkdirSync(dirPath); + } } export function directoryExistsSync(dirPath: string): boolean { - try { - return fs.statSync(dirPath).isDirectory(); - } catch (e) { - return false; - } + try { + return fs.statSync(dirPath).isDirectory(); + } catch (e) { + return false; + } } /** @@ -117,204 +119,257 @@ export function directoryExistsSync(dirPath: string): boolean { * The padding is applied from the start (left) of the current string. */ export function padStart( - sourceString: string, - targetLength: number, - padString?: string + sourceString: string, + targetLength: number, + padString?: string ): string { - if (!sourceString) { - return sourceString; - } + if (!sourceString) { + return sourceString; + } - if (!(String.prototype as any).padStart) { - // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js - padString = String(padString || " "); - if (sourceString.length > targetLength) { - return sourceString; + if (!(String.prototype as any).padStart) { + // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js + padString = String(padString || " "); + if (sourceString.length > targetLength) { + return sourceString; + } else { + targetLength = targetLength - sourceString.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed + } + return padString.slice(0, targetLength) + sourceString; + } } else { - targetLength = targetLength - sourceString.length; - if (targetLength > padString.length) { - padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed - } - return padString.slice(0, targetLength) + sourceString; + return (sourceString as any).padStart(targetLength, padString); } - } else { - return (sourceString as any).padStart(targetLength, padString); - } } export function convertToHex(num: number, width = 0): string { - return padStart(num.toString(16), width, "0"); + return padStart(num.toString(16), width, "0"); } export function generateCPXConfig(): void { - const deviceContext: DeviceContext = DeviceContext.getInstance(); - const cpxJson = { - port: deviceContext.port - }; - const cpxConfigFilePath: string = path.join( - CPXWorkspace.rootPath, - CPX_CONFIG_FILE - ); - mkdirRecursivelySync(path.dirname(cpxConfigFilePath)); - fs.writeFileSync(cpxConfigFilePath, JSON.stringify(cpxJson, null, 4)); + const deviceContext: DeviceContext = DeviceContext.getInstance(); + const cpxJson = { + port: deviceContext.port, + }; + const cpxConfigFilePath: string = path.join( + CPXWorkspace.rootPath, + CPX_CONFIG_FILE + ); + 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; + 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; + 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 { - 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); - } - }); - } + // Find our what command is the PATH for python + let executableName: string = ""; + const dependencyCheck = await checkPythonDependency(); + if (dependencyCheck.installed) { + executableName = dependencyCheck.dependency; + } else { + 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); + } + }); + } - return executableName; + return executableName; }; export const addVisibleTextEditorCallback = ( - currentPanel: vscode.WebviewPanel, - context: vscode.ExtensionContext + currentPanel: vscode.WebviewPanel, + context: vscode.ExtensionContext ): vscode.Disposable => { - const initialPythonEditors = filterForPythonFiles( - vscode.window.visibleTextEditors - ); - currentPanel.webview.postMessage({ - command: "visible-editors", - state: { activePythonEditors: initialPythonEditors } - }); - return vscode.window.onDidChangeVisibleTextEditors( - (textEditors: vscode.TextEditor[]) => { - const activePythonEditors = filterForPythonFiles(textEditors); - currentPanel.webview.postMessage({ + const initialPythonEditors = filterForPythonFiles( + vscode.window.visibleTextEditors + ); + currentPanel.webview.postMessage({ command: "visible-editors", - state: { activePythonEditors } - }); - }, - {}, - context.subscriptions - ); + state: { activePythonEditors: initialPythonEditors }, + }); + return vscode.window.onDidChangeVisibleTextEditors( + (textEditors: vscode.TextEditor[]) => { + const activePythonEditors = filterForPythonFiles(textEditors); + currentPanel.webview.postMessage({ + command: "visible-editors", + state: { activePythonEditors }, + }); + }, + {}, + context.subscriptions + ); }; export const filterForPythonFiles = (textEditors: vscode.TextEditor[]) => { - return textEditors - .filter(editor => editor.document.languageId === "python") - .map(editor => editor.document.fileName); + return textEditors + .filter(editor => editor.document.languageId === "python") + .map(editor => editor.document.fileName); }; export const getActiveEditorFromPath = ( - filePath: string + filePath: string ): vscode.TextDocument => { - const activeEditor = vscode.window.visibleTextEditors.find( - (editor: vscode.TextEditor) => editor.document.fileName === filePath - ); - return activeEditor ? activeEditor.document : undefined; + const activeEditor = vscode.window.visibleTextEditors.find( + (editor: vscode.TextEditor) => editor.document.fileName === filePath + ); + return activeEditor ? activeEditor.document : undefined; }; export const getServerPortConfig = (): number => { - // tslint:disable: no-backbone-get-set-outside-model prefer-type-cast - if ( - vscode.workspace - .getConfiguration() - .has(SERVER_INFO.SERVER_PORT_CONFIGURATION) - ) { - return vscode.workspace - .getConfiguration() - .get(SERVER_INFO.SERVER_PORT_CONFIGURATION) as number; - } - return SERVER_INFO.DEFAULT_SERVER_PORT; + // tslint:disable: no-backbone-get-set-outside-model prefer-type-cast + if ( + vscode.workspace + .getConfiguration() + .has(SERVER_INFO.SERVER_PORT_CONFIGURATION) + ) { + return vscode.workspace + .getConfiguration() + .get(SERVER_INFO.SERVER_PORT_CONFIGURATION) as number; + } + return SERVER_INFO.DEFAULT_SERVER_PORT; }; export const checkConfig = (configName: string): boolean => { - return vscode.workspace.getConfiguration().get(configName) === true; + return vscode.workspace.getConfiguration().get(configName) === true; }; -export const checkPythonDependencies = async (context: vscode.ExtensionContext, pythonExecutable: string) => { - let hasInstalledDependencies: boolean = false; - if (checkPipDependency() && checkPythonDependency()) { - if (checkConfig(CONFIG.SHOW_DEPENDENCY_INSTALL)) { - hasInstalledDependencies = await promptInstallPythonDependencies(context, pythonExecutable); - if (hasInstalledDependencies) { - await vscode.workspace - .getConfiguration() - .update(CONFIG.SHOW_DEPENDENCY_INSTALL, false); - } +export const checkPythonDependencies = async ( + context: vscode.ExtensionContext, + pythonExecutable: string +) => { + let hasInstalledDependencies: boolean = false; + const pathToLibs: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + CONSTANTS.FILESYSTEM.PYTHON_LIBS_DIR + ); + 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 + )); + } + } else { + hasInstalledDependencies = false; } - } else { - hasInstalledDependencies = false; - } - return hasInstalledDependencies; + return hasInstalledDependencies; }; -export const promptInstallPythonDependencies = (context: vscode.ExtensionContext, pythonExecutable: string) => { - return vscode.window.showInformationMessage( - CONSTANTS.INFO.INSTALL_PYTHON_DEPENDENCIES, - DialogResponses.YES, - DialogResponses.NO) - .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.YES) { - return installPythonDependencies(context, pythonExecutable); - } 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); - } else { - return false; - } - }) - } - }); +export const promptInstallPythonDependencies = ( + context: vscode.ExtensionContext, + pythonExecutable: string, + pathToLibs: string +) => { + return vscode.window + .showInformationMessage( + CONSTANTS.INFO.INSTALL_PYTHON_DEPENDENCIES, + DialogResponses.YES, + DialogResponses.NO + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.YES) { + return installPythonDependencies( + context, + pythonExecutable, + pathToLibs + ); + } 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; + } + }); + } + }); }; export const getTelemetryState = () => { - return vscode.workspace - .getConfiguration() - .get("telemetry.enableTelemetry", true); + return vscode.workspace + .getConfiguration() + .get("telemetry.enableTelemetry", true); }; -export const installPythonDependencies = async (context: vscode.ExtensionContext, pythonExecutable: string) => { - let installed: boolean = false; - try { - vscode.window.showInformationMessage(CONSTANTS.INFO.INSTALLING_PYTHON_DEPENDENCIES); - const requirementsPath: string = getPathToScript(context, "out", "requirements.txt"); - const pathToLibs: string = getPathToScript(context, "out", "python_libs"); - const { stdout } = await exec(`${pythonExecutable} -m pip install -r ${requirementsPath} -t ${pathToLibs}`); - console.info(stdout); - installed = true; - vscode.window.showInformationMessage(CONSTANTS.INFO.SUCCESSFUL_INSTALL); - } catch (err) { - console.error(err); - installed = false; - } - return installed -} +export const installPythonDependencies = async ( + context: vscode.ExtensionContext, + pythonExecutable: string, + pathToLibs: string +) => { + let installed: boolean = false; + try { + vscode.window.showInformationMessage( + CONSTANTS.INFO.INSTALLING_PYTHON_DEPENDENCIES + ); + + const requirementsPath: string = getPathToScript( + context, + CONSTANTS.FILESYSTEM.OUTPUT_DIRECTORY, + "requirements.txt" + ); + + // run command to download dependencies to out/python_libs + const { stdout } = await exec( + `${pythonExecutable} -m pip install -r ${requirementsPath} -t ${pathToLibs}` + ); + console.info(stdout); + installed = true; + + vscode.window.showInformationMessage(CONSTANTS.INFO.SUCCESSFUL_INSTALL); + } catch (err) { + vscode.window + .showErrorMessage( + CONSTANTS.ERROR.DEPENDENCY_DOWNLOAD_ERROR, + DialogResponses.READ_INSTALL_MD + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.READ_INSTALL_MD) { + open(CONSTANTS.LINKS.INSTALL); + } + }); + + console.error(err); + installed = false; + } + return installed; +}; diff --git a/src/process_user_code.py b/src/process_user_code.py index ad2fcac7b..1991f9816 100644 --- a/src/process_user_code.py +++ b/src/process_user_code.py @@ -13,8 +13,7 @@ # 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) +abs_path_to_lib = os.path.join(abs_path_to_parent_dir, CONSTANTS.PYTHON_LIBS_DIR) sys.path.insert(0, abs_path_to_lib) read_val = "" @@ -25,8 +24,7 @@ # Insert absolute path to Adafruit library 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.LIBRARY_NAME) +abs_path_to_lib = os.path.join(abs_path_to_parent_dir, CONSTANTS.LIBRARY_NAME) sys.path.insert(0, abs_path_to_lib) # This import must happen after the sys.path is modified @@ -34,10 +32,8 @@ from adafruit_circuitplayground.telemetry import telemetry_py - # Handle User Inputs Thread class UserInput(threading.Thread): - def __init__(self): threading.Thread.__init__(self) @@ -49,11 +45,11 @@ def run(self): 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]) + event, cpx._Express__state[event] + ) except Exception as e: - print(CONSTANTS.ERROR_SENDING_EVENT, - e, file=sys.stderr, flush=True) + print(CONSTANTS.ERROR_SENDING_EVENT, e, file=sys.stderr, flush=True) user_input = UserInput() @@ -66,7 +62,7 @@ def handle_user_prints(): global user_stdout while True: if user_stdout.getvalue(): - message = {'type': 'print', 'data': user_stdout.getvalue()} + message = {"type": "print", "data": user_stdout.getvalue()} print(json.dumps(message), file=sys.__stdout__, flush=True) user_stdout.truncate(0) user_stdout.seek(0) @@ -84,25 +80,24 @@ def execute_user_code(abs_path_to_code_file): with open(abs_path_to_code_file) as user_code_file: user_code = user_code_file.read() try: - codeObj = compile(user_code, abs_path_to_code_file, - CONSTANTS.EXEC_COMMAND) + codeObj = compile(user_code, abs_path_to_code_file, CONSTANTS.EXEC_COMMAND) exec(codeObj, {}) sys.stdout.flush() except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() errorMessage = CONSTANTS.ERROR_TRACEBACK - stackTrace = traceback.format_exception( - exc_type, exc_value, exc_traceback) + stackTrace = traceback.format_exception(exc_type, exc_value, exc_traceback) for frameIndex in range(2, len(stackTrace) - 1): - errorMessage += '\t' + str(stackTrace[frameIndex]) + errorMessage += "\t" + str(stackTrace[frameIndex]) print(e, errorMessage, file=sys.stderr, flush=True) 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) + CONSTANTS.ENABLE_TELEMETRY, True +) threads.append(user_code) user_code.start() diff --git a/src/python_constants.py b/src/python_constants.py index 25837377b..a700a3143 100644 --- a/src/python_constants.py +++ b/src/python_constants.py @@ -3,7 +3,7 @@ CPX_DRIVE_NAME = "CIRCUITPY" -ENABLE_TELEMETRY = 'enable_telemetry' +ENABLE_TELEMETRY = "enable_telemetry" EXPECTED_INPUT_EVENTS = [ "button_a", "button_b", @@ -14,7 +14,7 @@ "motion_x", "motion_y", "motion_z", - "touch" + "touch", ] EXEC_COMMAND = "exec" @@ -29,7 +29,9 @@ MOUNT_COMMAND = "mount" NO_CPX_DETECTED_ERROR_TITLE = "No Circuit Playground Express detected" -NO_CPX_DETECTED_ERROR_DETAIL = "Could not find drive with name 'CIRCUITPYTHON'. Detected OS: {}" +NO_CPX_DETECTED_ERROR_DETAIL = ( + "Could not find drive with name 'CIRCUITPYTHON'. Detected OS: {}" +) NOT_SUPPORTED_OS = 'The OS "{}" not supported.' NOT_IMPLEMENTED_ERROR = "This method is not implemented by the simulator" diff --git a/src/requirements.txt b/src/requirements.txt index b39b0bc1e..0708fa17c 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,6 +1,7 @@ +black==19.10b0 playsound==1.2.2 pytest==5.0.1 applicationinsights==0.11.9 python-socketio==4.3.1 requests==2.22.0 -pywin32==224 +pywin32==227; platform_system == "Windows" diff --git a/src/serialMonitor.ts b/src/serialMonitor.ts index a022ddb1b..630154859 100644 --- a/src/serialMonitor.ts +++ b/src/serialMonitor.ts @@ -4,10 +4,10 @@ // Credit: A majority of this code was taken from the Visual Studio Code Arduino extension with some modifications to suit our purposes. import * as vscode from "vscode"; +import CONSTANTS, { DialogResponses, STATUS_BAR_PRIORITY } from "./constants"; +import { DeviceContext } from "./deviceContext"; import { outChannel } from "./extension"; import { logToOutputChannel } from "./extension_utils/utils"; -import { DeviceContext } from "./deviceContext"; -import CONSTANTS, { STATUS_BAR_PRIORITY, DialogResponses } from "./constants"; import { SerialPortControl } from "./serialPortControl"; export interface ISerialPortDetail { @@ -18,11 +18,23 @@ export interface ISerialPortDetail { } export class SerialMonitor implements vscode.Disposable { - public static DEFAULT_BAUD_RATE: number = 115200; public static listBaudRates(): number[] { - return [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000]; + return [ + 300, + 1200, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 74880, + 115200, + 230400, + 250000, + ]; } public static getInstance(): SerialMonitor { @@ -56,21 +68,35 @@ export class SerialMonitor implements vscode.Disposable { public initialize() { const defaultBaudRate: number = SerialMonitor.DEFAULT_BAUD_RATE; - this._outputChannel = vscode.window.createOutputChannel(CONSTANTS.MISC.SERIAL_MONITOR_NAME); + this._outputChannel = vscode.window.createOutputChannel( + CONSTANTS.MISC.SERIAL_MONITOR_NAME + ); this._currentBaudRate = defaultBaudRate; - this._portsStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, STATUS_BAR_PRIORITY.PORT); - this._portsStatusBar.command = "deviceSimulatorExpress.selectSerialPort"; + this._portsStatusBar = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Right, + STATUS_BAR_PRIORITY.PORT + ); + this._portsStatusBar.command = + "deviceSimulatorExpress.selectSerialPort"; this._portsStatusBar.tooltip = "Select Serial Port"; this._portsStatusBar.show(); - this._openPortStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, STATUS_BAR_PRIORITY.OPEN_PORT); - this._openPortStatusBar.command = "deviceSimulatorExpress.openSerialMonitor"; + this._openPortStatusBar = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Right, + STATUS_BAR_PRIORITY.OPEN_PORT + ); + this._openPortStatusBar.command = + "deviceSimulatorExpress.openSerialMonitor"; this._openPortStatusBar.text = `$(plug)`; this._openPortStatusBar.tooltip = "Open Serial Monitor"; this._openPortStatusBar.show(); - this._baudRateStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, STATUS_BAR_PRIORITY.BAUD_RATE); - this._baudRateStatusBar.command = "deviceSimulatorExpress.changeBaudRate"; + this._baudRateStatusBar = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Right, + STATUS_BAR_PRIORITY.BAUD_RATE + ); + this._baudRateStatusBar.command = + "deviceSimulatorExpress.changeBaudRate"; this._baudRateStatusBar.tooltip = "Baud Rate"; this._baudRateStatusBar.text = defaultBaudRate.toString(); this.updatePortListStatus(null); @@ -79,31 +105,50 @@ export class SerialMonitor implements vscode.Disposable { public async selectSerialPort(vid: string | null, pid: string | null) { const lists = await SerialPortControl.list(); if (!lists.length) { - vscode.window.showInformationMessage("No serial message is available."); + vscode.window.showInformationMessage( + "No serial message is available." + ); return; } if (vid && pid) { const valueOfVid = parseInt(vid, 16); const valueOfPid = parseInt(pid, 16); - const foundPort = lists.find((port) => { + const foundPort = lists.find(port => { if (port.productId && port.vendorId) { - return parseInt(port.productId, 16) === valueOfPid && parseInt(port.vendorId, 16) === valueOfVid; + return ( + parseInt(port.productId, 16) === valueOfPid && + parseInt(port.vendorId, 16) === valueOfVid + ); } return false; }); - if (foundPort && !(this._serialPortControl && this._serialPortControl.isActive)) { + if ( + foundPort && + !(this._serialPortControl && this._serialPortControl.isActive) + ) { this.updatePortListStatus(foundPort.comName); } } else { - const chosen = await vscode.window.showQuickPick(lists.map((port: ISerialPortDetail): vscode.QuickPickItem => { - return { - description: port.manufacturer, - label: port.comName - }; - }).sort((a, b): number => { - return a.label === b.label ? 0 : (a.label > b.label ? 1 : -1); - }) as vscode.QuickPickItem[], { placeHolder: CONSTANTS.MISC.SELECT_PORT_PLACEHOLDER}); + const chosen = await vscode.window.showQuickPick( + lists + .map( + (port: ISerialPortDetail): vscode.QuickPickItem => { + return { + description: port.manufacturer, + label: port.comName, + }; + } + ) + .sort((a, b): number => { + return a.label === b.label + ? 0 + : a.label > b.label + ? 1 + : -1; + }) as vscode.QuickPickItem[], + { placeHolder: CONSTANTS.MISC.SELECT_PORT_PLACEHOLDER } + ); if (chosen && chosen.label) { this.updatePortListStatus(chosen.label); @@ -116,7 +161,7 @@ export class SerialMonitor implements vscode.Disposable { const ans = await vscode.window.showInformationMessage( CONSTANTS.WARNING.NO_SERIAL_PORT_SELECTED, DialogResponses.YES, - DialogResponses.NO, + DialogResponses.NO ); if (ans === DialogResponses.YES) { await this.selectSerialPort(null, null); @@ -130,15 +175,23 @@ export class SerialMonitor implements vscode.Disposable { if (this._currentPort !== this._serialPortControl.currentPort) { await this._serialPortControl.changePort(this._currentPort); } else if (this._serialPortControl.isActive) { - vscode.window.showWarningMessage(`Serial Monitor is already opened for ${this._currentPort}`); + vscode.window.showWarningMessage( + `Serial Monitor is already opened for ${this._currentPort}` + ); return; } } else { - this._serialPortControl = new SerialPortControl(this._currentPort, this._currentBaudRate, this._outputChannel); + this._serialPortControl = new SerialPortControl( + this._currentPort, + this._currentBaudRate, + this._outputChannel + ); } if (!this._serialPortControl.currentPort) { - console.error(CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT(this._currentPort)); + console.error( + CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT(this._currentPort) + ); return; } @@ -146,12 +199,19 @@ export class SerialMonitor implements vscode.Disposable { await this._serialPortControl.open(); this.updatePortStatus(true); } catch (error) { - logToOutputChannel(outChannel, CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT_DUE_TO(this._currentPort, error), true); + logToOutputChannel( + outChannel, + CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT_DUE_TO( + this._currentPort, + error + ), + true + ); } } public get initialized(): boolean { - return !!this._outputChannel; + return !!this._outputChannel; } public dispose() { @@ -162,20 +222,34 @@ export class SerialMonitor implements vscode.Disposable { public async changeBaudRate() { const baudRates = SerialMonitor.listBaudRates(); - const chosen = await vscode.window.showQuickPick(baudRates.map((baudRate) => baudRate.toString())); + const chosen = await vscode.window.showQuickPick( + baudRates.map(baudRate => baudRate.toString()) + ); if (!chosen) { - logToOutputChannel(outChannel, CONSTANTS.WARNING.NO_RATE_SELECTED, true); + logToOutputChannel( + outChannel, + CONSTANTS.WARNING.NO_RATE_SELECTED, + true + ); return; } if (!parseInt(chosen, 10)) { - logToOutputChannel(outChannel, CONSTANTS.WARNING.INVALID_BAUD_RATE, true); + logToOutputChannel( + outChannel, + CONSTANTS.WARNING.INVALID_BAUD_RATE, + true + ); return; } if (!this._serialPortControl) { - logToOutputChannel(outChannel, CONSTANTS.WARNING.SERIAL_MONITOR_NOT_STARTED, true); + logToOutputChannel( + outChannel, + CONSTANTS.WARNING.SERIAL_MONITOR_NOT_STARTED, + true + ); return; } @@ -195,19 +269,25 @@ export class SerialMonitor implements vscode.Disposable { this.updatePortStatus(false); return result; } else if (!port && showWarning) { - logToOutputChannel(outChannel, CONSTANTS.WARNING.SERIAL_PORT_NOT_STARTED, true); + logToOutputChannel( + outChannel, + CONSTANTS.WARNING.SERIAL_PORT_NOT_STARTED, + true + ); return false; } } private updatePortStatus(isOpened: boolean) { if (isOpened) { - this._openPortStatusBar.command = "deviceSimulatorExpress.closeSerialMonitor"; + this._openPortStatusBar.command = + "deviceSimulatorExpress.closeSerialMonitor"; this._openPortStatusBar.text = `$(x)`; this._openPortStatusBar.tooltip = "Close Serial Monitor"; this._baudRateStatusBar.show(); } else { - this._openPortStatusBar.command = "deviceSimulatorExpress.openSerialMonitor"; + this._openPortStatusBar.command = + "deviceSimulatorExpress.openSerialMonitor"; this._openPortStatusBar.text = `$(plug)`; this._openPortStatusBar.tooltip = "Open Serial Monitor"; this._baudRateStatusBar.hide(); diff --git a/src/serialPortControl.ts b/src/serialPortControl.ts index 0b3eb3912..cbc79c3bb 100644 --- a/src/serialPortControl.ts +++ b/src/serialPortControl.ts @@ -3,9 +3,9 @@ // Credit: A majority of this code was taken from the Visual Studio Code Arduino extension with some modifications to suit our purposes. -import { CONSTANTS } from "./constants"; import * as os from "os"; import { OutputChannel } from "vscode"; +import { CONSTANTS } from "./constants"; import { logToOutputChannel } from "./extension_utils/utils"; interface ISerialPortDetail { @@ -18,20 +18,22 @@ interface ISerialPortDetail { export class SerialPortControl { public static get serialport(): any { if (!SerialPortControl._serialport) { - SerialPortControl._serialport = require("../vendor/node-usb-native").SerialPort + SerialPortControl._serialport = require("../vendor/node-usb-native").SerialPort; } return SerialPortControl._serialport; } public static list(): Promise { return new Promise((resolve, reject) => { - SerialPortControl.serialport.list((error: any, ports: ISerialPortDetail[]) => { - if (error) { - reject(error); - } else { - resolve(ports); + SerialPortControl.serialport.list( + (error: any, ports: ISerialPortDetail[]) => { + if (error) { + reject(error); + } else { + resolve(ports); + } } - }); + ); }); } @@ -41,7 +43,11 @@ export class SerialPortControl { private _currentBaudRate: number; private _currentSerialPort: any; - public constructor(port: string, baudRate: number, private _outputChannel: OutputChannel) { + public constructor( + port: string, + baudRate: number, + private _outputChannel: OutputChannel + ) { this._currentPort = port; this._currentBaudRate = baudRate; } @@ -55,7 +61,10 @@ export class SerialPortControl { } public open(): Promise { - logToOutputChannel(this._outputChannel, CONSTANTS.INFO.OPENING_SERIAL_PORT(this._currentPort)); + logToOutputChannel( + this._outputChannel, + CONSTANTS.INFO.OPENING_SERIAL_PORT(this._currentPort) + ); return new Promise((resolve, reject) => { if (this._currentSerialPort && this._currentSerialPort.isOpen()) { this._currentSerialPort.close((err: any) => { @@ -63,26 +72,56 @@ export class SerialPortControl { return reject(err); } this._currentSerialPort = null; - return this.open().then(() => { - resolve(); - }, (error) => { - reject(error); - }); + return this.open().then( + () => { + resolve(); + }, + error => { + reject(error); + } + ); }); } else { - this._currentSerialPort = new SerialPortControl.serialport(this._currentPort, { baudRate: this._currentBaudRate }); + this._currentSerialPort = new SerialPortControl.serialport( + this._currentPort, + { baudRate: this._currentBaudRate } + ); this._outputChannel.show(); this._currentSerialPort.on("open", () => { - this._currentSerialPort.write(CONSTANTS.MISC.SERIAL_MONITOR_TEST_IF_OPEN, "Both NL & CR", (err: any) => { - if (err && !(err.message.indexOf(CONSTANTS.ERROR.COMPORT_UNKNOWN_ERROR) >= 0)) { - logToOutputChannel(this._outputChannel, CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT(this._currentPort)); - logToOutputChannel(this._outputChannel, CONSTANTS.ERROR.RECONNECT_DEVICE); - reject(err); - } else { - logToOutputChannel(this._outputChannel, CONSTANTS.INFO.OPENED_SERIAL_PORT(this._currentPort)); - resolve(); + this._currentSerialPort.write( + CONSTANTS.MISC.SERIAL_MONITOR_TEST_IF_OPEN, + "Both NL & CR", + (err: any) => { + if ( + err && + !( + err.message.indexOf( + CONSTANTS.ERROR.COMPORT_UNKNOWN_ERROR + ) >= 0 + ) + ) { + logToOutputChannel( + this._outputChannel, + CONSTANTS.ERROR.FAILED_TO_OPEN_SERIAL_PORT( + this._currentPort + ) + ); + logToOutputChannel( + this._outputChannel, + CONSTANTS.ERROR.RECONNECT_DEVICE + ); + reject(err); + } else { + logToOutputChannel( + this._outputChannel, + CONSTANTS.INFO.OPENED_SERIAL_PORT( + this._currentPort + ) + ); + resolve(); + } } - }); + ); }); } @@ -120,21 +159,24 @@ export class SerialPortControl { public stop(): Promise { return new Promise((resolve, reject) => { - if (!this._currentSerialPort || !this.isActive) { - resolve(false); - return; - } - this._currentSerialPort.close((error: any) => { - if (this._outputChannel) { - logToOutputChannel(this._outputChannel, CONSTANTS.INFO.CLOSED_SERIAL_PORT(this._currentPort)); - } - this._currentSerialPort = null; - if (error) { - reject(error); - } else { - resolve(true); + if (!this._currentSerialPort || !this.isActive) { + resolve(false); + return; } - }); + this._currentSerialPort.close((error: any) => { + if (this._outputChannel) { + logToOutputChannel( + this._outputChannel, + CONSTANTS.INFO.CLOSED_SERIAL_PORT(this._currentPort) + ); + } + this._currentSerialPort = null; + if (error) { + reject(error); + } else { + resolve(true); + } + }); }); } @@ -145,13 +187,16 @@ export class SerialPortControl { resolve(); return; } - this._currentSerialPort.update({ baudRate: this._currentBaudRate }, (error: any) => { - if (error) { - reject(error); - } else { - resolve(); + this._currentSerialPort.update( + { baudRate: this._currentBaudRate }, + (error: any) => { + if (error) { + reject(error); + } else { + resolve(); + } } - }); + ); }); } -} \ No newline at end of file +} diff --git a/src/simulatorDebugConfigurationProvider.ts b/src/simulatorDebugConfigurationProvider.ts index 50c7f02c4..e0b711016 100644 --- a/src/simulatorDebugConfigurationProvider.ts +++ b/src/simulatorDebugConfigurationProvider.ts @@ -2,97 +2,105 @@ // Licensed under the MIT license. import * as vscode from "vscode"; +import { CONSTANTS, DialogResponses } from "./constants"; import { - validCodeFileName, - getServerPortConfig + getServerPortConfig, + validCodeFileName, } from "./extension_utils/utils"; -import { CONSTANTS, DialogResponses } from "./constants"; let shouldShowInvalidFileNamePopup: boolean = true; export class SimulatorDebugConfigurationProvider - implements vscode.DebugConfigurationProvider { - public deviceSimulatorExpressDebug: boolean; + implements vscode.DebugConfigurationProvider { + public deviceSimulatorExpressDebug: boolean; - constructor(private pathToScript: string) { - this.deviceSimulatorExpressDebug = false; - } + constructor(private pathToScript: string) { + this.deviceSimulatorExpressDebug = false; + } - /** - * Modify the debug configuration just before a debug session is being launched. - */ - public resolveDebugConfiguration( - folder: vscode.WorkspaceFolder | undefined, - config: vscode.DebugConfiguration, - token?: vscode.CancellationToken - ): vscode.ProviderResult { - const activeTextEditor = vscode.window.activeTextEditor; + /** + * Modify the debug configuration just before a debug session is being launched. + */ + public resolveDebugConfiguration( + folder: vscode.WorkspaceFolder | undefined, + config: vscode.DebugConfiguration, + token?: vscode.CancellationToken + ): vscode.ProviderResult { + const activeTextEditor = vscode.window.activeTextEditor; - // Create a configuration if no launch.json exists or if it's empty - if (!config.type && !config.request && !config.name) { - if ( - activeTextEditor && - activeTextEditor.document.languageId === "python" - ) { - config.type = "deviceSimulatorExpress"; - config.request = "launch"; - config.name = "Device Simulator Express Debugger"; - config.console = "integratedTerminal"; - } - } - // Check config type - if (config.type === CONSTANTS.DEBUG_CONFIGURATION_TYPE) { - this.deviceSimulatorExpressDebug = true; - if (activeTextEditor) { - const currentFilePath = activeTextEditor.document.fileName; + // Create a configuration if no launch.json exists or if it's empty + if (!config.type && !config.request && !config.name) { + if ( + activeTextEditor && + activeTextEditor.document.languageId === "python" + ) { + config.type = "deviceSimulatorExpress"; + config.request = "launch"; + config.name = "Device Simulator Express Debugger"; + config.console = "integratedTerminal"; + } + } + // Check config type + if (config.type === CONSTANTS.DEBUG_CONFIGURATION_TYPE) { + this.deviceSimulatorExpressDebug = true; + if (activeTextEditor) { + const currentFilePath = activeTextEditor.document.fileName; - // Check file type and name - if (!(activeTextEditor.document.languageId === "python")) { - return vscode.window - .showErrorMessage(CONSTANTS.ERROR.INVALID_FILE_EXTENSION_DEBUG) - .then(() => { - return undefined; // Abort launch - }); - } else if ( - !validCodeFileName(currentFilePath) && - shouldShowInvalidFileNamePopup - ) { - vscode.window - .showInformationMessage( - CONSTANTS.INFO.INVALID_FILE_NAME_DEBUG, - ...[DialogResponses.DONT_SHOW, DialogResponses.MESSAGE_UNDERSTOOD] - ) - .then((selection: vscode.MessageItem | undefined) => { - if (selection === DialogResponses.DONT_SHOW) { - shouldShowInvalidFileNamePopup = false; - } - }); + // Check file type and name + if (!(activeTextEditor.document.languageId === "python")) { + return vscode.window + .showErrorMessage( + CONSTANTS.ERROR.INVALID_FILE_EXTENSION_DEBUG + ) + .then(() => { + return undefined; // Abort launch + }); + } else if ( + !validCodeFileName(currentFilePath) && + shouldShowInvalidFileNamePopup + ) { + vscode.window + .showInformationMessage( + CONSTANTS.INFO.INVALID_FILE_NAME_DEBUG, + ...[ + DialogResponses.DONT_SHOW, + DialogResponses.MESSAGE_UNDERSTOOD, + ] + ) + .then((selection: vscode.MessageItem | undefined) => { + if (selection === DialogResponses.DONT_SHOW) { + shouldShowInvalidFileNamePopup = false; + } + }); + } + // Set the new configuration type so the python debugger can take over + config.type = "python"; + // Set process_user_code path as program + config.program = this.pathToScript; + // Set user's code path and server's port as args + config.args = [ + currentFilePath, + getServerPortConfig().toString(), + ]; + // Set rules + config.rules = [ + { path: this.pathToScript, include: false }, + { + module: "adafruit_circuitplayground", + include: false, + }, + { module: "playsound", include: false }, + ]; + } } - // Set the new configuration type so the python debugger can take over - config.type = "python"; - // Set process_user_code path as program - config.program = this.pathToScript; - // Set user's code path and server's port as args - config.args = [currentFilePath, getServerPortConfig().toString()]; - // Set rules - config.rules = [ - { path: this.pathToScript, include: false }, - { - module: "adafruit_circuitplayground", - include: false - }, - { module: "playsound", include: false } - ]; - } - } - // Abort / show error message if can't find process_user_code.py - if (!config.program) { - return vscode.window - .showErrorMessage(CONSTANTS.ERROR.NO_PROGRAM_FOUND_DEBUG) - .then(() => { - return undefined; // Abort launch - }); + // Abort / show error message if can't find process_user_code.py + if (!config.program) { + return vscode.window + .showErrorMessage(CONSTANTS.ERROR.NO_PROGRAM_FOUND_DEBUG) + .then(() => { + return undefined; // Abort launch + }); + } + return config; } - return config; - } } diff --git a/src/telemetry/getPackageInfo.ts b/src/telemetry/getPackageInfo.ts index cb9b52dea..cd8d42ab7 100644 --- a/src/telemetry/getPackageInfo.ts +++ b/src/telemetry/getPackageInfo.ts @@ -1,6 +1,6 @@ -import * as vscode from 'vscode'; -import * as fs from 'fs' -import * as path from 'path'; +import * as fs from "fs"; +import * as path from "path"; +import * as vscode from "vscode"; export interface IPackageJson { name?: string; @@ -14,35 +14,44 @@ const getPackagePath = (context: vscode.ExtensionContext) => { ); const packagePath = onDiskPath.with({ scheme: "vscode-resource" }); - return packagePath; -} + return packagePath; +}; -export default function getPackageInfo(context: vscode.ExtensionContext): { extensionName: string, extensionVersion: string, instrumentationKey: string } { - let packageJson: IPackageJson; - const packagePath = getPackagePath(context); - - try { - packageJson = JSON.parse(fs.readFileSync(packagePath.fsPath, "utf8")); - } catch (error) { - console.error(`Failed to read from package.json: ${error}`); - throw new Error(`Failed to read from package.json: ${error}`); - } - - const extensionName: string | undefined = packageJson.name; - const extensionVersion: string | undefined = packageJson.version; - const instrumentationKey: string | undefined = packageJson.instrumentationKey; - - if (!extensionName) { - throw new Error('Extension\'s package.json is missing instrumentation key.'); - } - - if (!extensionVersion) { - throw new Error('Extension\'s package.json is missing version.'); - } - - if (!extensionVersion) { - throw new Error('Extension\'s package.json is missing version.'); - } - - return { extensionName, extensionVersion, instrumentationKey }; -} \ No newline at end of file +export default function getPackageInfo( + context: vscode.ExtensionContext +): { + extensionName: string; + extensionVersion: string; + instrumentationKey: string; +} { + let packageJson: IPackageJson; + const packagePath = getPackagePath(context); + + try { + packageJson = JSON.parse(fs.readFileSync(packagePath.fsPath, "utf8")); + } catch (error) { + console.error(`Failed to read from package.json: ${error}`); + throw new Error(`Failed to read from package.json: ${error}`); + } + + const extensionName: string | undefined = packageJson.name; + const extensionVersion: string | undefined = packageJson.version; + const instrumentationKey: string | undefined = + packageJson.instrumentationKey; + + if (!extensionName) { + throw new Error( + "Extension's package.json is missing instrumentation key." + ); + } + + if (!extensionVersion) { + throw new Error("Extension's package.json is missing version."); + } + + if (!extensionVersion) { + throw new Error("Extension's package.json is missing version."); + } + + return { extensionName, extensionVersion, instrumentationKey }; +} diff --git a/src/telemetry/telemetryAI.ts b/src/telemetry/telemetryAI.ts index addcabffa..4dbf5ca41 100644 --- a/src/telemetry/telemetryAI.ts +++ b/src/telemetry/telemetryAI.ts @@ -4,78 +4,80 @@ import getPackageInfo from "./getPackageInfo"; // tslint:disable-next-line:export-name export default class TelemetryAI { - private static telemetryReporter: TelemetryReporter; - private static enableTelemetry: boolean | undefined; + private static telemetryReporter: TelemetryReporter; + private static enableTelemetry: boolean | undefined; - constructor(vscodeContext: vscode.ExtensionContext) { - TelemetryAI.telemetryReporter = this.createTelemetryReporter(vscodeContext); - TelemetryAI.enableTelemetry = vscode.workspace - .getConfiguration() - .get("telemetry.enableTelemetry"); - if (TelemetryAI.enableTelemetry === undefined) { - TelemetryAI.enableTelemetry = true; + constructor(vscodeContext: vscode.ExtensionContext) { + TelemetryAI.telemetryReporter = this.createTelemetryReporter( + vscodeContext + ); + TelemetryAI.enableTelemetry = vscode.workspace + .getConfiguration() + .get("telemetry.enableTelemetry"); + if (TelemetryAI.enableTelemetry === undefined) { + TelemetryAI.enableTelemetry = true; + } } - } - public getExtensionName(context: vscode.ExtensionContext): string { - const { extensionName } = getPackageInfo(context); - return extensionName; - } + public getExtensionName(context: vscode.ExtensionContext): string { + const { extensionName } = getPackageInfo(context); + return extensionName; + } - public getExtensionVersionNumber(context: vscode.ExtensionContext): string { - const { extensionVersion } = getPackageInfo(context); - return extensionVersion; - } + public getExtensionVersionNumber(context: vscode.ExtensionContext): string { + const { extensionVersion } = getPackageInfo(context); + return extensionVersion; + } - public sendTelemetryIfEnabled( - eventName: string, - properties?: { [key: string]: string }, - measurements?: { [key: string]: number } - ) { - if (TelemetryAI.enableTelemetry) { - TelemetryAI.telemetryReporter.sendTelemetryEvent( - eventName, - properties, - measurements - ); + public sendTelemetryIfEnabled( + eventName: string, + properties?: { [key: string]: string }, + measurements?: { [key: string]: number } + ) { + if (TelemetryAI.enableTelemetry) { + TelemetryAI.telemetryReporter.sendTelemetryEvent( + eventName, + properties, + measurements + ); + } } - } - public trackFeatureUsage( - eventName: string, - eventProperties?: { [key: string]: string } - ) { - this.sendTelemetryIfEnabled(eventName, eventProperties); - } + public trackFeatureUsage( + eventName: string, + eventProperties?: { [key: string]: string } + ) { + this.sendTelemetryIfEnabled(eventName, eventProperties); + } - public runWithLatencyMeasure( - functionToRun: () => void, - eventName: string - ): void { - const numberOfNanosecondsInSecond: number = 1000000000; - const startTime: number = Number(process.hrtime.bigint()); - functionToRun(); - const latency: number = Number(process.hrtime.bigint()) - startTime; - const measurement = { - duration: latency / numberOfNanosecondsInSecond - }; - this.sendTelemetryIfEnabled(eventName, {}, measurement); - } + public runWithLatencyMeasure( + functionToRun: () => void, + eventName: string + ): void { + const numberOfNanosecondsInSecond: number = 1000000000; + const startTime: number = Number(process.hrtime.bigint()); + functionToRun(); + const latency: number = Number(process.hrtime.bigint()) - startTime; + const measurement = { + duration: latency / numberOfNanosecondsInSecond, + }; + this.sendTelemetryIfEnabled(eventName, {}, measurement); + } - private createTelemetryReporter( - context: vscode.ExtensionContext - ): TelemetryReporter { - const { - extensionName, - extensionVersion, - instrumentationKey - } = getPackageInfo(context); - const reporter: TelemetryReporter = new TelemetryReporter( - extensionName, - extensionVersion, - instrumentationKey - ); - context.subscriptions.push(reporter); - return reporter; - } + private createTelemetryReporter( + context: vscode.ExtensionContext + ): TelemetryReporter { + const { + extensionName, + extensionVersion, + instrumentationKey, + } = getPackageInfo(context); + const reporter: TelemetryReporter = new TelemetryReporter( + extensionName, + extensionVersion, + instrumentationKey + ); + context.subscriptions.push(reporter); + return reporter; + } } diff --git a/src/template.py b/src/template.py index 42ed88698..b32caaae0 100644 --- a/src/template.py +++ b/src/template.py @@ -8,7 +8,7 @@ """ # import CPX library -from adafruit_circuitplayground.express import cpx +from adafruit_circuitplayground import cp while True: # start your code here diff --git a/src/test/runTest.ts b/src/test/runTest.ts index a3e10548d..6d54aa78b 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -1,23 +1,23 @@ -import * as path from 'path'; +import * as path from "path"; -import { runTests } from 'vscode-test'; +import { runTests } from "vscode-test"; async function main() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + try { + // The folder containing the Extension Manifest package.json + // Passed to `--extensionDevelopmentPath` + const extensionDevelopmentPath = path.resolve(__dirname, "../../"); - // The path to the extension test script - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); + // The path to the extension test script + // Passed to --extensionTestsPath + const extensionTestsPath = path.resolve(__dirname, "./suite/index"); - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests'); - process.exit(1); - } + // Download VS Code, unzip it and run the integration test + await runTests({ extensionDevelopmentPath, extensionTestsPath }); + } catch (err) { + console.error("Failed to run tests"); + process.exit(1); + } } main(); diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts deleted file mode 100644 index 60293e737..000000000 --- a/src/test/suite/extension.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -// -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. -// - -// The module 'assert' provides assertion methods from node -import * as assert from 'assert'; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -// import * as vscode from 'vscode'; -// import * as myExtension from '../extension'; - -// Defines a Mocha test suite to group tests of similar kind together -suite('Extension Test Suite', () => { - - test('Sample test', () => { - assert.equal(-1, [1, 2, 3].indexOf(5)); - assert.equal(-1, [1, 2, 3].indexOf(0)); - }); -}); diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index 6d50df1c3..c223a6f0d 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -10,22 +10,22 @@ // to report the results back to the caller. When the tests are finished, return // a possible error to the callback or null if none. -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +import * as glob from "glob"; +import * as Mocha from "mocha"; +import * as path from "path"; // tslint:disable-next-line: export-name export function run(): Promise { // Create the mocha test const mocha = new Mocha({ - ui: 'tdd', + ui: "tdd", }); mocha.useColors(true); - const testsRoot = path.resolve(__dirname, '..'); + const testsRoot = path.resolve(__dirname, ".."); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { + glob("**/**.test.js", { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } @@ -47,4 +47,4 @@ export function run(): Promise { } }); }); -} \ No newline at end of file +} diff --git a/src/test_code/code.py b/src/test_code/code.py deleted file mode 100644 index 369561cc5..000000000 --- a/src/test_code/code.py +++ /dev/null @@ -1,19 +0,0 @@ -from adafruit_circuitplayground.express import cpx -import time - -cpx.pixels.brightness = 0.3 -cpx.pixels.fill((0, 0, 0)) # Turn off the NeoPixels if they're on! -cpx.pixels.show() - -while True: - if cpx.button_a: - cpx.pixels[2] = (0, 255, 0) - else: - cpx.pixels[2] = (0, 0, 0) - - if cpx.button_b: - cpx.pixels[7] = (0, 0, 255) - else: - cpx.pixels[7] = (0, 0, 0) - cpx.pixels.show() - diff --git a/src/test_code/control.py b/src/test_code/control.py deleted file mode 100644 index 1aceb880b..000000000 --- a/src/test_code/control.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys -import json - -# Read data from stdin - - -def read_in(): - lines = sys.stdin.readlines() - # Since our input would only be having one line, parse our JSON data from that - return json.loads(lines[0]) - - -def main(): - # get our data as an array from read_in() - # lines = read_in() - - openCmd = { - 'pixels': [ - (0, 0, 255), - (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), - ], - 'button_a': False, - 'button_b': False, - } - print(json.dumps(openCmd)) - - -# start process -if __name__ == '__main__': - main() diff --git a/src/usbDetector.ts b/src/usbDetector.ts index 44989781e..ccff7a679 100644 --- a/src/usbDetector.ts +++ b/src/usbDetector.ts @@ -3,13 +3,13 @@ // Credit: A majority of this code was taken from the Visual Studio Code Arduino extension with some modifications to suit our purposes. -import * as os from "os"; import * as fs from "fs"; +import * as os from "os"; import * as path from "path"; -import * as utils from "./extension_utils/utils"; import * as vscode from "vscode"; -import { SerialMonitor } from "./serialMonitor"; import { CONFIG_KEYS } from "./constants"; +import * as utils from "./extension_utils/utils"; +import { SerialMonitor } from "./serialMonitor"; export class UsbDetector { public static getInstance(): UsbDetector { @@ -27,7 +27,7 @@ export class UsbDetector { private _extensionRoot: string = null; - private constructor() { } + private constructor() {} public initialize(extensionRoot: string) { this._extensionRoot = extensionRoot; @@ -35,7 +35,9 @@ export class UsbDetector { public async startListening() { const workspaceConfig = vscode.workspace.getConfiguration(); - const enableUSBDetection = workspaceConfig.get(CONFIG_KEYS.ENABLE_USB_DETECTION); + const enableUSBDetection = workspaceConfig.get( + CONFIG_KEYS.ENABLE_USB_DETECTION + ); if (os.platform() === "linux" || !enableUSBDetection) { return; @@ -78,22 +80,33 @@ export class UsbDetector { } } - private getUsbDeviceDescriptor(vendorId: string, productId: string, extensionRoot: string): any { + private getUsbDeviceDescriptor( + vendorId: string, + productId: string, + extensionRoot: string + ): any { if (!this._boardDescriptors) { this._boardDescriptors = []; - const fileContent = fs.readFileSync(path.join(extensionRoot, "misc", "usbmapping.json"), "utf8"); + const fileContent = fs.readFileSync( + path.join(extensionRoot, "misc", "usbmapping.json"), + "utf8" + ); const boardIndexes: [] = JSON.parse(fileContent); boardIndexes.forEach((boardIndex: any) => { boardIndex.boards.forEach((board: any) => { - board.indexFile = boardIndex.index_file + board.indexFile = boardIndex.index_file; }); - this._boardDescriptors = this._boardDescriptors.concat(boardIndex.boards); + this._boardDescriptors = this._boardDescriptors.concat( + boardIndex.boards + ); }); } return this._boardDescriptors.find((obj: any) => { - return obj.vid === vendorId && - (obj.pid === productId || - (obj.pid.indexOf && obj.pid.indexOf(productId) >= 0)); + return ( + obj.vid === vendorId && + (obj.pid === productId || + (obj.pid.indexOf && obj.pid.indexOf(productId) >= 0)) + ); }); } -} \ No newline at end of file +} diff --git a/src/view/App.css b/src/view/App.css index 10158ee73..413e9fcbc 100644 --- a/src/view/App.css +++ b/src/view/App.css @@ -1,16 +1,16 @@ .App { - text-align: center; - display: flex; - justify-content: space-between; + text-align: center; + display: flex; + justify-content: space-between; } .App-main { - background-color: var(--vscode-editor-background); - padding: 0px 0.75em 0px 0.75em; - min-height: 100vh; - width: 100%; - margin-top: 24px; - margin-bottom: 53px; - max-height: 400px; - overflow: scroll; + background-color: var(--vscode-editor-background); + padding: 0px 0.75em 0px 0.75em; + min-height: 100vh; + width: 100%; + margin-top: 24px; + margin-bottom: 53px; + max-height: 400px; + overflow: scroll; } diff --git a/src/view/App.test.tsx b/src/view/App.test.tsx new file mode 100644 index 000000000..3822593f7 --- /dev/null +++ b/src/view/App.test.tsx @@ -0,0 +1,15 @@ +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 b3d3737cb..b52993907 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -3,21 +3,19 @@ "use strict"; import * as React from "react"; -import Simulator from "./components/Simulator"; -import ToolBar from "./components/toolbar/ToolBar"; import "./App.css"; +import Device from "./container/device/Device"; class App extends React.Component { - render() { - return ( -
-
- - -
-
- ); - } + render() { + return ( +
+
+ +
+
+ ); + } } export default App; diff --git a/src/view/components/Button.tsx b/src/view/components/Button.tsx index c613b5910..db5034b9d 100644 --- a/src/view/components/Button.tsx +++ b/src/view/components/Button.tsx @@ -2,33 +2,33 @@ import * as React from "react"; import "../styles/Button.css"; export interface IButtonProps { - label: string; - image: any; - focusable: boolean; - styleLabel: string; - width: number; - onClick: (event: React.MouseEvent) => void; + label: string; + image: any; + focusable: boolean; + styleLabel: string; + width: number; + onClick: (event: React.MouseEvent) => void; } // Functional Component render const Button: React.FC = props => { - const iconSvg: SVGElement = props.image as SVGElement; - const buttonStyle = { width: props.width }; - const tabIndex = props.focusable ? 0 : -1; + const iconSvg: SVGElement = props.image as SVGElement; + const buttonStyle = { width: props.width }; + const tabIndex = props.focusable ? 0 : -1; - return ( - - ); + return ( + + ); }; export default Button; diff --git a/src/view/components/Dropdown.tsx b/src/view/components/Dropdown.tsx index d84c09cf3..f4c995923 100644 --- a/src/view/components/Dropdown.tsx +++ b/src/view/components/Dropdown.tsx @@ -2,58 +2,59 @@ // Licensed under the MIT license. import * as React from "react"; + import { CONSTANTS } from "../constants"; import "../styles/Dropdown.css"; export interface IDropdownProps { - label: string; - textOptions: string[]; - lastChosen: string; - styleLabel: string; - width: number; - onBlur: (event: React.FocusEvent) => void; + label: string; + textOptions: string[]; + lastChosen: string; + styleLabel: string; + width: number; + onBlur: (event: React.FocusEvent) => void; } const Dropdown: React.FC = props => { - const parsedPath = parsePath(props.lastChosen); - const defaultText = - props.lastChosen !== "" - ? CONSTANTS.CURRENTLY_RUNNING(parsedPath[1]) - : CONSTANTS.NO_FILES_AVAILABLE; - return ( -
- -
- ); + const parsedPath = parsePath(props.lastChosen); + const defaultText = + props.lastChosen !== "" + ? CONSTANTS.CURRENTLY_RUNNING(parsedPath[1]) + : CONSTANTS.NO_FILES_AVAILABLE; + return ( +
+ +
+ ); }; const renderOptions = (options: string[]) => { - return options.map((name, index) => { - const key = `option-${index}`; - const parsedPath = parsePath(name); - return ( - - ); - }); + return options.map((name, index) => { + const key = `option-${index}`; + const parsedPath = parsePath(name); + return ( + + ); + }); }; const parsePath = (filePath: string) => { - const lastSlash = - filePath.lastIndexOf("/") !== -1 - ? filePath.lastIndexOf("/") - : filePath.lastIndexOf("\\"); - return [filePath.slice(0, lastSlash), filePath.substr(lastSlash + 1)]; + const lastSlash = + filePath.lastIndexOf("/") !== -1 + ? filePath.lastIndexOf("/") + : filePath.lastIndexOf("\\"); + return [filePath.slice(0, lastSlash), filePath.substr(lastSlash + 1)]; }; export default Dropdown; diff --git a/src/view/components/Simulator.tsx b/src/view/components/Simulator.tsx index 29e25e5e5..a1ddee6b6 100644 --- a/src/view/components/Simulator.tsx +++ b/src/view/components/Simulator.tsx @@ -2,379 +2,400 @@ // Licensed under the MIT license. import * as React from "react"; -import { BUTTON_NEUTRAL, BUTTON_PRESSED } from "./cpx/Cpx_svg_style"; -import Cpx, { updateSwitch, updatePinTouch } from "./cpx/Cpx"; -import Button from "./Button"; -import Dropdown from "./Dropdown"; import { CONSTANTS } from "../constants"; +import "../styles/Simulator.css"; import PlayLogo from "../svgs/play_svg"; import StopLogo from "../svgs/stop_svg"; -import RefreshLogo from "../svgs/refresh_svg"; - -import "../styles/Simulator.css"; +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"; interface ICpxState { - pixels: number[][]; - brightness: number; - red_led: boolean; - button_a: boolean; - button_b: boolean; - switch: boolean; - touch: boolean[]; - shake: boolean; + pixels: number[][]; + brightness: number; + red_led: boolean; + button_a: boolean; + button_b: boolean; + switch: boolean; + touch: boolean[]; + shake: boolean; } interface IState { - active_editors: string[]; - running_file: string; - selected_file: string; - cpx: ICpxState; - play_button: boolean; + active_editors: string[]; + running_file: string; + selected_file: string; + cpx: ICpxState; + play_button: boolean; } interface IMyProps { - children?: any; + children?: any; } const DEFAULT_CPX_STATE: ICpxState = { - 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, - touch: [false, false, false, false, false, false, false], - shake: false + 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, + touch: [false, false, false, false, false, false, false], + shake: false, }; interface vscode { - postMessage(message: any): void; + postMessage(message: any): void; } declare const vscode: vscode; const sendMessage = (type: string, state: any) => { - vscode.postMessage({ command: type, text: state }); + vscode.postMessage({ command: type, text: state }); }; class Simulator extends React.Component { - constructor(props: IMyProps) { - super(props); - this.state = { - active_editors: [], - cpx: DEFAULT_CPX_STATE, - play_button: false, - running_file: "", - selected_file: "" + constructor(props: IMyProps) { + super(props); + this.state = { + active_editors: [], + cpx: DEFAULT_CPX_STATE, + play_button: false, + running_file: "", + selected_file: "", + }; + + this.handleClick = this.handleClick.bind(this); + this.onKeyEvent = this.onKeyEvent.bind(this); + this.onMouseDown = this.onMouseDown.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); + this.onMouseLeave = this.onMouseLeave.bind(this); + this.togglePlayClick = this.togglePlayClick.bind(this); + this.refreshSimulatorClick = this.refreshSimulatorClick.bind(this); + this.onSelectBlur = this.onSelectBlur.bind(this); + } + + handleMessage = (event: any): void => { + const message = event.data; // The JSON data our extension sent + switch (message.command) { + case "reset-state": + console.log("Clearing the state"); + this.setState({ + ...this.state, + cpx: DEFAULT_CPX_STATE, + play_button: false, + }); + break; + case "set-state": + console.log( + "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; + case "visible-editors": + console.log( + "Setting active editors", + 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; + } }; - this.handleClick = this.handleClick.bind(this); - this.onKeyEvent = this.onKeyEvent.bind(this); - this.onMouseDown = this.onMouseDown.bind(this); - this.onMouseUp = this.onMouseUp.bind(this); - this.onMouseLeave = this.onMouseLeave.bind(this); - this.togglePlayClick = this.togglePlayClick.bind(this); - this.refreshSimulatorClick = this.refreshSimulatorClick.bind(this); - this.onSelectBlur = this.onSelectBlur.bind(this); - } - - handleMessage = (event: any): void => { - const message = event.data; // The JSON data our extension sent - switch (message.command) { - case "reset-state": - console.log("Clearing the state"); - this.setState({ - ...this.state, - cpx: DEFAULT_CPX_STATE, - play_button: false - }); - break; - case "set-state": - console.log("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; - case "visible-editors": - console.log( - "Setting active editors", - message.state.activePythonEditors + componentDidMount() { + console.log("Mounted"); + window.addEventListener("message", this.handleMessage); + } + + componentWillUnmount() { + // Make sure to remove the DOM listener when the component is unmounted. + window.removeEventListener("message", this.handleMessage); + } + + render() { + const playStopImage = this.state.play_button ? StopLogo : PlayLogo; + return ( +
+
+ +
+
+ +
+ +
); - this.setState({ - ...this.state, - active_editors: message.state.activePythonEditors + } + + protected togglePlayClick() { + sendMessage("play-simulator", { + selected_file: this.state.selected_file, + state: !this.state.play_button, }); - break; - case "current-file": - console.log("Setting current file", message.state.running_file); + const button = + window.document.getElementById(CONSTANTS.ID_NAME.PLAY_BUTTON) || + window.document.getElementById(CONSTANTS.ID_NAME.STOP_BUTTON); + if (button) { + button.focus(); + } + } + + protected refreshSimulatorClick() { + sendMessage("refresh-simulator", true); + const button = window.document.getElementById( + CONSTANTS.ID_NAME.REFRESH_BUTTON + ); + if (button) { + button.focus(); + } + } + + protected onSelectBlur(event: React.FocusEvent) { this.setState({ - ...this.state, - running_file: message.state.running_file + ...this.state, + selected_file: event.currentTarget.value, }); - break; - default: - console.log("Invalid message received from the extension."); - this.setState({ ...this.state, cpx: DEFAULT_CPX_STATE }); - break; } - }; - - componentDidMount() { - console.log("Mounted"); - window.addEventListener("message", this.handleMessage); - } - - componentWillUnmount() { - // Make sure to remove the DOM listener when the component is unmounted. - window.removeEventListener("message", this.handleMessage); - } - - render() { - const image = this.state.play_button ? StopLogo : PlayLogo; - return ( -
-
- -
-
- -
-
-
-
- ); - } - - 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(); + protected onKeyEvent(event: KeyboardEvent, active: boolean) { + let element; + const target = event.target as SVGElement; + // Guard Clause + if (target === undefined) { + return; + } + + if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.ENTER)) { + element = window.document.getElementById(target.id); + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.A) + ) { + element = window.document.getElementById( + CONSTANTS.ID_NAME.BUTTON_A + ); + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.B) + ) { + element = window.document.getElementById( + CONSTANTS.ID_NAME.BUTTON_B + ); + } else if ( + [event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.S) + ) { + element = window.document.getElementById(CONSTANTS.ID_NAME.SWITCH); + } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) { + this.togglePlayClick(); + } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_R) { + this.refreshSimulatorClick(); + } else { + if (event.shiftKey) { + switch (event.code) { + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_ONE: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A1 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_TWO: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A2 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_THREE: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A3 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_FOUR: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A4 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_FIVE: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A5 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_SIX: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A6 + ); + break; + + case CONSTANTS.KEYBOARD_KEYS.NUMERIC_SEVEN: + element = window.document.getElementById( + CONSTANTS.ID_NAME.PIN_A7 + ); + break; + } + } + } + if (element) { + event.preventDefault(); + this.handleClick(element, active); + element.focus(); + } } - } - - protected refreshSimulatorClick() { - sendMessage("refresh-simulator", true); - const button = window.document.getElementById( - CONSTANTS.ID_NAME.REFRESH_BUTTON - ); - if (button) { - button.focus(); + protected onMouseDown(button: HTMLElement, event: Event) { + event.preventDefault(); + this.handleClick(button, true); + button.focus(); } - } - - protected onSelectBlur(event: React.FocusEvent) { - this.setState({ ...this.state, selected_file: event.currentTarget.value }); - } - protected onKeyEvent(event: KeyboardEvent, active: boolean) { - let element; - const target = event.target as SVGElement; - // Guard Clause - if (target === undefined) { - return; + + protected onMouseUp(button: HTMLElement, event: Event) { + event.preventDefault(); + this.handleClick(button, false); } - if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.ENTER)) { - element = window.document.getElementById(target.id); - } else if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.A)) { - element = window.document.getElementById(CONSTANTS.ID_NAME.BUTTON_A); - } else if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.B)) { - element = window.document.getElementById(CONSTANTS.ID_NAME.BUTTON_B); - } else if ([event.code, event.key].includes(CONSTANTS.KEYBOARD_KEYS.S)) { - element = window.document.getElementById(CONSTANTS.ID_NAME.SWITCH); - } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_F) { - this.togglePlayClick(); - } else if (event.key === CONSTANTS.KEYBOARD_KEYS.CAPITAL_R) { - this.refreshSimulatorClick(); - } else { - if (event.shiftKey) { - switch (event.code) { - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_ONE: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A1); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_TWO: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A2); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_THREE: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A3); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_FOUR: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A4); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_FIVE: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A5); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_SIX: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A6); - break; - - case CONSTANTS.KEYBOARD_KEYS.NUMERIC_SEVEN: - element = window.document.getElementById(CONSTANTS.ID_NAME.PIN_A7); - break; + protected onMouseLeave(button: HTMLElement, event: Event) { + event.preventDefault(); + + if (button.getAttribute("pressed") === "true") { + this.handleClick(button, false); } - } - } - if (element) { - event.preventDefault(); - this.handleClick(element, active); - element.focus(); } - } - protected onMouseDown(button: HTMLElement, event: Event) { - event.preventDefault(); - this.handleClick(button, true); - button.focus(); - } - - protected onMouseUp(button: HTMLElement, event: Event) { - event.preventDefault(); - this.handleClick(button, false); - } - - protected onMouseLeave(button: HTMLElement, event: Event) { - event.preventDefault(); - - if (button.getAttribute("pressed") === "true") { - this.handleClick(button, false); - } - } - - private handleClick(element: HTMLElement, active: boolean) { - let newState; - let message; - if (element.id.includes("BTN")) { - newState = this.handleButtonClick(element, active); - message = "button-press"; - } else if (element.id.includes("SWITCH")) { - newState = this.handleSwitchClick(); - message = "button-press"; - } else if (element.id.includes("PIN")) { - newState = this.handleTouchPinClick(element, active); - message = "sensor-changed"; - } else { - return; + + private handleClick(element: HTMLElement, active: boolean) { + let newState; + let message; + if (element.id.includes("BTN")) { + newState = this.handleButtonClick(element, active); + message = "button-press"; + } else if (element.id.includes("SWITCH")) { + newState = this.handleSwitchClick(); + message = "button-press"; + } else if (element.id.includes("PIN")) { + newState = this.handleTouchPinClick(element, active); + message = "sensor-changed"; + } else { + return; + } + + if (newState && message) { + sendMessage(message, newState); + } } - if (newState && message) { - sendMessage(message, newState); + private handleButtonClick(button: HTMLElement, active: boolean) { + const ButtonA: boolean = button.id.match(/BTN_A/) !== null; + const ButtonB: boolean = button.id.match(/BTN_B/) !== null; + const ButtonAB: boolean = button.id.match(/BTN_AB/) !== null; + let innerButton; + let newState; + + if (ButtonAB) { + innerButton = window.document.getElementById("BTN_AB_INNER"); + newState = { + button_a: active, + button_b: active, + }; + this.setState({ ...this.state, ...newState }); + } else if (ButtonA) { + innerButton = window.document.getElementById("BTN_A_INNER"); + newState = { + button_a: active, + }; + this.setState({ ...this.state, ...newState }); + } else if (ButtonB) { + innerButton = window.document.getElementById("BTN_B_INNER"); + newState = { + button_b: active, + }; + this.setState({ ...this.state, ...newState }); + } + + if (innerButton) { + innerButton.style.fill = this.getButtonColor(active); + } + + button.setAttribute("pressed", `${active}`); + return newState; } - } - - private handleButtonClick(button: HTMLElement, active: boolean) { - const ButtonA: boolean = button.id.match(/BTN_A/) !== null; - const ButtonB: boolean = button.id.match(/BTN_B/) !== null; - const ButtonAB: boolean = button.id.match(/BTN_AB/) !== null; - let innerButton; - let newState; - - if (ButtonAB) { - innerButton = window.document.getElementById("BTN_AB_INNER"); - newState = { - button_a: active, - button_b: active - }; - this.setState({ ...this.state, ...newState }); - } else if (ButtonA) { - innerButton = window.document.getElementById("BTN_A_INNER"); - newState = { - button_a: active - }; - this.setState({ ...this.state, ...newState }); - } else if (ButtonB) { - innerButton = window.document.getElementById("BTN_B_INNER"); - newState = { - button_b: active - }; - this.setState({ ...this.state, ...newState }); + + private getButtonColor(pressed: boolean) { + const buttonUps = BUTTON_NEUTRAL; + const buttonDown = BUTTON_PRESSED; + return pressed ? buttonDown : buttonUps; } - if (innerButton) { - innerButton.style.fill = this.getButtonColor(active); + private handleSwitchClick() { + let cpxState = this.state.cpx; + const switchIsOn: boolean = !this.state.cpx.switch; + updateSwitch(switchIsOn); + cpxState = { ...cpxState, switch: switchIsOn }; + this.setState({ ...this.state, ...cpxState }); + return { switch: switchIsOn }; } - button.setAttribute("pressed", `${active}`); - return newState; - } - - private getButtonColor(pressed: boolean) { - const buttonUps = BUTTON_NEUTRAL; - const buttonDown = BUTTON_PRESSED; - return pressed ? buttonDown : buttonUps; - } - - private handleSwitchClick() { - let cpxState = this.state.cpx; - const switchIsOn: boolean = !this.state.cpx.switch; - updateSwitch(switchIsOn); - cpxState = { ...cpxState, switch: switchIsOn }; - this.setState({ ...this.state, ...cpxState }); - return { switch: switchIsOn }; - } - - private handleTouchPinClick(pin: HTMLElement, active: boolean): any { - let cpxState = this.state.cpx; - const pinIndex = parseInt(pin.id.charAt(pin.id.length - 1)) - 1; - let pinState = cpxState.touch; - pinState[pinIndex] = active; - cpxState = { ...cpxState, touch: pinState }; - this.setState({ ...this.state, ...cpxState }); - updatePinTouch(active, pin.id); - return { touch: pinState }; - } + private handleTouchPinClick(pin: HTMLElement, active: boolean): any { + let cpxState = this.state.cpx; + const pinIndex = parseInt(pin.id.charAt(pin.id.length - 1)) - 1; + const pinState = cpxState.touch; + pinState[pinIndex] = active; + cpxState = { ...cpxState, touch: pinState }; + this.setState({ ...this.state, ...cpxState }); + updatePinTouch(active, pin.id); + return { touch: pinState }; + } } export default Simulator; diff --git a/src/view/components/cpx/Accessibility_utils.ts b/src/view/components/cpx/Accessibility_utils.ts index 0ea83d1b2..afdadb2ac 100644 --- a/src/view/components/cpx/Accessibility_utils.ts +++ b/src/view/components/cpx/Accessibility_utils.ts @@ -3,20 +3,24 @@ // Helpers designed to help to make a simulator accessible. namespace accessibility { - export function makeFocusable(elem: SVGElement): void { - elem.setAttribute("focusable", "true"); - elem.setAttribute("tabindex", "0"); - } - - export function setAria(elem: Element, role?: string, label?: string): void { - if (role && !elem.hasAttribute("role")) { - elem.setAttribute("role", role); + export function makeFocusable(elem: SVGElement): void { + elem.setAttribute("focusable", "true"); + elem.setAttribute("tabindex", "0"); } - if (label && !elem.hasAttribute("aria-label")) { - elem.setAttribute("aria-label", label); + export function setAria( + elem: Element, + role?: string, + label?: string + ): void { + if (role && !elem.hasAttribute("role")) { + elem.setAttribute("role", role); + } + + if (label && !elem.hasAttribute("aria-label")) { + elem.setAttribute("aria-label", label); + } } - } } export default accessibility; diff --git a/src/view/components/cpx/Cpx.tsx b/src/view/components/cpx/Cpx.tsx deleted file mode 100644 index 845ab3654..000000000 --- a/src/view/components/cpx/Cpx.tsx +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import * as React from "react"; -import CPX_SVG from "./Cpx_svg"; -import * as SvgStyle from "./Cpx_svg_style"; -import CONSTANTS from "../../constants"; -import svg from "./Svg_utils"; -import accessibility from "./Accessibility_utils"; - -interface IProps { - pixels: number[][]; - red_led: boolean; - brightness: number; - switch: boolean; - on: boolean; - onKeyEvent: (event: KeyboardEvent, active: boolean) => void; - onMouseUp: (button: HTMLElement, event: Event) => void; - onMouseDown: (button: HTMLElement, event: Event) => void; - onMouseLeave: (button: HTMLElement, event: Event) => void; -} - -let firstTime = true; - -// Functional Component render -const Cpx: 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; - } - // Update Neopixels and red LED state - updateNeopixels(props); - updateRedLED(props.red_led); - updatePowerLED(props.on); - updateSwitch(props.switch); - } - - return CPX_SVG; -}; - -const makeButton = ( - g: SVGElement, - left: number, - top: number, - id: string -): { outer: SVGElement; inner: SVGElement } => { - const buttonCornerRadius = SvgStyle.BUTTON_CORNER_RADIUS; - const buttonWidth = SvgStyle.BUTTON_WIDTH; - const buttonCircleRadius = SvgStyle.BUTTON_CIRCLE_RADIUS; - const btng = svg.child(g, "g", { class: "sim-button-group" }); - svg.child(btng, "rect", { - fill: SvgStyle.BUTTON_OUTER, - height: buttonWidth, - id: id + "_OUTER", - rx: buttonCornerRadius, - ry: buttonCornerRadius, - width: buttonWidth, - x: left, - y: top - }); - - const outer = btng; - const inner = svg.child(btng, "circle", { - id: id + "_INNER", - cx: left + buttonWidth / 2, - cy: top + buttonWidth / 2, - r: buttonCircleRadius, - fill: SvgStyle.BUTTON_NEUTRAL - }); - - return { outer, inner }; -}; - -const initSvgStyle = (svgElement: HTMLElement, brightness: number): void => { - let style: SVGStyleElement = svg.child( - svgElement, - "style", - {} - ) as SVGStyleElement; - style.textContent = SvgStyle.SVG_STYLE; - - // Filters for the glow effect (Adapted from : https://github.com/microsoft/pxt-adafruit/blob/master/sim/visuals/board.ts) - const defs: SVGDefsElement = svg.child( - svgElement, - "defs", - {} - ) as SVGDefsElement; - - const g = svg.createElement("g") as SVGElement; - svgElement.appendChild(g); - - const glow = svg.child(defs, "filter", { - height: "120%", - id: "filterglow", - width: "120%", - x: "-5%", - y: "-5%" - }); - svg.child(glow, "feGaussianBlur", { stdDeviation: "5", result: "glow" }); - const merge = svg.child(glow, "feMerge", {}); - for (let i = 0; i < 3; ++i) { - svg.child(merge, "feMergeNode", { in: "glow" }); - } - - const neopixelglow = svg.child(defs, "filter", { - height: "600%", - id: "neopixelglow", - width: "600%", - x: "-300%", - y: "-300%" - }); - svg.child(neopixelglow, "feGaussianBlur", { - result: "coloredBlur", - stdDeviation: "4.3" - }); - const neopixelmerge = svg.child(neopixelglow, "feMerge", {}); - svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }); - svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }); - svg.child(neopixelmerge, "feMergeNode", { in: "SourceGraphic" }); - - // Brightness - const neopixelfeComponentTransfer = svg.child( - neopixelglow, - "feComponentTransfer", - {} - ); - svg.child(neopixelfeComponentTransfer, "feFuncR", { - id: "brightnessFilterR", - type: "linear", - slope: brightness - }); - svg.child(neopixelfeComponentTransfer, "feFuncG", { - id: "brightnessFilterG", - slope: brightness, - type: "linear" - }); - svg.child(neopixelfeComponentTransfer, "feFuncB", { - id: "brightnessFilterB", - slope: brightness, - type: "linear" - }); - - // BTN A+B - const outerBtn = (left: number, top: number, label: string) => { - return makeButton(g, left, top, "BTN_AB"); - }; - - const ab = outerBtn(165, SvgStyle.MB_HEIGHT - 15, "A+B"); - const abtext = svg.child(ab.outer, "text", { - class: "sim-text", - x: SvgStyle.BUTTON_TEXT_BASELINE, - y: SvgStyle.MB_HEIGHT - 18 - }) as SVGTextElement; - abtext.textContent = "A+B"; -}; - -const updateNeopixels = (props: IProps): void => { - for (let i = 0; i < props.pixels.length; i++) { - const led = window.document.getElementById(`NEOPIXEL_${i}`); - if (led) { - setNeopixel(led, props.pixels[i], props.brightness); - } - } -}; - -const updateRedLED = (propsRedLED: boolean): void => { - const redLED = window.document.getElementById("SERIAL_LED"); - if (redLED) { - redLED.style.fill = propsRedLED - ? SvgStyle.RED_LED_ON - : SvgStyle.RED_LED_OFF; - } -}; - -const updatePowerLED = (propsPowerLED: boolean): void => { - const powerLED = window.document.getElementById("PWR_LED"); - if (powerLED) { - powerLED.style.fill = propsPowerLED - ? SvgStyle.POWER_LED_ON - : SvgStyle.POWER_LED_OFF; - } -}; - -const setNeopixel = ( - led: HTMLElement, - pixValue: number[], - brightness: number -): void => { - if (isLightOn(pixValue) && brightness > 0) { - // Neopixels style (Adapted from : https://github.com/microsoft/pxt-adafruit/blob/master/sim/visuals/board.ts) - changeBrightness("brightnessFilterR", brightness); - changeBrightness("brightnessFilterG", brightness); - changeBrightness("brightnessFilterB", brightness); - - let [hue, sat, lum] = SvgStyle.rgbToHsl([ - pixValue[0], - pixValue[1], - pixValue[2] - ]); - const innerLum = Math.max( - lum * SvgStyle.INTENSITY_FACTOR, - SvgStyle.MIN_INNER_LUM - ); - lum = (lum * 90) / 100 + 10; // at least 10% luminosity for the stroke - - led.style.filter = `url(#neopixelglow)`; - led.style.fill = `hsl(${hue}, ${sat}%, ${innerLum}%)`; - led.style.stroke = `hsl(${hue}, ${sat}%, ${Math.min( - lum * 3, - SvgStyle.MAX_STROKE_LUM - )}%)`; - led.style.strokeWidth = `1.5`; - } else { - led.style.fill = SvgStyle.OFF_COLOR; - led.style.filter = `none`; - led.style.stroke = `none`; - } -}; - -const isLightOn = (pixValue: number[]): boolean => { - return !pixValue.every(val => { - return val === 0; - }); -}; - -const changeBrightness = (filterID: string, brightness: number): void => { - const brightnessFilter: HTMLElement | null = window.document.getElementById( - filterID - ); - if (brightnessFilter) { - brightnessFilter.setAttribute("slope", brightness.toString()); - } -}; - -const setupButtons = (props: IProps): void => { - const outButtons = ["A_OUTER", "B_OUTER", "AB_OUTER"]; - const inButtons = ["A_INNER", "B_INNER", "AB_INNER"]; - outButtons.forEach(buttonName => { - const button = window.document.getElementById("BTN_" + buttonName); - - if (button) { - setupButton(button, "sim-button-outer", props); - } - }); - inButtons.forEach(buttonName => { - const button = window.document.getElementById("BTN_" + buttonName); - if (button) { - setupButton(button, "sim-button", props); - } - }); -}; - -const setupPins = (props: IProps): void => { - const pins = [ - "PIN_A1", - "PIN_A2", - "PIN_A3", - "PIN_A4", - "PIN_A5", - "PIN_A6", - "PIN_A7" - ]; - pins.forEach(pinName => { - const pin = window.document.getElementById(pinName); - - if (pin) { - const svgPin = (pin as unknown) as SVGElement; - svg.addClass(svgPin, `sim-${pinName}-touch`); - accessibility.makeFocusable(svgPin); - svgPin.onmouseup = e => props.onMouseUp(pin, e); - svgPin.onkeyup = e => props.onKeyEvent(e, false); - svgPin.onmousedown = e => props.onMouseDown(pin, e); - svgPin.onkeydown = e => props.onKeyEvent(e, true); - accessibility.setAria( - svgPin, - "Pin", - `Touch pin ${pinName.substr(pinName.length - 2)}` - ); - } - }); -}; - -const addButtonLabels = (button: HTMLElement) => { - let label = ""; - if (button.id.match(/AB/) !== null) { - label = "a+b"; - } else if (button.id.match(/A/) !== null) { - label = "a"; - } else if (button.id.match(/B/) !== null) { - label = "b"; - } - accessibility.setAria(button, "button", label); -}; - -const setupButton = (button: HTMLElement, className: string, props: IProps) => { - const svgButton = (button as unknown) as SVGElement; - svg.addClass(svgButton, className); - addButtonLabels(button); - if (className.match(/outer/) !== null) { - accessibility.makeFocusable(svgButton); - } - svgButton.onmousedown = e => props.onMouseDown(button, e); - svgButton.onmouseup = e => props.onMouseUp(button, e); - svgButton.onkeydown = e => 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"); - const swHousingElement = window.document.getElementById("SWITCH_HOUSING"); - - if (switchElement && swInnerElement && swHousingElement) { - const svgSwitch: SVGElement = (switchElement as unknown) as SVGElement; - const svgSwitchInner: SVGElement = (swInnerElement as unknown) as SVGElement; - const svgSwitchHousing: SVGElement = (swHousingElement as unknown) as SVGElement; - - svg.addClass(svgSwitch, "sim-slide-switch"); - - svgSwitch.onmouseup = e => props.onMouseUp(switchElement, e); - svgSwitchInner.onmouseup = e => props.onMouseUp(swInnerElement, e); - svgSwitchHousing.onmouseup = e => props.onMouseUp(swHousingElement, e); - svgSwitch.onkeyup = e => props.onKeyEvent(e, false); - - accessibility.makeFocusable(svgSwitch); - accessibility.setAria(svgSwitch, "button", "On/Off Switch"); - } -}; - -export const updateSwitch = (switchState: boolean): void => { - const switchElement = window.document.getElementById("SWITCH"); - const switchInner = (window.document.getElementById( - "SWITCH_INNER" - ) as unknown) as SVGElement; - - if (switchElement && switchInner) { - svg.addClass(switchInner, "sim-slide-switch-inner"); - - if (switchState) { - svg.addClass(switchInner, "on"); - switchInner.setAttribute("transform", "translate(-5,0)"); - } else { - svg.removeClass(switchInner, "on"); - switchInner.removeAttribute("transform"); - } - switchElement.setAttribute("aria-pressed", switchState.toString()); - } -}; -export const updatePinTouch = (pinState: boolean, id: string): void => { - console.log(`updating ${id} with ${pinState}`); - const pinElement = window.document.getElementById(id); - const pinSvg: SVGElement = (pinElement as unknown) as SVGElement; - - if (pinElement && pinSvg) { - pinElement.setAttribute("aria-pressed", pinState.toString()); - pinState - ? svg.addClass(pinSvg, "pin-pressed") - : svg.removeClass(pinSvg, "pin-pressed"); - } -}; - -export default Cpx; diff --git a/src/view/components/cpx/CpxImage.tsx b/src/view/components/cpx/CpxImage.tsx new file mode 100644 index 000000000..0c74dd936 --- /dev/null +++ b/src/view/components/cpx/CpxImage.tsx @@ -0,0 +1,391 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import CONSTANTS from "../../constants"; +import accessibility from "./Accessibility_utils"; +import CPX_SVG from "./Cpx_svg"; +import * as SvgStyle from "./Cpx_svg_style"; +import svg from "./Svg_utils"; + +interface IProps { + pixels: number[][]; + red_led: boolean; + brightness: number; + switch: boolean; + on: boolean; + onKeyEvent: (event: KeyboardEvent, active: boolean) => void; + onMouseUp: (button: HTMLElement, event: Event) => void; + onMouseDown: (button: HTMLElement, event: Event) => void; + 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; + } + // Update Neopixels and red LED state + updateNeopixels(props); + updateRedLED(props.red_led); + updatePowerLED(props.on); + updateSwitch(props.switch); + } + + return CPX_SVG; +}; + +const makeButton = ( + g: SVGElement, + left: number, + top: number, + id: string +): { outer: SVGElement; inner: SVGElement } => { + const buttonCornerRadius = SvgStyle.BUTTON_CORNER_RADIUS; + const buttonWidth = SvgStyle.BUTTON_WIDTH; + const buttonCircleRadius = SvgStyle.BUTTON_CIRCLE_RADIUS; + const btng = svg.child(g, "g", { class: "sim-button-group" }); + svg.child(btng, "rect", { + fill: SvgStyle.BUTTON_OUTER, + height: buttonWidth, + id: id + "_OUTER", + rx: buttonCornerRadius, + ry: buttonCornerRadius, + width: buttonWidth, + x: left, + y: top, + }); + + const outer = btng; + const inner = svg.child(btng, "circle", { + id: id + "_INNER", + cx: left + buttonWidth / 2, + cy: top + buttonWidth / 2, + r: buttonCircleRadius, + fill: SvgStyle.BUTTON_NEUTRAL, + }); + + return { outer, inner }; +}; + +const initSvgStyle = (svgElement: HTMLElement, brightness: number): void => { + const style: SVGStyleElement = svg.child( + svgElement, + "style", + {} + ) as SVGStyleElement; + style.textContent = SvgStyle.SVG_STYLE; + + // Filters for the glow effect (Adapted from : https://github.com/microsoft/pxt-adafruit/blob/master/sim/visuals/board.ts) + const defs: SVGDefsElement = svg.child( + svgElement, + "defs", + {} + ) as SVGDefsElement; + + const g = svg.createElement("g") as SVGElement; + svgElement.appendChild(g); + + const glow = svg.child(defs, "filter", { + height: "120%", + id: "filterglow", + width: "120%", + x: "-5%", + y: "-5%", + }); + svg.child(glow, "feGaussianBlur", { stdDeviation: "5", result: "glow" }); + const merge = svg.child(glow, "feMerge", {}); + for (let i = 0; i < 3; ++i) { + svg.child(merge, "feMergeNode", { in: "glow" }); + } + + const neopixelglow = svg.child(defs, "filter", { + height: "600%", + id: "neopixelglow", + width: "600%", + x: "-300%", + y: "-300%", + }); + svg.child(neopixelglow, "feGaussianBlur", { + result: "coloredBlur", + stdDeviation: "4.3", + }); + const neopixelmerge = svg.child(neopixelglow, "feMerge", {}); + svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }); + svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }); + svg.child(neopixelmerge, "feMergeNode", { in: "SourceGraphic" }); + + // Brightness + const neopixelfeComponentTransfer = svg.child( + neopixelglow, + "feComponentTransfer", + {} + ); + svg.child(neopixelfeComponentTransfer, "feFuncR", { + id: "brightnessFilterR", + type: "linear", + slope: brightness, + }); + svg.child(neopixelfeComponentTransfer, "feFuncG", { + id: "brightnessFilterG", + slope: brightness, + type: "linear", + }); + svg.child(neopixelfeComponentTransfer, "feFuncB", { + id: "brightnessFilterB", + slope: brightness, + type: "linear", + }); + + // BTN A+B + const outerBtn = (left: number, top: number, label: string) => { + return makeButton(g, left, top, "BTN_AB"); + }; + + const ab = outerBtn(165, SvgStyle.MB_HEIGHT - 15, "A+B"); + const abtext = svg.child(ab.outer, "text", { + class: "sim-text", + x: SvgStyle.BUTTON_TEXT_BASELINE, + y: SvgStyle.MB_HEIGHT - 18, + }) as SVGTextElement; + abtext.textContent = "A+B"; +}; + +const updateNeopixels = (props: IProps): void => { + for (let i = 0; i < props.pixels.length; i++) { + const led = window.document.getElementById(`NEOPIXEL_${i}`); + if (led) { + setNeopixel(led, props.pixels[i], props.brightness); + } + } +}; + +const updateRedLED = (propsRedLED: boolean): void => { + const redLED = window.document.getElementById("SERIAL_LED"); + if (redLED) { + redLED.style.fill = propsRedLED + ? SvgStyle.RED_LED_ON + : SvgStyle.RED_LED_OFF; + } +}; + +const updatePowerLED = (propsPowerLED: boolean): void => { + const powerLED = window.document.getElementById("PWR_LED"); + if (powerLED) { + powerLED.style.fill = propsPowerLED + ? SvgStyle.POWER_LED_ON + : SvgStyle.POWER_LED_OFF; + } +}; + +const setNeopixel = ( + led: HTMLElement, + pixValue: number[], + brightness: number +): void => { + if (isLightOn(pixValue) && brightness > 0) { + // Neopixels style (Adapted from : https://github.com/microsoft/pxt-adafruit/blob/master/sim/visuals/board.ts) + changeBrightness("brightnessFilterR", brightness); + changeBrightness("brightnessFilterG", brightness); + changeBrightness("brightnessFilterB", brightness); + + let [hue, sat, lum] = SvgStyle.rgbToHsl([ + pixValue[0], + pixValue[1], + pixValue[2], + ]); + const innerLum = Math.max( + lum * SvgStyle.INTENSITY_FACTOR, + SvgStyle.MIN_INNER_LUM + ); + lum = (lum * 90) / 100 + 10; // at least 10% luminosity for the stroke + + led.style.filter = `url(#neopixelglow)`; + led.style.fill = `hsl(${hue}, ${sat}%, ${innerLum}%)`; + led.style.stroke = `hsl(${hue}, ${sat}%, ${Math.min( + lum * 3, + SvgStyle.MAX_STROKE_LUM + )}%)`; + led.style.strokeWidth = `1.5`; + } else { + led.style.fill = SvgStyle.OFF_COLOR; + led.style.filter = `none`; + led.style.stroke = `none`; + } +}; + +const isLightOn = (pixValue: number[]): boolean => { + return !pixValue.every(val => { + return val === 0; + }); +}; + +const changeBrightness = (filterID: string, brightness: number): void => { + const brightnessFilter: HTMLElement | null = window.document.getElementById( + filterID + ); + if (brightnessFilter) { + brightnessFilter.setAttribute("slope", brightness.toString()); + } +}; + +const setupButtons = (props: IProps): void => { + const outButtons = ["A_OUTER", "B_OUTER", "AB_OUTER"]; + const inButtons = ["A_INNER", "B_INNER", "AB_INNER"]; + outButtons.forEach(buttonName => { + const button = window.document.getElementById("BTN_" + buttonName); + + if (button) { + setupButton(button, "sim-button-outer", props); + } + }); + inButtons.forEach(buttonName => { + const button = window.document.getElementById("BTN_" + buttonName); + if (button) { + setupButton(button, "sim-button", props); + } + }); +}; + +const setupPins = (props: IProps): void => { + const pins = [ + "PIN_A1", + "PIN_A2", + "PIN_A3", + "PIN_A4", + "PIN_A5", + "PIN_A6", + "PIN_A7", + ]; + pins.forEach(pinName => { + const pin = window.document.getElementById(pinName); + + if (pin) { + const svgPin = (pin as unknown) as SVGElement; + svg.addClass(svgPin, `sim-${pinName}-touch`); + accessibility.makeFocusable(svgPin); + svgPin.onmouseup = e => props.onMouseUp(pin, e); + svgPin.onkeyup = e => props.onKeyEvent(e, false); + svgPin.onmousedown = e => props.onMouseDown(pin, e); + svgPin.onkeydown = e => props.onKeyEvent(e, true); + accessibility.setAria( + svgPin, + "Pin", + `Touch pin ${pinName.substr(pinName.length - 2)}` + ); + } + }); +}; + +const addButtonLabels = (button: HTMLElement) => { + let label = ""; + if (button.id.match(/AB/) !== null) { + label = "a+b"; + } else if (button.id.match(/A/) !== null) { + label = "a"; + } else if (button.id.match(/B/) !== null) { + label = "b"; + } + accessibility.setAria(button, "button", label); +}; + +const setupButton = (button: HTMLElement, className: string, props: IProps) => { + const svgButton = (button as unknown) as SVGElement; + svg.addClass(svgButton, className); + addButtonLabels(button); + if (className.match(/outer/) !== null) { + accessibility.makeFocusable(svgButton); + } + svgButton.onmousedown = e => props.onMouseDown(button, e); + svgButton.onmouseup = e => props.onMouseUp(button, e); + svgButton.onkeydown = e => 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"); + const swHousingElement = window.document.getElementById("SWITCH_HOUSING"); + + if (switchElement && swInnerElement && swHousingElement) { + const svgSwitch: SVGElement = (switchElement as unknown) as SVGElement; + const svgSwitchInner: SVGElement = (swInnerElement as unknown) as SVGElement; + const svgSwitchHousing: SVGElement = (swHousingElement as unknown) as SVGElement; + + svg.addClass(svgSwitch, "sim-slide-switch"); + + svgSwitch.onmouseup = e => props.onMouseUp(switchElement, e); + svgSwitchInner.onmouseup = e => props.onMouseUp(swInnerElement, e); + svgSwitchHousing.onmouseup = e => props.onMouseUp(swHousingElement, e); + svgSwitch.onkeyup = e => props.onKeyEvent(e, false); + + accessibility.makeFocusable(svgSwitch); + accessibility.setAria(svgSwitch, "button", "On/Off Switch"); + } +}; + +export const updateSwitch = (switchState: boolean): void => { + const switchElement = window.document.getElementById("SWITCH"); + const switchInner = (window.document.getElementById( + "SWITCH_INNER" + ) as unknown) as SVGElement; + + if (switchElement && switchInner) { + svg.addClass(switchInner, "sim-slide-switch-inner"); + + if (switchState) { + svg.addClass(switchInner, "on"); + switchInner.setAttribute("transform", "translate(-5,0)"); + } else { + svg.removeClass(switchInner, "on"); + switchInner.removeAttribute("transform"); + } + switchElement.setAttribute("aria-pressed", switchState.toString()); + } +}; +export const updatePinTouch = (pinState: boolean, id: string): void => { + console.log(`updating ${id} with ${pinState}`); + const pinElement = window.document.getElementById(id); + const pinSvg: SVGElement = (pinElement as unknown) as SVGElement; + + if (pinElement && pinSvg) { + pinElement.setAttribute("aria-pressed", pinState.toString()); + pinState + ? svg.addClass(pinSvg, "pin-pressed") + : svg.removeClass(pinSvg, "pin-pressed"); + } +}; + +export default CpxImage; diff --git a/src/view/components/cpx/Cpx_svg.tsx b/src/view/components/cpx/Cpx_svg.tsx index a1f8cf973..55864d460 100644 --- a/src/view/components/cpx/Cpx_svg.tsx +++ b/src/view/components/cpx/Cpx_svg.tsx @@ -6,2964 +6,2997 @@ import * as React from "react"; export const CPX_SVG = ( - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + ); export default CPX_SVG; diff --git a/src/view/components/cpx/Cpx_svg_style.tsx b/src/view/components/cpx/Cpx_svg_style.tsx index f0fb41f9d..72ba0e18a 100644 --- a/src/view/components/cpx/Cpx_svg_style.tsx +++ b/src/view/components/cpx/Cpx_svg_style.tsx @@ -24,44 +24,45 @@ export const POWER_LED_OFF: string = "#FFFFFF"; // Adapted from : https://github.com/microsoft/pxt/blob/master/pxtsim/simlib.ts export function rgbToHsl( - rgb: [number, number, number] + rgb: [number, number, number] ): [number, number, number] { - let [r, g, b] = rgb; - let [r$, g$, b$] = [r / 255, g / 255, b / 255]; - let cMin = Math.min(r$, g$, b$); - let cMax = Math.max(r$, g$, b$); - let cDelta = cMax - cMin; - let h: number = 0, - s: number, - l: number; - let maxAndMin = cMax + cMin; + const [r, g, b] = rgb; + const [r$, g$, b$] = [r / 255, g / 255, b / 255]; + const cMin = Math.min(r$, g$, b$); + const cMax = Math.max(r$, g$, b$); + const cDelta = cMax - cMin; + let h: number = 0, + s: number, + l: number; + const maxAndMin = cMax + cMin; - // Luminosity - l = (maxAndMin / 2) * 100; + // Luminosity + l = (maxAndMin / 2) * 100; - if (cDelta === 0) { - s = 0; - h = 0; - } else { - // Hue - switch (cMax) { - case r$: - h = 60 * (((g$ - b$) / cDelta) % 6); - break; - case g$: - h = 60 * ((b$ - r$) / cDelta + 2); - break; - case b$: - h = 60 * ((r$ - g$) / cDelta + 4); - break; - } + if (cDelta === 0) { + s = 0; + h = 0; + } else { + // Hue + switch (cMax) { + case r$: + h = 60 * (((g$ - b$) / cDelta) % 6); + break; + case g$: + h = 60 * ((b$ - r$) / cDelta + 2); + break; + case b$: + h = 60 * ((r$ - g$) / cDelta + 4); + break; + } - // Saturation - if (l > 50) s = 100 * (cDelta / (2 - maxAndMin)); - else s = 100 * (cDelta / maxAndMin); - } + // Saturation + l > 50 + ? (s = 100 * (cDelta / (2 - maxAndMin))) + : (s = 100 * (cDelta / maxAndMin)); + } - return [Math.floor(h), Math.floor(s), Math.floor(l)]; + return [Math.floor(h), Math.floor(s), Math.floor(l)]; } export const SVG_STYLE = ` diff --git a/src/view/components/cpx/Svg_utils.tsx b/src/view/components/cpx/Svg_utils.tsx index faff4c682..b80e66165 100644 --- a/src/view/components/cpx/Svg_utils.tsx +++ b/src/view/components/cpx/Svg_utils.tsx @@ -4,70 +4,70 @@ // Adapted from : https://github.com/microsoft/pxt/blob/master/pxtsim/svg.ts namespace svg { - export function addClass(el: SVGElement, cls: string) { - if (el.classList) el.classList.add(cls); - else if (el.className.baseVal.indexOf(cls) < 0) - el.className.baseVal += " " + cls; - } + export function addClass(el: SVGElement, cls: string) { + 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 - el.className.baseVal = el.className.baseVal - .replace(cls, "") - .replace(/\s{2,}/, " "); - } + export function removeClass(el: SVGElement, cls: string) { + 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) { - if (k == "title") { - svg.title(el, props[k]); - } else el.setAttributeNS(null, k, props[k]); + export function hydrate(el: SVGElement, props: any) { + for (let k in props) { + if (k == "title") { + svg.title(el, props[k]); + } else el.setAttributeNS(null, k, props[k]); + } } - } - export function createElement(name: string, props?: any): SVGElement { - let newElement = document.createElementNS( - "http://www.w3.org/2000/svg", - name - ); - if (props) svg.hydrate(newElement, props); - return newElement; - } + export function createElement(name: string, props?: any): SVGElement { + let newElement = document.createElementNS( + "http://www.w3.org/2000/svg", + name + ); + if (props) svg.hydrate(newElement, props); + return newElement; + } - export function child( - parent: Element, - name: string, - props?: any - ): SVGElement { - let childElement = svg.createElement(name, props); - parent.appendChild(childElement); - return childElement; - } + export function child( + parent: Element, + name: string, + props?: any + ): SVGElement { + let childElement = svg.createElement(name, props); + parent.appendChild(childElement); + return childElement; + } - export function fill(el: SVGElement, c: string) { - el.style.fill = c; - } + export function fill(el: SVGElement, c: string) { + el.style.fill = c; + } - export function filter(el: SVGElement, c: string) { - el.style.filter = c; - } + export function filter(el: SVGElement, c: string) { + el.style.filter = c; + } - export function fills(els: SVGElement[], c: string) { - els.forEach(el => (el.style.fill = c)); - } + export function fills(els: SVGElement[], c: string) { + els.forEach(el => (el.style.fill = c)); + } - export function mkTitle(txt: string): SVGTitleElement { - let t = svg.createElement("title") as SVGTitleElement; - t.textContent = txt; - return t; - } + export function mkTitle(txt: string): SVGTitleElement { + let t = svg.createElement("title") as SVGTitleElement; + t.textContent = txt; + return t; + } - export function title(el: SVGElement, txt: string): SVGTitleElement { - let t = mkTitle(txt); - el.appendChild(t); - return t; - } + export function title(el: SVGElement, txt: string): SVGTitleElement { + let t = mkTitle(txt); + el.appendChild(t); + return t; + } } export default svg; diff --git a/src/view/components/simulator/ActionBar.tsx b/src/view/components/simulator/ActionBar.tsx new file mode 100644 index 000000000..2188555b2 --- /dev/null +++ b/src/view/components/simulator/ActionBar.tsx @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import { CONSTANTS } from "../../constants"; +import RefreshLogo from "../../svgs/refresh_svg"; +import Button from "../Button"; + +interface IProps { + onTogglePlay: (event: React.MouseEvent) => void; + onToggleRefresh: (event: React.MouseEvent) => void; + playStopImage: JSX.Element; +} + +// Component including the actions done on the Simulator (play/stop, refresh) + +class ActionBar extends React.Component { + public render() { + const { onTogglePlay, onToggleRefresh, playStopImage } = this.props; + return ( +
+
+ ); + } +} +export default ActionBar; diff --git a/src/view/components/toolbar/InputSlider.tsx b/src/view/components/toolbar/InputSlider.tsx index 56eaba400..52bb643b9 100644 --- a/src/view/components/toolbar/InputSlider.tsx +++ b/src/view/components/toolbar/InputSlider.tsx @@ -6,136 +6,141 @@ import "../../styles/InputSlider.css"; import { ISliderProps } from "../../viewUtils"; interface vscode { - postMessage(message: any): void; + postMessage(message: any): void; } declare const vscode: vscode; const sendMessage = (state: any) => { - vscode.postMessage({ command: "sensor-changed", text: state }); + vscode.postMessage({ command: "sensor-changed", text: state }); }; class InputSlider extends React.Component { - constructor(props: ISliderProps) { - super(props); - this.state = { - value: 0 + constructor(props: ISliderProps) { + super(props); + this.state = { + value: 0, + }; + + this.handleOnChange = this.handleOnChange.bind(this); + this.validateRange = this.validateRange.bind(this); + } + + handleMessage = (event: any): void => { + const message = event.data; // The JSON data our extension sent + switch (message.command) { + case "reset-state": + this.setState({ value: 0 }); + break; + case "set-state": + console.log( + "Setting the state: " + JSON.stringify(message.state) + ); + break; + default: + console.log("Invalid message received from the extension."); + this.setState({ value: 0 }); + break; + } }; - this.handleOnChange = this.handleOnChange.bind(this); - this.validateRange = this.validateRange.bind(this); - } - - handleMessage = (event: any): void => { - const message = event.data; // The JSON data our extension sent - switch (message.command) { - case "reset-state": - this.setState({ value: 0 }); - break; - case "set-state": - console.log("Setting the state: " + JSON.stringify(message.state)); - break; - default: - console.log("Invalid message received from the extension."); - this.setState({ value: 0 }); - break; + componentDidMount() { + console.log("Mounted"); + window.addEventListener("message", this.handleMessage); } - }; - - componentDidMount() { - console.log("Mounted"); - window.addEventListener("message", this.handleMessage); - } - - componentWillUnmount() { - // Make sure to remove the DOM listener when the component is unmounted. - window.removeEventListener("message", this.handleMessage); - } - render() { - return ( -
- {this.props.axisLabel} - - - - {this.props.minValue} - {this.props.maxValue} - - - - {this.props.minLabel} - {this.props.maxLabel} - - -
- ); - } - - private handleOnChange = (event: any) => { - const validatedValue = this.validateRange(this.updateValue(event)); - const newSensorState = this.writeMessage(validatedValue); - if (newSensorState) { - sendMessage(newSensorState); - } - }; - private writeMessage = (valueTowrite: number) => { - let value = valueTowrite; - if (value > this.props.maxValue || value < this.props.minValue) { - value = parseInt(this.state.value, 10); + componentWillUnmount() { + // Make sure to remove the DOM listener when the component is unmounted. + window.removeEventListener("message", this.handleMessage); } - - return this.props.type && this.state.value !== undefined - ? { [this.props.type]: value } - : undefined; - }; - - private updateValue = (event: any) => { - const newValue = event.target.validity.valid - ? event.target.value - : this.state.value; - this.setState({ value: newValue }); - return newValue; - }; - - private sendTelemetry = () => { - vscode.postMessage({ command: "slider-telemetry", text: this.props.type }); - }; - - private validateRange = (valueString: string) => { - let valueInt = parseInt(valueString, 10); - if (valueInt < this.props.minValue) { - valueInt = this.props.minValue; - this.setState({ value: valueInt }); - } else if (valueInt > this.props.maxValue) { - valueInt = this.props.maxValue; - this.setState({ value: valueInt }); + render() { + return ( +
+ {this.props.axisLabel} + + + + {this.props.minValue} + {this.props.maxValue} + + + + {this.props.minLabel} + {this.props.maxLabel} + + +
+ ); } - return valueInt; - }; + + private handleOnChange = (event: any) => { + const validatedValue = this.validateRange(this.updateValue(event)); + const newSensorState = this.writeMessage(validatedValue); + if (newSensorState) { + sendMessage(newSensorState); + } + }; + + private writeMessage = (valueTowrite: number) => { + let value = valueTowrite; + if (value > this.props.maxValue || value < this.props.minValue) { + value = parseInt(this.state.value, 10); + } + + return this.props.type && this.state.value !== undefined + ? { [this.props.type]: value } + : undefined; + }; + + private updateValue = (event: any) => { + const newValue = event.target.validity.valid + ? event.target.value + : this.state.value; + this.setState({ value: newValue }); + return newValue; + }; + + private sendTelemetry = () => { + vscode.postMessage({ + command: "slider-telemetry", + text: this.props.type, + }); + }; + + private validateRange = (valueString: string) => { + let valueInt = parseInt(valueString, 10); + if (valueInt < this.props.minValue) { + valueInt = this.props.minValue; + this.setState({ value: valueInt }); + } else if (valueInt > this.props.maxValue) { + valueInt = this.props.maxValue; + this.setState({ value: valueInt }); + } + return valueInt; + }; } export default InputSlider; diff --git a/src/view/components/toolbar/LightSensorBar.tsx b/src/view/components/toolbar/LightSensorBar.tsx index 5ff52c64a..3ecb69025 100644 --- a/src/view/components/toolbar/LightSensorBar.tsx +++ b/src/view/components/toolbar/LightSensorBar.tsx @@ -2,54 +2,61 @@ // Licensed under the MIT license. import * as React from "react"; -import InputSlider from "./InputSlider"; import "../../styles/LightSensorBar.css"; import { ISensorProps, ISliderProps, X_SLIDER_INDEX } from "../../viewUtils"; +import InputSlider from "./InputSlider"; const LIGHT_SLIDER_PROPS: ISliderProps = { - maxValue: 255, - minValue: 0, - minLabel: "Dark", - maxLabel: "Bright", - type: "light", - axisLabel: " " + maxValue: 255, + minValue: 0, + minLabel: "Dark", + maxLabel: "Bright", + type: "light", + axisLabel: " ", }; const LIGHT_SENSOR_PROPERTIES: ISensorProps = { - LABEL: "Light sensor", - sliderProps: [LIGHT_SLIDER_PROPS], - unitLabel: "Lux" + LABEL: "Light sensor", + sliderProps: [LIGHT_SLIDER_PROPS], + unitLabel: "Lux", }; class LightSensorBar extends React.Component { - constructor(props: any) { - super(props); - } + constructor(props: any) { + super(props); + } - render() { - return ( -
- -
- ); - } + render() { + return ( +
+ +
+ ); + } } export default LightSensorBar; diff --git a/src/view/components/toolbar/MotionSensorBar.tsx b/src/view/components/toolbar/MotionSensorBar.tsx index 3dcdba145..db1f1a020 100644 --- a/src/view/components/toolbar/MotionSensorBar.tsx +++ b/src/view/components/toolbar/MotionSensorBar.tsx @@ -4,163 +4,209 @@ import * as React from "react"; import InputSlider from "./InputSlider"; import SensorButton from "./SensorButton"; +import svg from "../cpx/Svg_utils"; +import { CONSTANTS } from "../../constants"; +import "../../styles/MotionSensorBar.css"; import { - ISensorProps, - ISliderProps, - X_SLIDER_INDEX, - Z_SLIDER_INDEX, - Y_SLIDER_INDEX + ISensorProps, + ISliderProps, + X_SLIDER_INDEX, + Y_SLIDER_INDEX, + Z_SLIDER_INDEX, } from "../../viewUtils"; -import "../../styles/MotionSensorBar.css"; -import { CONSTANTS } from "../../constants"; interface vscode { - postMessage(message: any): void; + postMessage(message: any): void; } declare const vscode: vscode; const sendMessage = (state: any) => { - vscode.postMessage({ command: "sensor-changed", text: state }); + vscode.postMessage({ command: "sensor-changed", text: state }); }; const MOTION_SLIDER_PROPS_X: ISliderProps = { - axisLabel: "X", - maxLabel: "Right", - maxValue: 78, - minLabel: "Left", - minValue: -78, - type: "motion_x" + axisLabel: "X", + maxLabel: "Right", + maxValue: 78, + minLabel: "Left", + minValue: -78, + type: "motion_x", }; const MOTION_SLIDER_PROPS_Y: ISliderProps = { - axisLabel: "Y", - maxLabel: "Front", - maxValue: 78, - minLabel: "Back", - minValue: -78, - type: "motion_y" + axisLabel: "Y", + maxLabel: "Front", + maxValue: 78, + minLabel: "Back", + minValue: -78, + type: "motion_y", }; const MOTION_SLIDER_PROPS_Z: ISliderProps = { - maxValue: 78, - minValue: -78, - minLabel: "Up", - maxLabel: "Down", - type: "motion_z", - axisLabel: "Z" + maxValue: 78, + minValue: -78, + minLabel: "Up", + maxLabel: "Down", + type: "motion_z", + axisLabel: "Z", }; const MOTION_SENSOR_PROPERTIES: ISensorProps = { - LABEL: "Motion sensor", - sliderProps: [ - MOTION_SLIDER_PROPS_X, - MOTION_SLIDER_PROPS_Y, - MOTION_SLIDER_PROPS_Z - ], - unitLabel: "Lux" + LABEL: "Motion sensor", + sliderProps: [ + MOTION_SLIDER_PROPS_X, + MOTION_SLIDER_PROPS_Y, + MOTION_SLIDER_PROPS_Z, + ], + unitLabel: "Lux", }; class MotionSensorBar extends React.Component { - constructor(props: any) { - super(props); - } - - render() { - return ( -
- -
- -
- -
- -
-
- ); - } - - private onMouseDown = () => this.handleOnclick(true, "shake"); - - private onKeyUp = (event: React.KeyboardEvent) => - this.onKeyEvent(event, false); - - private onKeyDown = (event: React.KeyboardEvent) => - this.onKeyEvent(event, true); - - private onMouseUp = () => this.handleOnclick(false, "shake"); - - private handleOnclick = (active: boolean, type: string) => { - const messageState = { [type]: active }; - sendMessage(messageState); - }; - - private onKeyEvent( - event: React.KeyboardEvent, - active: boolean - ) { - if ([event.keyCode, event.key].includes(CONSTANTS.KEYBOARD_KEYS.ENTER)) { - this.handleOnclick(active, "shake"); + constructor(props: any) { + super(props); } - } + + render() { + return ( +
+ +
+ +
+ +
+ +
+
+ ); + } + + private onMouseDown = (event: React.PointerEvent) => { + this.updateShakePress(true, event.currentTarget.id); + this.handleOnclick(true, "shake"); + }; + + private onKeyUp = (event: React.KeyboardEvent) => + this.onKeyEvent(event, false); + + private onKeyDown = (event: React.KeyboardEvent) => + this.onKeyEvent(event, true); + + private onMouseUp = (event: React.PointerEvent) => { + this.updateShakePress(false, event.currentTarget.id); + this.handleOnclick(false, "shake"); + }; + + private handleOnclick = (active: boolean, type: string) => { + const messageState = { [type]: active }; + sendMessage(messageState); + }; + + private onKeyEvent( + event: React.KeyboardEvent, + active: boolean + ) { + if ( + [event.keyCode, event.key].includes(CONSTANTS.KEYBOARD_KEYS.ENTER) + ) { + this.handleOnclick(active, "shake"); + } + } + + private updateShakePress = (shakeState: boolean, id: string): void => { + const svgElement = window.document.getElementById("cpx_svg"); + const buttonElement = window.document.getElementById(id); + const cpxSvg: SVGElement = (svgElement as unknown) as SVGElement; + + if (svgElement && cpxSvg && buttonElement) { + buttonElement.setAttribute("aria-pressed", shakeState.toString()); + shakeState + ? svg.addClass(cpxSvg, "shake-pressed") + : svg.removeClass(cpxSvg, "shake-pressed"); + } + }; } export default MotionSensorBar; diff --git a/src/view/components/toolbar/SensorButton.tsx b/src/view/components/toolbar/SensorButton.tsx index 8726cf1a4..03bb9a8dd 100644 --- a/src/view/components/toolbar/SensorButton.tsx +++ b/src/view/components/toolbar/SensorButton.tsx @@ -2,22 +2,23 @@ // Licensed under the MIT license. import * as React from "react"; -import { ISensorButtonProps } from "../../viewUtils"; import "../../styles/SensorButton.css"; +import { ISensorButtonProps } from "../../viewUtils"; const SensorButton: React.FC = props => { - return ( - - ); + return ( + + ); }; export default SensorButton; diff --git a/src/view/components/toolbar/SensorModalUtils.tsx b/src/view/components/toolbar/SensorModalUtils.tsx new file mode 100644 index 000000000..134e7dcc1 --- /dev/null +++ b/src/view/components/toolbar/SensorModalUtils.tsx @@ -0,0 +1,197 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import * as React from "react"; +import { ARROW_RIGHT_SVG } from "../../svgs/arrow_right_svg"; +import { TAG_INPUT_SVG } from "../../svgs/tag_input_svg"; +import { TAG_OUTPUT_SVG } from "../../svgs/tag_output_svg"; +import LightSensorBar from "./LightSensorBar"; +import MotionSensorBar from "./MotionSensorBar"; +import TemperatureSensorBar from "./TemperatureSensorBar"; + +export const TRY_IT_MAKE_CODE = ( + +); + +export const TOOLBAR_ICON_LABEL = { + GPIO: "GPIO", + IR: "IR", + LEFT_EDGE: "left-edge", + LIGHT: "Light sensor", + MOTION: "Motion Sensor", + NEO_PIXEL: "Neo Pixels", + PUSH_BUTTON: "Push Button", + RED_LED: "Red LED", + RIGHT_EDGE: "right-edge", + SOUND: "Sound Sensor", + SPEAKER: "Speaker", + SWITCH: "Switch", + TAG_INPUT: "Tag Input", + TAG_OUTPUT: "Tag Output", + TEMPERATURE: "Temperature Sensor", +}; +export const TOOLBAR_ICON_ID = { + GPIO: "toolbar-gpio", + IR: "toolbar-ir-sensor", + LEFT_EDGE: "left-edge", + LIGHT: "toolbar-light-sensor", + MOTION: "toolbar-motion-sensor", + NEO_PIXEL: "toolbar-neo-pixels", + PUSH_BUTTON: "toolbar-push-button", + RED_LED: "toolbar-red-led", + RIGHT_EDGE: "right-edge", + SOUND: "toolbar-sound-sensor", + SPEAKER: "toolbar-speaker", + SWITCH: "toolbar-slider-switch", + TEMPERATURE: "toolbar-temperature-sensor", +}; + +export interface IModalContent { + component: any; + descriptionText: string; + descriptionTitle: string; + id: string; + tagInput: any; + tagOutput: any; + tryItDescription: string; + tryItTitle: string; +} + +export const DEFAULT_MODAL_CONTENT: IModalContent = { + descriptionTitle: "default", + tagInput: undefined, + tagOutput: undefined, + descriptionText: "none", + tryItTitle: "none", + tryItDescription: "none", + component: undefined, + id: "none", +}; +export const GPIO_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-gpio.title", + tagInput: TAG_INPUT_SVG, + tagOutput: TAG_OUTPUT_SVG, + descriptionText: "toolbar-gpio.description", + tryItTitle: "Simulation Coming Soon!", + tryItDescription: "toolbar-gpio.tryItDescription", + component: undefined, + id: "GPIO", +}; + +export const IR_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-ir-sensor.title", + tagInput: TAG_INPUT_SVG, + tagOutput: TAG_OUTPUT_SVG, + descriptionText: "toolbar-ir-sensor.description", + tryItTitle: "Simulation Coming Soon!", + tryItDescription: "toolbar-ir-sensor.tryItDescription", + component: TRY_IT_MAKE_CODE, + id: "IR", +}; +export const LIGHT_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-light-sensor.title", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + descriptionText: "toolbar-light-sensor.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-light-sensor.tryItDescription", + component: , + id: "light_sensor", +}; +export const MOTION_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-motion-sensor.title", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + descriptionText: "toolbar-motion-sensor.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-motion-sensor.tryItDescription", + component: , + id: "motion_sensor", +}; +export const NEOP_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-neo-pixels.title", + tagInput: undefined, + tagOutput: TAG_OUTPUT_SVG, + descriptionText: "toolbar-neo-pixels.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-neo-pixels.tryItDescription", + component: undefined, + id: "neon_pixel", +}; +export const PUSHB_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-push-button.title", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + descriptionText: "toolbar-push-button.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-push-button.tryItDescription", + component: undefined, + id: "push_btn", +}; +export const RED_LED_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-red-led.title", + tagInput: undefined, + tagOutput: TAG_OUTPUT_SVG, + descriptionText: "toolbar-red-led.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-red-led.tryItDescription", + component: undefined, + id: "red_LED", +}; +export const SOUND_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-sound-sensor.title", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + descriptionText: "toolbar-sound-sensor.description", + tryItTitle: "Simulation Coming Soon!", + tryItDescription: "toolbar-sound-sensor.tryItDescription", + component: TRY_IT_MAKE_CODE, + id: "sound_sensor", +}; +export const SWITCH_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-slider-switch.title", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + descriptionText: "toolbar-slider-switch.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-slider-switch.tryItDescription", + component: undefined, + id: "slider_switch", +}; +export const SPEAKER_MODAL_CONTENT: IModalContent = { + descriptionTitle: "toolbar-speaker.title", + tagInput: undefined, + tagOutput: TAG_OUTPUT_SVG, + descriptionText: "toolbar-speaker.description", + tryItTitle: "Try it on the Simulator!", + tryItDescription: "toolbar-speaker.tryItDescription", + component: undefined, + id: "speaker", +}; +export const TEMPERATURE_MODAL_CONTENT: IModalContent = { + component: , + descriptionText: "toolbar-temperature-sensor.description", + descriptionTitle: "toolbar-temperature-sensor.title", + id: "temperature", + tagInput: TAG_INPUT_SVG, + tagOutput: undefined, + tryItDescription: "toolbar-temperature-sensor.tryItDescription", + tryItTitle: "Try it on the Simulator!", +}; + +export const LABEL_TO_MODAL_CONTENT = new Map([ + [TOOLBAR_ICON_ID.GPIO, GPIO_MODAL_CONTENT], + [TOOLBAR_ICON_ID.IR, IR_MODAL_CONTENT], + [TOOLBAR_ICON_ID.LIGHT, LIGHT_MODAL_CONTENT], + [TOOLBAR_ICON_ID.MOTION, MOTION_MODAL_CONTENT], + [TOOLBAR_ICON_ID.NEO_PIXEL, NEOP_MODAL_CONTENT], + [TOOLBAR_ICON_ID.PUSH_BUTTON, PUSHB_MODAL_CONTENT], + [TOOLBAR_ICON_ID.RED_LED, RED_LED_MODAL_CONTENT], + [TOOLBAR_ICON_ID.SOUND, SOUND_MODAL_CONTENT], + [TOOLBAR_ICON_ID.SPEAKER, SPEAKER_MODAL_CONTENT], + [TOOLBAR_ICON_ID.SWITCH, SWITCH_MODAL_CONTENT], + [TOOLBAR_ICON_ID.TEMPERATURE, TEMPERATURE_MODAL_CONTENT], +]); diff --git a/src/view/components/toolbar/TemperatureSensorBar.tsx b/src/view/components/toolbar/TemperatureSensorBar.tsx index d5ca66a1f..2c396494f 100644 --- a/src/view/components/toolbar/TemperatureSensorBar.tsx +++ b/src/view/components/toolbar/TemperatureSensorBar.tsx @@ -2,53 +2,67 @@ // Licensed under the MIT license. import * as React from "react"; -import InputSlider from "./InputSlider"; -import { ISensorProps, ISliderProps, X_SLIDER_INDEX } from "../../viewUtils"; import "../../styles/TemperatureSensorBar.css"; +import { ISensorProps, ISliderProps, X_SLIDER_INDEX } from "../../viewUtils"; +import InputSlider from "./InputSlider"; const TEMPERATURE_SLIDER_PROPS: ISliderProps = { - axisLabel: " ", - maxLabel: "Hot", - maxValue: 125, - minLabel: "Cold", - minValue: -55, - type: "temperature" + axisLabel: " ", + maxLabel: "Hot", + maxValue: 125, + minLabel: "Cold", + minValue: -55, + type: "temperature", }; const TEMPERATURE_SENSOR_PROPERTIES: ISensorProps = { - LABEL: "Temperature sensor", - sliderProps: [TEMPERATURE_SLIDER_PROPS], - unitLabel: "°C" + LABEL: "Temperature sensor", + sliderProps: [TEMPERATURE_SLIDER_PROPS], + unitLabel: "°C", }; class TemperatureSensorBar extends React.Component { - constructor(props: any) { - super(props); - } + constructor(props: any) { + super(props); + } - render() { - return ( -
- -
- ); - } + render() { + return ( +
+ +
+ ); + } } export default TemperatureSensorBar; diff --git a/src/view/components/toolbar/ToolBar.tsx b/src/view/components/toolbar/ToolBar.tsx index 860d2f75c..88b064261 100644 --- a/src/view/components/toolbar/ToolBar.tsx +++ b/src/view/components/toolbar/ToolBar.tsx @@ -1,265 +1,159 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. import * as React from "react"; -import Button from "../Button"; -import * as TOOLBAR_SVG from "../../svgs/toolbar_svg"; +import { + FormattedMessage, + injectIntl, + WrappedComponentProps, +} from "react-intl"; import "../../styles/ToolBar.css"; +import Button from "../Button"; import { - LABEL_TO_MODAL_CONTENT, - DEFAULT_MODAL_CONTENT, - IModalContent, - TOOLBAR_ICON_ID -} from "./sensorModalUtils"; -import { FormattedMessage, injectIntl } from "react-intl"; + DEFAULT_MODAL_CONTENT, + IModalContent, + LABEL_TO_MODAL_CONTENT, +} from "./SensorModalUtils"; interface IToolbarState { - currentOpenedId: string; - showModal: boolean; + currentOpenedId: string; + showModal: boolean; } -class ToolBar extends React.Component { - private readonly TOOLBAR_BUTTON_WIDTH: number = 32; - private readonly TOOLBAR_EDGE_WIDTH: number = 8; - - constructor(props: any) { - super(props); - this.state = { - currentOpenedId: "", - showModal: false - }; - } - - render() { - return ( -
-
-
-
- {this.getIconModal()} -
-
- ); - } +class ToolBar extends React.Component { + private readonly TOOLBAR_BUTTON_WIDTH: number = 32; - private handleOnClick = ( - event: React.MouseEvent, - label: string - ) => { - if ( - !this.state.showModal && - this.state.currentOpenedId === "" && - this.state.currentOpenedId !== label - ) { - this.openModal(label); - } else { - this.closeCurrentModal(); - if (this.state.currentOpenedId !== label) { - this.openModal(label); - } + constructor(props: IProps) { + super(props); + this.state = { + currentOpenedId: "", + showModal: false, + }; } - }; - private changePressedState(id: string, pressed: boolean) { - const elt = window.document.getElementById(`${id}-button`); - if (elt) { - pressed - ? elt.classList.add("button-pressed") - : elt.classList.remove("button-pressed"); + public render() { + const { buttonList } = this.props; + return ( +
+
+
+ {buttonList.map( + (currrentButton: any, index: number) => { + return ( +
+ {this.getIconModal()} +
+
+ ); } - } - private closeCurrentModal = () => { - this.changePressedState(this.state.currentOpenedId, false); - this.setState({ - currentOpenedId: "", - showModal: false - }); - }; - private openModal = (label: string) => { - this.setState({ - currentOpenedId: label, - showModal: true - }); - this.changePressedState(label, true); - }; + private handleOnClick = ( + event: React.MouseEvent, + label: string + ) => { + if ( + !this.state.showModal && + this.state.currentOpenedId === "" && + this.state.currentOpenedId !== label + ) { + this.openModal(label); + } else { + this.closeCurrentModal(); + if (this.state.currentOpenedId !== label) { + this.openModal(label); + } + } + }; - private getIconModal() { - if ( - !this.state.showModal || - !LABEL_TO_MODAL_CONTENT.get(this.state.currentOpenedId) - ) { - return null; + private changePressedState(id: string, pressed: boolean) { + const elt = window.document.getElementById(`${id}-button`); + if (elt) { + pressed + ? elt.classList.add("button-pressed") + : elt.classList.remove("button-pressed"); + } } + private closeCurrentModal = () => { + this.changePressedState(this.state.currentOpenedId, false); + this.setState({ + currentOpenedId: "", + showModal: false, + }); + }; - const content = LABEL_TO_MODAL_CONTENT.get( - this.state.currentOpenedId - ) as IModalContent; - - const component = content - ? content["component"] - : DEFAULT_MODAL_CONTENT.component; - return ( -
-
- - - {content["tagInput"]} - {content["tagOutput"]} - -
-
-
- -
-
-
- - - -
+ private openModal = (label: string) => { + this.setState({ + currentOpenedId: label, + showModal: true, + }); + this.changePressedState(label, true); + }; -
{component}
-
-
- ); - } + private getIconModal() { + if ( + !this.state.showModal || + !LABEL_TO_MODAL_CONTENT.get(this.state.currentOpenedId) + ) { + return null; + } + + const content = LABEL_TO_MODAL_CONTENT.get( + this.state.currentOpenedId + ) as IModalContent; + + const component = content + ? content.component + : DEFAULT_MODAL_CONTENT.component; + return ( +
+
+ + + {content.tagInput} + {content.tagOutput} + +
+
+
+ +
+
+
+ + + +
+ +
{component}
+
+
+ ); + } } export default injectIntl(ToolBar); diff --git a/src/view/components/toolbar/sensorModalUtils.tsx b/src/view/components/toolbar/sensorModalUtils.tsx deleted file mode 100644 index cb4c60665..000000000 --- a/src/view/components/toolbar/sensorModalUtils.tsx +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -import LightSensorBar from "./LightSensorBar"; -import TemperatureSensorBar from "./TemperatureSensorBar"; -import MotionSensorBar from "./MotionSensorBar"; -import * as React from "react"; -import { TAG_INPUT_SVG } from "../../svgs/tag_input_svg"; -import { TAG_OUTPUT_SVG } from "../../svgs/tag_output_svg"; -import { ARROW_RIGHT_SVG } from "../../svgs/arrow_right_svg"; - -export const TRY_IT_MAKE_CODE = ( - -); - -export const TOOLBAR_ICON_LABEL = { - GPIO: "GPIO", - IR: "IR", - LEFT_EDGE: "left-edge", - LIGHT: "Light sensor", - MOTION: "Motion Sensor", - NEO_PIXEL: "Neo Pixels", - PUSH_BUTTON: "Push Button", - RED_LED: "Red LED", - RIGHT_EDGE: "right-edge", - SOUND: "Sound Sensor", - SPEAKER: "Speaker", - SWITCH: "Switch", - TAG_INPUT: "Tag Input", - TAG_OUTPUT: "Tag Output", - TEMPERATURE: "Temperature Sensor" -}; -export const TOOLBAR_ICON_ID = { - GPIO: "toolbar-gpio", - IR: "toolbar-ir-sensor", - LEFT_EDGE: "left-edge", - LIGHT: "toolbar-light-sensor", - MOTION: "toolbar-motion-sensor", - NEO_PIXEL: "toolbar-neo-pixels", - PUSH_BUTTON: "toolbar-push-button", - RED_LED: "toolbar-red-led", - RIGHT_EDGE: "right-edge", - SOUND: "toolbar-sound-sensor", - SPEAKER: "toolbar-speaker", - SWITCH: "toolbar-slider-switch", - TEMPERATURE: "toolbar-temperature-sensor" -}; - -export interface IModalContent { - component: any; - descriptionText: string; - descriptionTitle: string; - id: string; - tagInput: any; - tagOutput: any; - tryItDescription: string; - tryItTitle: string; -} - -export const DEFAULT_MODAL_CONTENT: IModalContent = { - descriptionTitle: "default", - tagInput: undefined, - tagOutput: undefined, - descriptionText: "none", - tryItTitle: "none", - tryItDescription: "none", - component: undefined, - id: "none" -}; -export const GPIO_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-gpio.title", - tagInput: TAG_INPUT_SVG, - tagOutput: TAG_OUTPUT_SVG, - descriptionText: "toolbar-gpio.description", - tryItTitle: "Simulation Coming Soon!", - tryItDescription: "toolbar-gpio.tryItDescription", - component: undefined, - id: "GPIO" -}; - -export const IR_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-ir-sensor.title", - tagInput: TAG_INPUT_SVG, - tagOutput: TAG_OUTPUT_SVG, - descriptionText: "toolbar-ir-sensor.description", - tryItTitle: "Simulation Coming Soon!", - tryItDescription: "toolbar-ir-sensor.tryItDescription", - component: TRY_IT_MAKE_CODE, - id: "IR" -}; -export const LIGHT_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-light-sensor.title", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - descriptionText: "toolbar-light-sensor.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-light-sensor.tryItDescription", - component: , - id: "light_sensor" -}; -export const MOTION_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-motion-sensor.title", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - descriptionText: "toolbar-motion-sensor.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-motion-sensor.tryItDescription", - component: , - id: "motion_sensor" -}; -export const NEOP_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-neo-pixels.title", - tagInput: undefined, - tagOutput: TAG_OUTPUT_SVG, - descriptionText: "toolbar-neo-pixels.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-neo-pixels.tryItDescription", - component: undefined, - id: "neon_pixel" -}; -export const PUSHB_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-push-button.title", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - descriptionText: "toolbar-push-button.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-push-button.tryItDescription", - component: undefined, - id: "push_btn" -}; -export const RED_LED_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-red-led.title", - tagInput: undefined, - tagOutput: TAG_OUTPUT_SVG, - descriptionText: "toolbar-red-led.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-red-led.tryItDescription", - component: undefined, - id: "red_LED" -}; -export const SOUND_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-sound-sensor.title", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - descriptionText: "toolbar-sound-sensor.description", - tryItTitle: "Simulation Coming Soon!", - tryItDescription: "toolbar-sound-sensor.tryItDescription", - component: TRY_IT_MAKE_CODE, - id: "sound_sensor" -}; -export const SWITCH_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-slider-switch.title", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - descriptionText: "toolbar-slider-switch.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-slider-switch.tryItDescription", - component: undefined, - id: "slider_switch" -}; -export const SPEAKER_MODAL_CONTENT: IModalContent = { - descriptionTitle: "toolbar-speaker.title", - tagInput: undefined, - tagOutput: TAG_OUTPUT_SVG, - descriptionText: "toolbar-speaker.description", - tryItTitle: "Try it on the Simulator!", - tryItDescription: "toolbar-speaker.tryItDescription", - component: undefined, - id: "speaker" -}; -export const TEMPERATURE_MODAL_CONTENT: IModalContent = { - component: , - descriptionText: "toolbar-temperature-sensor.description", - descriptionTitle: "toolbar-temperature-sensor.title", - id: "temperature", - tagInput: TAG_INPUT_SVG, - tagOutput: undefined, - tryItDescription: "toolbar-temperature-sensor.tryItDescription", - tryItTitle: "Try it on the Simulator!" -}; - -export const LABEL_TO_MODAL_CONTENT = new Map([ - [TOOLBAR_ICON_ID.GPIO, GPIO_MODAL_CONTENT], - [TOOLBAR_ICON_ID.IR, IR_MODAL_CONTENT], - [TOOLBAR_ICON_ID.LIGHT, LIGHT_MODAL_CONTENT], - [TOOLBAR_ICON_ID.MOTION, MOTION_MODAL_CONTENT], - [TOOLBAR_ICON_ID.NEO_PIXEL, NEOP_MODAL_CONTENT], - [TOOLBAR_ICON_ID.PUSH_BUTTON, PUSHB_MODAL_CONTENT], - [TOOLBAR_ICON_ID.RED_LED, RED_LED_MODAL_CONTENT], - [TOOLBAR_ICON_ID.SOUND, SOUND_MODAL_CONTENT], - [TOOLBAR_ICON_ID.SPEAKER, SPEAKER_MODAL_CONTENT], - [TOOLBAR_ICON_ID.SWITCH, SWITCH_MODAL_CONTENT], - [TOOLBAR_ICON_ID.TEMPERATURE, TEMPERATURE_MODAL_CONTENT] -]); diff --git a/src/view/constants.ts b/src/view/constants.ts index 372d77cbf..64f6a71f6 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -3,43 +3,43 @@ // Key events export const CONSTANTS = { - CURRENTLY_RUNNING: (file: string) => { - return `Currently running: ${file}` - }, - ID_NAME: { - BUTTON_A: "BTN_A_OUTER", - BUTTON_AB: "BTN_AB_OUTER", - BUTTON_B: "BTN_B_OUTER", - PIN_A1: "PIN_A1", - PIN_A2: "PIN_A2", - PIN_A3: "PIN_A3", - PIN_A4: "PIN_A4", - PIN_A5: "PIN_A5", - PIN_A6: "PIN_A6", - PIN_A7: "PIN_A7", - PLAY_BUTTON: "play-button", - REFRESH_BUTTON: "refresh-button", - STOP_BUTTON: "stop-button", - SWITCH: "SWITCH" - }, - KEYBOARD_KEYS: { - A: "KeyA", - B: "KeyB", - CAPITAL_R: "R", - CAPITAL_F: "F", - ENTER: "Enter", - S: "KeyS", - NUMERIC_ONE: "Digit1", - NUMERIC_TWO: "Digit2", - NUMERIC_THREE: "Digit3", - NUMERIC_FOUR: "Digit4", - NUMERIC_FIVE: "Digit5", - NUMERIC_SIX: "Digit6", - NUMERIC_SEVEN: "Digit7" - }, - NO_FILES_AVAILABLE: "Choose a .py file to run on the Simulator", - SIMULATOR_BUTTON_WIDTH: 60, - TOOLBAR_INFO: `Explore what's on the board:`, + CURRENTLY_RUNNING: (file: string) => { + return `Currently running: ${file}`; + }, + ID_NAME: { + BUTTON_A: "BTN_A_OUTER", + BUTTON_AB: "BTN_AB_OUTER", + BUTTON_B: "BTN_B_OUTER", + PIN_A1: "PIN_A1", + PIN_A2: "PIN_A2", + PIN_A3: "PIN_A3", + PIN_A4: "PIN_A4", + PIN_A5: "PIN_A5", + PIN_A6: "PIN_A6", + PIN_A7: "PIN_A7", + PLAY_BUTTON: "play-button", + REFRESH_BUTTON: "refresh-button", + STOP_BUTTON: "stop-button", + SWITCH: "SWITCH", + }, + KEYBOARD_KEYS: { + A: "KeyA", + B: "KeyB", + CAPITAL_R: "R", + CAPITAL_F: "F", + ENTER: "Enter", + S: "KeyS", + NUMERIC_ONE: "Digit1", + NUMERIC_TWO: "Digit2", + NUMERIC_THREE: "Digit3", + NUMERIC_FOUR: "Digit4", + NUMERIC_FIVE: "Digit5", + NUMERIC_SIX: "Digit6", + NUMERIC_SEVEN: "Digit7", + }, + NO_FILES_AVAILABLE: "Choose a .py file to run on the Simulator", + SIMULATOR_BUTTON_WIDTH: 60, + TOOLBAR_INFO: `Explore what's on the board:`, }; export default CONSTANTS; diff --git a/src/view/container/device/Device.tsx b/src/view/container/device/Device.tsx new file mode 100644 index 000000000..1a66b9b2f --- /dev/null +++ b/src/view/container/device/Device.tsx @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as React from "react"; +import Simulator from "../../components/Simulator"; +import { TOOLBAR_ICON_ID } from "../../components/toolbar/SensorModalUtils"; +import ToolBar from "../../components/toolbar/ToolBar"; +import * as TOOLBAR_SVG from "../../svgs/toolbar_svg"; + +const CPX_TOOLBAR_BUTTONS: Array<{ label: any; image: any }> = [ + { + image: TOOLBAR_SVG.SLIDER_SWITCH_SVG, + label: TOOLBAR_ICON_ID.SWITCH, + }, + { + image: TOOLBAR_SVG.PUSH_BUTTON_SVG, + label: TOOLBAR_ICON_ID.PUSH_BUTTON, + }, + { + image: TOOLBAR_SVG.RED_LED_SVG, + label: TOOLBAR_ICON_ID.RED_LED, + }, + { + image: TOOLBAR_SVG.SOUND_SVG, + label: TOOLBAR_ICON_ID.SOUND, + }, + { + image: TOOLBAR_SVG.TEMPERATURE_SVG, + label: TOOLBAR_ICON_ID.TEMPERATURE, + }, + { + image: TOOLBAR_SVG.LIGHT_SVG, + label: TOOLBAR_ICON_ID.LIGHT, + }, + { + image: TOOLBAR_SVG.NEO_PIXEL_SVG, + label: TOOLBAR_ICON_ID.NEO_PIXEL, + }, + { + image: TOOLBAR_SVG.SPEAKER_SVG, + label: TOOLBAR_ICON_ID.SPEAKER, + }, + { + image: TOOLBAR_SVG.MOTION_SVG, + label: TOOLBAR_ICON_ID.MOTION, + }, + { + image: TOOLBAR_SVG.IR_SVG, + label: TOOLBAR_ICON_ID.IR, + }, + { + image: TOOLBAR_SVG.GPIO_SVG, + label: TOOLBAR_ICON_ID.GPIO, + }, +]; + +// Container to switch between multiple devices + +class Device extends React.Component { + render() { + return ( +
+ + +
+ ); + } +} +export default Device; diff --git a/src/view/index.css b/src/view/index.css index 4c477d278..918c31f9e 100644 --- a/src/view/index.css +++ b/src/view/index.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css?family=Joti+One'); +@import url("https://fonts.googleapis.com/css?family=Joti+One"); body { margin: 0; @@ -6,7 +6,8 @@ body { font-family: sans-serif; } -html, body { +html, +body { overflow: hidden; height: 100%; -} \ No newline at end of file +} diff --git a/src/view/index.tsx b/src/view/index.tsx index d5a969aa8..9b0fc44a2 100644 --- a/src/view/index.tsx +++ b/src/view/index.tsx @@ -3,8 +3,8 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; -import App from "./App"; import { IntlProvider } from "react-intl"; +import App from "./App"; import "./index.css"; @@ -12,12 +12,12 @@ const messageEn = require("./translations/en.json"); const locale = "en"; const message = { - en: messageEn + en: messageEn, }; ReactDOM.render( - - - , - document.getElementById("root") + + + , + document.getElementById("root") ); diff --git a/src/view/styles/Button.css b/src/view/styles/Button.css index bd2b1c8fe..78c8372a5 100644 --- a/src/view/styles/Button.css +++ b/src/view/styles/Button.css @@ -1,49 +1,49 @@ .button { - height: 32px; - background: var(--vscode-debugToolBar-background); - border-color: var(--vscode-debugToolBar-background); + height: 32px; + background: var(--vscode-debugToolBar-background); + border-color: var(--vscode-debugToolBar-background); } .button-icon { - fill: var(--vscode-badgeForegroundOverride); + fill: var(--vscode-badgeForegroundOverride); } .button-rectangle { - stroke: var(--vscode-badgeForegroundOverride); + stroke: var(--vscode-badgeForegroundOverride); } .play-button { - border-radius: 8px 0px 0px 8px; - border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-radius: 8px 0px 0px 8px; + border-color: var(--vscode-highContrastButtonBorderOverride-color); } .refresh-button { - border-radius: 0px 8px 8px 0px; - border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-radius: 0px 8px 8px 0px; + border-color: var(--vscode-highContrastButtonBorderOverride-color); } .button:focus, .button:hover { - background-color: var(--vscode-terminal-selectionBackground); + background-color: var(--vscode-terminal-selectionBackground); } .button:active { - background-color: var(--vscode-editor-selectionHighlightBackground); + background-color: var(--vscode-editor-selectionHighlightBackground); } .toolbar-button { - border: none; + border: none; } .toolbar-button:hover { - outline: none; + outline: none; } .edge-button { - pointer-events: none; - border: none; + pointer-events: none; + border: none; } .button-pressed { - background-color: var(--vscode-button-background); - outline: none; + background-color: var(--vscode-button-background); + outline: none; } diff --git a/src/view/styles/Dropdown.css b/src/view/styles/Dropdown.css index c1b355d26..3d6243fc3 100644 --- a/src/view/styles/Dropdown.css +++ b/src/view/styles/Dropdown.css @@ -1,27 +1,27 @@ .dropdown { - background: var(--vscode-debugToolBar-background); - border-color: var(--vscode-highContrastButtonBorderOverride-color); - border-radius: 2px; - max-width: 300px; - min-width: 240px; - box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.22); - color: var(--vscode-foreground); - height: 32px; - padding-left: 8px; - padding-right: 4px; + background: var(--vscode-debugToolBar-background); + border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-radius: 2px; + max-width: 300px; + min-width: 240px; + box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.22); + color: var(--vscode-foreground); + height: 32px; + padding-left: 8px; + padding-right: 4px; } select.dropdown:hover, select.dropdown:focus, select.dropdown:active { - outline: 1px solid var(--vscode-button-background); - outline-offset: 1px; + outline: 1px solid var(--vscode-button-background); + outline-offset: 1px; } option { - height: 32px; - background: var(--vscode-debugToolBar-background); - align-items: center; - font-size: 14px; - color: var(--vscode-foreground); + height: 32px; + background: var(--vscode-debugToolBar-background); + align-items: center; + font-size: 14px; + color: var(--vscode-foreground); } diff --git a/src/view/styles/InputSlider.css b/src/view/styles/InputSlider.css index 8bd87a83c..b51dae8f3 100644 --- a/src/view/styles/InputSlider.css +++ b/src/view/styles/InputSlider.css @@ -1,103 +1,103 @@ :root { - --slider-gray-color: #cccccc; - --slider-width: 240px; + --slider-gray-color: #cccccc; + --slider-width: 240px; } .inputSlider { - height: 48px; - margin-bottom: 60px; - display: table-cell; + height: 48px; + margin-bottom: 60px; + display: table-cell; } .sliderValue { - -webkit-appearance: none; - text-align: center; - width: 48px; - height: 32px; - background-color: var(--vscode-editor-background); - margin-right: 15px; - margin-top: auto; - margin-bottom: auto; - margin-left: 5px; - color: var(--badgeForegroundOverride); - border-radius: 2px; - font-size: 16px; - font-weight: bold; - border-width: 1px; - border-radius: 2px; - border-color: var(--vscode-highContrastButtonBorderOverride-color); + -webkit-appearance: none; + text-align: center; + width: 48px; + height: 32px; + background-color: var(--vscode-editor-background); + margin-right: 15px; + margin-top: auto; + margin-bottom: auto; + margin-left: 5px; + color: var(--badgeForegroundOverride); + border-radius: 2px; + font-size: 16px; + font-weight: bold; + border-width: 1px; + border-radius: 2px; + border-color: var(--vscode-highContrastButtonBorderOverride-color); } .slider { - -webkit-appearance: none; - background-color: var(--slider-gray-color); - height: 1px; - width: var(--slider-width); - vertical-align: middle; + -webkit-appearance: none; + background-color: var(--slider-gray-color); + height: 1px; + width: var(--slider-width); + vertical-align: middle; } .slider::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 16px; - height: 16px; - border-radius: 50%; - background: var(--vscode-textLink-activeForeground); - cursor: pointer; + -webkit-appearance: none; + appearance: none; + width: 16px; + height: 16px; + border-radius: 50%; + background: var(--vscode-textLink-activeForeground); + cursor: pointer; } .slider::-webkit-slider-runnable-track:focus, .inputSlider:focus, .slider:focus { - outline: none; + outline: none; } .sliderValue:focus, .sliderValue:hover { - -webkit-appearance: none; - color: var(--vscode-textLink-activeForeground); - outline: 1px solid var(--vscode-textLink-activeForeground); + -webkit-appearance: none; + color: var(--vscode-textLink-activeForeground); + outline: 1px solid var(--vscode-textLink-activeForeground); } .maxLabel, .minLabel { - display: inline-block; - position: absolute; - vertical-align: top; + display: inline-block; + position: absolute; + vertical-align: top; } .maxLabel { - right: 0; + right: 0; } .minLabel { - left: 0; + left: 0; } .sliderArea, .sliderValue { - display: inline-block; - vertical-align: middle; + display: inline-block; + vertical-align: middle; } .sliderArea { - width: var(--slider-width); - height: 49px; + width: var(--slider-width); + height: 49px; } .downLabelArea { - width: var(--slider-width); - height: 15px; - margin-top: 10px; - position: relative; - font-size: 14px; + width: var(--slider-width); + height: 15px; + margin-top: 10px; + position: relative; + font-size: 14px; } .upLabelArea { - width: var(--slider-width); - height: 15px; - margin-bottom: 10px; - position: relative; - font-weight: bolder; - font-size: 16px; + width: var(--slider-width); + height: 15px; + margin-bottom: 10px; + position: relative; + font-weight: bolder; + font-size: 16px; } .slider, .upLabelArea, .downLabelArea { - display: block; + display: block; } diff --git a/src/view/styles/LightSensorBar.css b/src/view/styles/LightSensorBar.css index 2d2a84c5e..5d0abac42 100644 --- a/src/view/styles/LightSensorBar.css +++ b/src/view/styles/LightSensorBar.css @@ -1,20 +1,20 @@ .title { - font-size: 14px; - text-align: left; - font-weight: bold; + font-size: 14px; + text-align: left; + font-weight: bold; } .header { - -webkit-appearance: none; - height: 30px; - margin-bottom: 2px; + -webkit-appearance: none; + height: 30px; + margin-bottom: 2px; } .lightSensorBar { - -webkit-appearance: none; - margin-top: 10px; - width: 400px; - margin-left: auto; - margin-right: auto; - padding-bottom: 16px; + -webkit-appearance: none; + margin-top: 10px; + width: 400px; + margin-left: auto; + margin-right: auto; + padding-bottom: 16px; } diff --git a/src/view/styles/MotionSensorBar.css b/src/view/styles/MotionSensorBar.css index 552e1ddcd..76674dbe8 100644 --- a/src/view/styles/MotionSensorBar.css +++ b/src/view/styles/MotionSensorBar.css @@ -1,16 +1,16 @@ .title { - font-size: 14px; - text-align: left; + font-size: 14px; + text-align: left; } .header { - -webkit-appearance: none; - height: 30px; - margin-bottom: 2px; + -webkit-appearance: none; + height: 30px; + margin-bottom: 2px; } .MotionSensorBar { - width: 440px; - margin-left: auto; - margin-right: auto; + width: 440px; + margin-left: auto; + margin-right: auto; } diff --git a/src/view/styles/SensorButton.css b/src/view/styles/SensorButton.css index df85bcef2..8f49d1842 100644 --- a/src/view/styles/SensorButton.css +++ b/src/view/styles/SensorButton.css @@ -1,26 +1,26 @@ .sensor-button { - color: var(--vscode-badgeForegroundOverride); - text-align: center; - background-color: var(--vscode-button-background); - width: 320px; - height: 32px; - font-weight: bolder; - float: left; - padding-left: 20px; - margin-bottom: 20px; - margin-top: 20px; - border-color: var(--vscode-highContrastButtonBorderOverride-color); - border-width: 1px; - border-style: solid; + color: var(--vscode-badgeForegroundOverride); + text-align: center; + background-color: var(--vscode-button-background); + width: 320px; + height: 32px; + font-weight: bolder; + float: left; + padding-left: 20px; + margin-bottom: 20px; + margin-top: 20px; + border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-width: 1px; + border-style: solid; } .sensor-button:focus, .sensor-button:active { - outline-width: thick; - outline-offset: 4px; - outline: 2px solid var(--vscode-focusBorder); - background-color: var(--vscode-button-hoverBackground); + outline-width: thick; + outline-offset: 4px; + outline: 2px solid var(--vscode-focusBorder); + background-color: var(--vscode-button-hoverBackground); } .sensor-button:hover { - background-color: var(--vscode-button-hoverBackground); + background-color: var(--vscode-button-hoverBackground); } diff --git a/src/view/styles/Simulator.css b/src/view/styles/Simulator.css index 5a428910b..62a2f3547 100644 --- a/src/view/styles/Simulator.css +++ b/src/view/styles/Simulator.css @@ -1,20 +1,74 @@ .simulator { - display: flex; - flex-direction: column; - justify-content: center; - max-width: 700px; - max-height: 700px; - margin-left: auto; - margin-right: auto; + display: flex; + flex-direction: column; + justify-content: center; + max-width: 700px; + max-height: 700px; + margin-left: auto; + margin-right: auto; } .buttons { - display: flex; - flex-direction: row; - padding-top: 20px; - justify-content: center; + display: flex; + flex-direction: row; + padding-top: 20px; + justify-content: center; } .file-selector { - padding: 20px; + padding: 20px; +} + +.shake-pressed { + /* Start the shake animation and make the animation last for 0.5 seconds */ + animation: shake 0.5s; + + /* When the animation is finished, start again */ + animation-iteration-count: infinite; +} + +@keyframes shake { + 0% { + transform: translate(1px, 1px) rotate(0deg); + } + 10% { + transform: translate(-1px, -2px) rotate(-1deg); + } + 20% { + transform: translate(-3px, 0px) rotate(1deg); + } + 30% { + transform: translate(3px, 2px) rotate(0deg); + } + 40% { + transform: translate(1px, -1px) rotate(1deg); + } + 50% { + transform: translate(-1px, 2px) rotate(-1deg); + } + 60% { + transform: translate(-3px, 1px) rotate(0deg); + } + 70% { + transform: translate(3px, 1px) rotate(-1deg); + } + 80% { + transform: translate(-1px, -1px) rotate(1deg); + } + 90% { + transform: translate(1px, 2px) rotate(0deg); + } + 100% { + transform: translate(1px, -2px) rotate(-1deg); + } +} + +.simulator { + display: flex; + flex-direction: column; + justify-content: center; + max-width: 700px; + max-height: 700px; + margin-left: auto; + margin-right: auto; } diff --git a/src/view/styles/TemperatureSensorBar.css b/src/view/styles/TemperatureSensorBar.css index e09ab9b44..dfab0b7cd 100644 --- a/src/view/styles/TemperatureSensorBar.css +++ b/src/view/styles/TemperatureSensorBar.css @@ -1,18 +1,18 @@ .title { - font-size: 14px; - text-align: left; - font-weight: bold; + font-size: 14px; + text-align: left; + font-weight: bold; } .header { - -webkit-appearance: none; - height: 30px; - margin-bottom: 2px; + -webkit-appearance: none; + height: 30px; + margin-bottom: 2px; } .temperatureSensorBar { - margin-top: 10px; - width: 440px; - margin-left: auto; - margin-right: auto; - padding-bottom: 16px; + margin-top: 10px; + width: 440px; + margin-left: auto; + margin-right: auto; + padding-bottom: 16px; } diff --git a/src/view/styles/ToolBar.css b/src/view/styles/ToolBar.css index 89e6c1d9f..b2cb2bc34 100644 --- a/src/view/styles/ToolBar.css +++ b/src/view/styles/ToolBar.css @@ -1,106 +1,113 @@ .toolbar-parent { - background: var(--vscode-debugToolBar-background); - width: fit-content; - border-radius: 2px; - height: fit-content; - margin-left: auto; - margin-right: auto; - margin-top: 24px; - margin-bottom: 50px; + background: var(--vscode-debugToolBar-background); + width: fit-content; + border-radius: 2px; + height: fit-content; + margin-left: auto; + margin-right: auto; + margin-top: 24px; + margin-bottom: 50px; +} + +.toolbar { + box-shadow: 0px 0px 20px rgba(0, 0, 0, 30%); + border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-width: 1px; + border-style: solid; } -.toolbar, .toolbar-icon { - box-shadow: 0px 0px 20px rgba(0, 0, 0, 30%); - border-color: var(--vscode-highContrastButtonBorderOverride-color); - border-width: 1px; - border-style: solid; + box-shadow: 0px 0px 20px rgba(0, 0, 0, 30%); + border-color: var(--vscode-highContrastButtonBorderOverride-color); + border-width: 1px; + border-style: solid; + padding: 0px 8px 0px 8px; } .tag, .title { - display: inline; + display: inline; } .sensor_modal { - vertical-align: middle; - width: 360px; - max-height: 240px; - overflow-y: scroll; - overflow-x: hidden; - position: relative; - height: fit-content; - padding-left: 16px; - box-shadow: none; - background: var(--vscode-debugToolBar-background); - margin-left: 1px; + vertical-align: middle; + width: 360px; + max-height: 240px; + overflow-y: scroll; + overflow-x: hidden; + position: relative; + height: fit-content; + padding-left: 16px; + box-shadow: none; + background: var(--vscode-debugToolBar-background); + margin-left: 1px; } .title { - -webkit-appearance: none; - font-size: 16px; - font-weight: bolder; - color: var(--vscode-badgeForegroundOverride); - text-align: left; - margin-right: 40px; - position: absolute; - left: 0; - padding-left: inherit; - width: 320px; + -webkit-appearance: none; + font-size: 16px; + font-weight: bolder; + color: var(--vscode-badgeForegroundOverride); + text-align: left; + margin-right: 40px; + position: absolute; + left: 0; + padding-left: inherit; + width: 320px; } .tag { - position: absolute; - left: 200px; + position: absolute; + left: 200px; } .description { - -webkit-appearance: none; - font-size: 14px; - color: var(--vscode-foreground); - word-wrap: break-word; - width: 320px; - margin-top: 15px; - text-align: left; - line-height: 17px; - font-weight: 100; - opacity: 50%; + -webkit-appearance: none; + font-size: 14px; + color: var(--vscode-foreground); + word-wrap: break-word; + width: 320px; + margin-top: 15px; + text-align: left; + line-height: 17px; + font-weight: 100; + opacity: 50%; } .title_group { - margin-top: 20px; - width: fit-content; - padding-left: 16px; + margin-top: 20px; + width: fit-content; + padding-left: 16px; } .try_area { - position: relative; - padding-bottom: 30px; - text-align: left; - line-height: 17px; - font-weight: 100; - opacity: 50%; - font-size: 14px; - word-wrap: break-word; + position: relative; + padding-bottom: 30px; + text-align: left; + line-height: 17px; + font-weight: 100; + opacity: 50%; + font-size: 14px; + word-wrap: break-word; } .link-parent { - padding-top: 12px; - -webkit-appearance: none; - padding-left: 150px; - color: var(--vscode-textLink-activeForeground); - text-align: right; - text-decoration: none; - font-weight: bold; + padding-top: 12px; + -webkit-appearance: none; + padding-left: 150px; + color: var(--vscode-textLink-activeForeground); + text-align: right; + text-decoration: none; + font-weight: bold; } .link-parent:hover { - -webkit-appearance: none; - padding-left: 150px; - color: var(--vscode-textLink-activeForeground); - text-decoration: none; + -webkit-appearance: none; + padding-left: 150px; + color: var(--vscode-textLink-activeForeground); + text-decoration: none; } .link { - -webkit-appearance: none; - text-decoration: none; + -webkit-appearance: none; + text-decoration: none; } diff --git a/src/view/svgs/arrow_right_svg.tsx b/src/view/svgs/arrow_right_svg.tsx index a482812a5..3d7e2f1ab 100644 --- a/src/view/svgs/arrow_right_svg.tsx +++ b/src/view/svgs/arrow_right_svg.tsx @@ -1,20 +1,20 @@ import * as React from "react"; export const ARROW_RIGHT_SVG = ( - - - + + + ); export default ARROW_RIGHT_SVG; diff --git a/src/view/svgs/close_svg.tsx b/src/view/svgs/close_svg.tsx index a37425c79..ac05bedfc 100644 --- a/src/view/svgs/close_svg.tsx +++ b/src/view/svgs/close_svg.tsx @@ -1,26 +1,26 @@ import * as React from "react"; export const CLOSE_SVG = ( - - - - + + + + ); export default CLOSE_SVG; diff --git a/src/view/svgs/play_svg.tsx b/src/view/svgs/play_svg.tsx index ee4ceb487..0da21aa9d 100644 --- a/src/view/svgs/play_svg.tsx +++ b/src/view/svgs/play_svg.tsx @@ -1,19 +1,19 @@ import * as React from "react"; export const PLAY_SVG = ( - - - + + + ); export default PLAY_SVG; diff --git a/src/view/svgs/refresh_svg.tsx b/src/view/svgs/refresh_svg.tsx index 368d64860..340ad03f8 100644 --- a/src/view/svgs/refresh_svg.tsx +++ b/src/view/svgs/refresh_svg.tsx @@ -2,20 +2,20 @@ import * as React from "react"; import "../styles/Button.css"; export const REFRESH_SVG = ( - - - + + + ); export default REFRESH_SVG; diff --git a/src/view/svgs/stop_svg.tsx b/src/view/svgs/stop_svg.tsx index bdcf04660..a89175f66 100644 --- a/src/view/svgs/stop_svg.tsx +++ b/src/view/svgs/stop_svg.tsx @@ -1,15 +1,21 @@ import * as React from "react"; export const STOP_SVG = ( - - - + + + ); export default STOP_SVG; diff --git a/src/view/svgs/tag_input_svg.tsx b/src/view/svgs/tag_input_svg.tsx index ca02485a8..13a507504 100644 --- a/src/view/svgs/tag_input_svg.tsx +++ b/src/view/svgs/tag_input_svg.tsx @@ -1,27 +1,27 @@ import * as React from "react"; export const TAG_INPUT_SVG = ( - - - - + + + + ); export default TAG_INPUT_SVG; diff --git a/src/view/svgs/tag_output_svg.tsx b/src/view/svgs/tag_output_svg.tsx index 3273d2a37..745175db5 100644 --- a/src/view/svgs/tag_output_svg.tsx +++ b/src/view/svgs/tag_output_svg.tsx @@ -1,19 +1,26 @@ import * as React from "react"; export const TAG_OUTPUT_SVG = ( - - - - + + + + ); export default TAG_OUTPUT_SVG; diff --git a/src/view/svgs/toolbar_svg.tsx b/src/view/svgs/toolbar_svg.tsx index d763724ad..fccd752f3 100644 --- a/src/view/svgs/toolbar_svg.tsx +++ b/src/view/svgs/toolbar_svg.tsx @@ -1,447 +1,479 @@ import * as React from "react"; -import { TOOLBAR_ICON_LABEL } from "../components/toolbar/sensorModalUtils"; +import { TOOLBAR_ICON_LABEL } from "../components/toolbar/SensorModalUtils"; import "../styles/Button.css"; export const LEFT_EDGE_SVG = ( - - - - - - - - - - + + + + + + + + + + ); export const RIGHT_EDGE_SVG = ( - - - - - - - - - - + + + + + + + + + + ); export const GPIO_SVG = ( - - GPIO - Created with Sketch. - - - - - - + + GPIO + Created with Sketch. + + + + + + ); export const IR_SVG = ( - - IR - Created with Sketch. - - - - + IR + Created with Sketch. + + stroke="none" + stroke-width="1" + fill="none" + fill-rule="evenodd" + > + + + + + - - - + ); export const LIGHT_SVG = ( - - {TOOLBAR_ICON_LABEL.LIGHT} - - - - - - - + {TOOLBAR_ICON_LABEL.LIGHT} + + + + + + + + + - - - + ); export const MOTION_SVG = ( - - - - - - - + + + + + + + + - - - + ); export const NEO_PIXEL_SVG = ( - - neon_pixel - Created with Sketch. - - - - - - - - - - - + neon_pixel + Created with Sketch. + + + + + + + + + + + + + - - - + ); export const PUSH_BUTTON_SVG = ( - - {TOOLBAR_ICON_LABEL.PUSH_BUTTON} - Created with Sketch. - - - - - + {TOOLBAR_ICON_LABEL.PUSH_BUTTON} + Created with Sketch. + + + + + + + - - - + ); export const RED_LED_SVG = ( - - {TOOLBAR_ICON_LABEL.RED_LED} - Created with Sketch. - - - - - + {TOOLBAR_ICON_LABEL.RED_LED} + Created with Sketch. + + + + + + + - - - + ); export const SLIDER_SWITCH_SVG = ( - - {TOOLBAR_ICON_LABEL.SWITCH} - Created with Sketch. - - - - - + {TOOLBAR_ICON_LABEL.SWITCH} + Created with Sketch. + + + + + + + - - - + ); export const SOUND_SVG = ( - - {TOOLBAR_ICON_LABEL.SOUND} - Created with Sketch. - - - - - - - + {TOOLBAR_ICON_LABEL.SOUND} + Created with Sketch. + + + + + + + + + - - - + ); export const SPEAKER_SVG = ( - - {TOOLBAR_ICON_LABEL.SPEAKER} - Created with Sketch. - - - - + {TOOLBAR_ICON_LABEL.SPEAKER} + Created with Sketch. + + + + + + - - - + ); export const TEMPERATURE_SVG = ( - - {TOOLBAR_ICON_LABEL.TEMPERATURE} - - - - - - - - - + {TOOLBAR_ICON_LABEL.TEMPERATURE} + + + + + + + + + ); export default LEFT_EDGE_SVG; diff --git a/src/view/viewUtils.tsx b/src/view/viewUtils.tsx index c2caa4fe5..7b6efed48 100644 --- a/src/view/viewUtils.tsx +++ b/src/view/viewUtils.tsx @@ -1,27 +1,27 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. export interface ISliderProps { - minValue: number; - maxValue: number; - maxLabel: string; - minLabel: string; - type: string; - axisLabel: string; + minValue: number; + maxValue: number; + maxLabel: string; + minLabel: string; + type: string; + axisLabel: string; } export interface ISensorButtonProps { - label: string; - type: string; - onMouseUp: () => void; - onMouseDown: () => void; - onKeyUp: (event: React.KeyboardEvent) => void; - onKeyDown: (event: React.KeyboardEvent) => void; + label: string; + type: string; + onMouseUp: (event: React.PointerEvent) => void; + onMouseDown: (event: React.PointerEvent) => void; + onKeyUp: (event: React.KeyboardEvent) => void; + onKeyDown: (event: React.KeyboardEvent) => void; } export interface ISensorProps { - LABEL: string; - sliderProps: ISliderProps[]; - unitLabel: string; + LABEL: string; + sliderProps: ISliderProps[]; + unitLabel: string; } export const X_SLIDER_INDEX = 0; diff --git a/tslint.json b/tslint.json index 3529d6acb..4b199b36e 100644 --- a/tslint.json +++ b/tslint.json @@ -20,7 +20,13 @@ "triple-equals": true, "object-literal-sort-keys": true, "react-hooks-nesting": "error", - "ordered-imports": false + "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" } diff --git a/vsc-extension-quickstart.md b/vsc-extension-quickstart.md deleted file mode 100644 index cde73347a..000000000 --- a/vsc-extension-quickstart.md +++ /dev/null @@ -1,41 +0,0 @@ -# Welcome to your VS Code Extension - -## What's in the folder - -* This folder contains all of the files necessary for your extension. -* `package.json` - this is the manifest file in which you declare your extension and command. - * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. -* `src/extension.ts` - this is the main file where you will provide the implementation of your command. - * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. - * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. - -## Get up and running straight away - -* Press `F5` to open a new window with your extension loaded. -* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. -* Set breakpoints in your code inside `src/extension.ts` to debug your extension. -* Find output from your extension in the debug console. - -## Make changes - -* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. -* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. - -## Explore the API - -* You can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts`. - -## Run tests - -* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. -* Press `F5` to run the tests in a new window with your extension loaded. -* See the output of the test result in the debug console. -* Make changes to `test/extension.test.ts` or create new test files inside the `test` folder. - * By convention, the test runner will only consider files matching the name pattern `**.test.ts`. - * You can create folders inside the `test` folder to structure your tests any way you want. - -## Go further - - * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/testing-extension). - * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. - * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).