Update and merge PR #107 (REUSE compliance)

Reapply the SPDX header to current files, and some others that seem to
have been overlooked.

Copy LICENSE file instead of moving it (symlinking it breaks Rat, somehow).
diff --git a/.eslintignore b/.eslintignore
index ba489a4..652cc15 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,5 +3,6 @@
 !/packages/*/src/types
 **/*.d.ts
 /coverage
+/docs
 /packages/*/lib
 /web/dist
diff --git a/.eslintrc.js b/.eslintrc.js
index 0fb5c28..fb4a40d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -20,15 +20,6 @@
  * under the License.
  */
 
-const babel = require('@babel/core');
-
-// Use the root babel.config.js for module resolution.
-// Relevant issue: tleunen/eslint-import-resolver-babel-module#89
-const babelConfig = babel.loadPartialConfig({ cwd: __dirname });
-const babelModuleResolver = babelConfig.options.plugins.find(
-  (item) => item.file.request === 'module-resolver',
-);
-
 module.exports = {
   root: true,
   extends: ['eslint:recommended', 'plugin:import/recommended', 'prettier'],
@@ -69,7 +60,11 @@
   settings: {
     'import/internal-regex': '^@apache-annotator/',
     'import/resolver': {
-      'babel-module': babelModuleResolver.options,
+      'babel-module': {
+        babelOptions: {
+          root: __dirname,
+        },
+      },
     },
   },
   overrides: [
@@ -87,6 +82,12 @@
         es2017: true,
         node: true,
       },
+      globals: {
+        globalThis: 'readonly',
+      },
+      parserOptions: {
+        ecmaVersion: 2019,
+      },
       plugins: ['node'],
       rules: {
         'no-console': 'off',
@@ -97,10 +98,6 @@
     },
     {
       files: ['**/*.ts'],
-      env: {
-        es2020: true,
-        'shared-node-browser': true,
-      },
       extends: [
         'plugin:@typescript-eslint/recommended',
         'plugin:@typescript-eslint/recommended-requiring-type-checking',
@@ -108,12 +105,14 @@
         'prettier/@typescript-eslint',
       ],
       parserOptions: {
-        project: ['./tsconfig.json', './packages/*/tsconfig.json'],
+        ecmaVersion: 2020,
+        project: ['./tsconfig.test.json', './packages/*/tsconfig.json'],
         tsconfigRootDir: __dirname,
       },
       plugins: ['@typescript-eslint'],
       rules: {
         '@typescript-eslint/consistent-type-imports': 'error',
+        '@typescript-eslint/no-duplicate-imports': 'error',
         '@typescript-eslint/no-explicit-any': 'off',
         '@typescript-eslint/no-unused-vars': [
           'error',
@@ -131,29 +130,18 @@
     },
     {
       files: ['packages/*/test/**/*.ts', 'test/**/*.ts'],
-      env: {
-        mocha: true,
-      },
-      globals: {
-        assert: true,
-      },
       rules: {
         'import/no-relative-parent-imports': 'off',
       },
     },
     {
-      files: ['packages/dom/**/*.js'],
-      env: {
-        browser: true,
-      },
-    },
-    {
-      files: ['web/demo/**/*.js'],
+      files: ['web/**/*.js'],
       env: {
         browser: true,
         es2020: true,
       },
       parserOptions: {
+        ecmaVersion: 2020,
         sourceType: 'module',
       },
     },
diff --git a/.gitignore b/.gitignore
index 44c4e74..7ed21a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,12 @@
 *.d.ts
+!/packages/**/src/**/*.d.ts
 *.d.ts.map
 .nyc_output
 coverage
+docs
 node_modules
 tsconfig.tsbuildinfo
+tsconfig.test.tsbuildinfo
 /packages/*/DISCLAIMER-WIP
 /packages/*/LICENSE
 /packages/*/NOTICE
diff --git a/.mocharc.js b/.mocharc.js
index ab18b43..3df0187 100644
--- a/.mocharc.js
+++ b/.mocharc.js
@@ -23,6 +23,11 @@
 module.exports = {
   extension: ['.ts'],
   ignore: ['node_modules'],
-  require: ['./babel-register.js', 'global-jsdom/lib/register'],
+  require: ['./babel-register.js', 'global-jsdom/register'],
   timeout: 5000,
+  watchFiles: [
+    './test/**/*.ts',
+    './packages/*/src/**/*.ts',
+    './packages/*/test/**/*.ts',
+  ],
 };
diff --git a/.ratignore b/.ratignore
index 2d1dedc..b31f5da 100644
--- a/.ratignore
+++ b/.ratignore
@@ -11,8 +11,10 @@
 package\.json
 repolinter\.json
 tsconfig(\.\w+)?\.json
+typedoc\.json
 yarn\.lock
 CODE_OF_CONDUCT\.md
 DISCLAIMER-WIP
+LICENSES
 README\.md
 SECURITY\.md
diff --git a/.travis.yml b/.travis.yml
index 857c9c9..bdcc041 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,29 +1,14 @@
 dist: focal
 language: node_js
-node_js:
-  - "10"
-  - "12"
-  - "13"
-  - "14"
+node_js: node
 
 before_deploy:
   - git fetch --unshallow
   - git checkout master
 
-jobs:
-  include:
-    - stage: deploy
-      node_js: node
-      script: skip
-      deploy:
-        provider: npm
-        edge: true
-        api_token:
-          secure: kjnHYXAsaqKFX9tYWRC4Zp/k9e8RQ79jVdjBNKlFExmPL5AvocYz/YeCbA/hZSnR02IjVHDAgWxVKCSDcIpDmhs0Bd7fOuyNmNm+ET0aFF6emtAMnw4RfmS0z0ZcQ8gDk3EhQ+c59VTe6s3TexBxXXUhEclKghF/iRFrcHtPBxmqTuo1rH9Nyp9Kk7QLFHMC2y1AWeTpjCdKA5ooxPb353oXRHS985sirnYkzUphTkMSFkK27hupbDpDSfiHYOZEZzGWUrgT7YYALqcck22Jqy7MdWhZgoAOFr0R26oz7wVssnvt2PNc8hFgK4oLBRwKloNjBKMBChRoJ257yGM2ak+z844xFx36u1x/MOS6NhC15UOdyZLKm6gyGFvNOUVuPmLpNhwh/0DkZ+N56FevOWoAT7+fg3Op67KnGKk3TZfEPKOixqF4w6TfhJCEQfEvZg/6618SfoxuI5SidBqweRNT9B+iTo3QDR4JzP6vtCa1/Kc6yzLmx2EQpJIICWI90ZDOuqd1/aC39tLostpzrbQD64vDfQvGTXAd0WZT8lEvtQ4UIQA/MDJBW5OCDDMazlZlv3nvH0rGsv48vKHDzUYlz6VAt9E2F65h1oHfwa2YYHtKHV+J9/Vdof7psz7CBfkemlRsaPPiknDpXv0Y4kpq/75wtAZzpNho8j5LGf8=
-        run_script: publish -- --canary --exact --force-publish "*" --yes minor
-        on:
-          branch: master
-
-branches:
-  only:
-    - master
+deploy:
+  provider: npm
+  edge: true
+  run_script: publish:ci
+  on:
+    branch: master
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Makefile b/Makefile
index c193ecf..e00541e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+# SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+# SPDX-License-Identifier: Apache-2.0
 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
 # use this file except in compliance with the License. You may obtain a copy of
 # the License at
diff --git a/README.md b/README.md
index 17fae17..039ad5b 100644
--- a/README.md
+++ b/README.md
@@ -1,110 +1,19 @@
-# [Apache Annotator](http://annotator.apache.org/) (incubating) [![Build Status](https://travis-ci.org/apache/incubator-annotator.svg?branch=master)](https://travis-ci.org/apache/incubator-annotator)
+# [Apache Annotator](http://annotator.apache.org/) (incubating) [![Build Status](https://travis-ci.com/apache/incubator-annotator.svg?branch=master)](https://travis-ci.com/apache/incubator-annotator)
 
 Apache Annotator (incubating) provides libraries to enable annotation related
 software, with an initial focus on identification of textual fragments in
 browser environments.
 
-## Usage
+## Installation, usage, API documentation
 
-The Apache Annotator project is written in TypeScript, but the project is
-compiled and distributed in CommonJS and ECMAScript Module formats.
-
-The project is made up of multiple packages. Install the `apache-annotator`
-package, which includes all sub-packages, or install individual packages from
-the `@apache-annotator` scope.
-
-Import packages from either `apache-annotator/package` or
-`@apache-annotator/package`.
-
-Currently, the following sub-packages are part of the project:
-
-### `@apache-annotator/dom`
-
-This package contains functions for creating and resolving Web Annotation
-Selectors in DOM environments.
-
-### `@apache-annotator/selector`
-
-This package contains generic utilities for composing functions that create
-and resolve Web Annotation Selectors.
+See documentation on the website: <https://annotator.apache.org/docs/>
 
 ## Getting Involved
 
-* Join the [mailing list]. Send an email to
+* Join the [mailing list](http://mail-archives.apache.org/mod_mbox/incubator-annotator-dev/). Send an email to
   dev-subscribe@apache-annotator.apache.org to subscribe.
-* Browse the [issue tracker] and file new issues if you encounter problems.
-* Read or contribute to the [wiki].
-
-[mailing list]: http://mail-archives.apache.org/mod_mbox/incubator-annotator-dev/
-[issue tracker](https://github.com/apache/incubator-annotator/issues)
-[wiki](https://github.com/apache/incubator-annotator/wiki)
-
-### Requirements
-
-We use [Lerna](https://lernajs.io/) to juggle the various Apache Annotator
-libraries. If you'd like to contribute, you'll need the following:
-
-- [node](https://nodejs.org) ^10 || ^11 || ^12 || >=13.7
-- [yarn](https://www.yarnpkg.com/) ^1.5
-
-#### Setup
-
-```sh
-$ yarn install
-```
-
-#### Test
-
-```sh
-$ yarn test
-```
-
-#### Start a local test project
-
-```sh
-$ yarn start
-```
-
-## Selectors
-
-Many Annotations refer to part of a resource, rather than all of it, as the Target. We call that part of the resource a Segment (of Interest). A Selector is used to describe how to determine the Segment from within the Source resource.
-
-The [W3C Web Annotation Data Model](https://www.w3.org/TR/annotation-model) outlines a number of different selectors. See table below for full list and status.
-
-| Selector                                                                        | Description                                                                                                                                                                                          | Implementation Status |
-| ------------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------: |
-| [Text Quote](https://www.w3.org/TR/annotation-model/#text-quote-selector)       | This Selector describes a range of text, including some of the text immediately before (a prefix) and after (a suffix) it to distinguish between multiple copies of the same sequence of characters. | Yes                   |
-| [CSS](https://www.w3.org/TR/annotation-model/#css-selector)                     | CSS Selectors allow for a wide variety of well supported ways to describe the path to an element in a web page.                                                                                      | Yes                   |
-| [Text Position](https://www.w3.org/TR/annotation-model/#text-position-selector) | This Selector describes a range of text by recording the start and end positions of the selection in the stream.                                                                                     | No                    |
-| [Fragment](https://www.w3.org/TR/annotation-model/#fragment-selector)           | Uses the fragment part of an IRI defined by the representation's media type.                                                                                                                         | No                    |
-| [XPath](https://www.w3.org/TR/annotation-model/#xpath-selector)                 | Implements an XPath based selection.                                                                                                                                                                 | No                    |
-| [Data Postion](https://www.w3.org/TR/annotation-model/#data-position-selector)  | Similar to the Text Position Selector, the Data Position Selector uses the same properties but works at the byte in bitstream level rather than the character in text level.                         | No                    |
-| [SVG](https://www.w3.org/TR/annotation-model/#svg-selector)                     | An SvgSelector defines an area through the use of the Scalable Vector Graphics standard.                                                                                                             | No                    |
-| [Range](https://www.w3.org/TR/annotation-model/#range-selector)                 | A Range Selector can be used to identify the beginning and the end of the selection by using other Selectors.                                                                                        | Yes                   |
-| [Refinement](https://www.w3.org/TR/annotation-model/#refinement-of-selection)   | Select a part of a selection, rather than as a selection of the complete resource.                                                                                                                   |                       |
-
-## Web Annotation Data Model Validation
-
-If you have any Web Annotation Data Model JSON documents, you can validate them
-using the `validate` script:
-
-```sh
-$ yarn validate --url https://raw.githubusercontent.com/w3c/web-annotation-tests/master/tools/samples/correct/anno1.json
-```
-
-With the `--url` option you can pass in a URL or a local path to a JSON file.
-
-### Examples
-
-Valid:
-
-`https://raw.githubusercontent.com/w3c/web-annotation-tests/master/tools/samples/correct/anno1.json`
-
-Invalid:
-
-`https://raw.githubusercontent.com/w3c/web-annotation-tests/master/tools/samples/incorrect/anno1.json`
-
-[(More)](https://github.com/w3c/web-annotation-tests/tree/master/tools/samples)
+* Browse the [issue tracker](https://github.com/apache/incubator-annotator/issues) and file new issues if you encounter problems.
+* Read or contribute to the [wiki](https://github.com/apache/incubator-annotator/wiki).
 
 # License
 
diff --git a/babel.config.js b/babel.config.js
index a2ca325..0550e6d 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -27,7 +27,6 @@
   const ENV = api.env();
   const DEV = ENV === 'development';
   const TEST = ENV === 'test';
-  const CJS = ENV === 'cjs';
 
   // Options for the @babel/env preset.
   const envOptions = {
@@ -35,9 +34,7 @@
     // Note: This setting may become the default in Babel 8.
     bugfixes: true,
     // Transform module syntax if necessary.
-    modules: CJS || TEST ? 'commonjs' : false,
-    // Set target environment to default browsers.
-    targets: TEST ? { node: 'current' } : 'defaults',
+    modules: TEST ? 'commonjs' : false,
   };
 
   // Options for the @babel/typescript preset.
@@ -49,7 +46,7 @@
   };
 
   const addImportExtensionOptions = {
-    extension: DEV || TEST ? 'ts' : CJS ? 'js' : 'mjs',
+    extension: DEV || TEST ? 'ts' : 'js',
   };
 
   // Options for the module-resolver plugin.
@@ -58,10 +55,8 @@
     alias: {
       ...(DEV || TEST
         ? {
-            '^@apache-annotator/([^/]+)$': path.join(
-              __dirname,
-              'packages/\\1/src/index.ts',
-            ),
+            '^@apache-annotator/([^/]+)$': ([, name]) =>
+              path.join(__dirname, 'packages', name, '/src/index.ts'),
           }
         : null),
     },
@@ -71,23 +66,24 @@
   // Options for the @babel/transform-runtime plugin.
   const runtimeOptions = {
     // Use corejs version 3.
-    corejs: { version: 3 },
+    corejs: { version: 3, proposals: true },
     // Use helpers formatted for the target environment.
-    useESModules: !CJS && !TEST,
+    useESModules: !TEST,
   };
 
   return {
     plugins: [
       '@babel/plugin-proposal-class-properties',
       ['@babel/transform-runtime', runtimeOptions],
-      ...(TEST ? ['istanbul'] : []),
       ['add-import-extension', addImportExtensionOptions],
       ['module-resolver', resolverOptions],
       'preserve-comment-header',
+      ...(TEST ? ['istanbul'] : []),
     ],
     presets: [
       ['@babel/env', envOptions],
       ['@babel/typescript', typescriptOptions],
     ],
+    targets: TEST ? { node: 'current' } : 'defaults',
   };
 };
diff --git a/package.json b/package.json
index 688fae6..85dfe58 100644
--- a/package.json
+++ b/package.json
@@ -15,17 +15,16 @@
     ]
   },
   "scripts": {
-    "build": "concurrently yarn:build:lib:* yarn:build:misc",
-    "build:lib": "lerna exec --parallel -- babel -d lib -s inline -x .ts --root-mode upward src",
-    "build:lib:cjs": "cross-env BABEL_ENV=cjs yarn build:lib",
-    "build:lib:esm": "cross-env BABEL_ENV=esm yarn build:lib --out-file-extension .mjs",
-    "build:lib:types": "tsc --build",
+    "build": "concurrently yarn:build:*",
+    "build:js": "lerna exec --parallel -- babel -d lib -s -x .ts --env-name production --root-mode upward src",
     "build:misc": "lerna exec --parallel -- cp ../../DISCLAIMER-WIP ../../LICENSE ../../NOTICE ../../README.md .",
-    "clean": "tsc --build --clean && lerna exec -- rimraf DISCLAIMER-WIP LICENSE NOTICE README.md lib",
-    "lint": "tsc --build && eslint .",
-    "prepare": "yarn run build:lib:types && lerna run prepare",
+    "build:types": "tsc --build",
+    "clean": "tsc --build --clean && lerna exec -- rimraf DISCLAIMER-WIP LICENSE NOTICE README.md lib && rimraf .nyc_output coverage docs web/dist *.tsbuildinfo",
+    "docs": "tsc --build && typedoc",
+    "lint": "eslint .",
     "prepublishOnly": "yarn run build",
     "publish": "lerna publish",
+    "publish:ci": "yarn run publish --canary --exact --force-publish '*' --no-verify-access --yes minor",
     "start": "yarn run web:server",
     "test": "cross-env BABEL_ENV=test nyc mocha packages/**/*.test.ts",
     "validate": "cross-env BABEL_ENV=test mocha test/**/*.test.ts",
@@ -33,19 +32,19 @@
     "web:server": "webpack-dev-server --config=web/webpack.config.js --hot --mode development"
   },
   "devDependencies": {
-    "@babel/cli": "^7.12.10",
-    "@babel/core": "^7.12.10",
-    "@babel/plugin-proposal-class-properties": "^7.12.1",
-    "@babel/plugin-transform-runtime": "^7.12.10",
-    "@babel/preset-env": "^7.12.11",
-    "@babel/preset-typescript": "^7.12.7",
-    "@babel/register": "^7.12.10",
+    "@babel/cli": "^7.13.14",
+    "@babel/core": "^7.13.14",
+    "@babel/plugin-proposal-class-properties": "^7.13.0",
+    "@babel/plugin-transform-runtime": "^7.13.10",
+    "@babel/preset-env": "^7.13.12",
+    "@babel/preset-typescript": "^7.13.0",
+    "@babel/register": "^7.13.14",
     "@types/chai": "^4.2.11",
     "@types/mocha": "^7.0.2",
     "@types/node-fetch": "^2.5.7",
     "@types/resolve": "^1.17.0",
-    "@typescript-eslint/eslint-plugin": "^4.1.1",
-    "@typescript-eslint/parser": "^4.1.1",
+    "@typescript-eslint/eslint-plugin": "^4.20.0",
+    "@typescript-eslint/parser": "^4.20.0",
     "ajv": "^6.11.0",
     "babel-loader": "^8.0.5",
     "babel-plugin-add-import-extension": "^1.4.1",
@@ -62,27 +61,26 @@
     "eslint-plugin-node": "^11.1.0",
     "eslint-plugin-prettier": "^3.1.4",
     "file-loader": "^6.0.0",
-    "global-jsdom": "^6.1.0",
+    "global-jsdom": "^8.0.0",
     "husky": "^4.2.1",
     "jsdom": "^16.2.2",
     "lerna": "^3.20.2",
     "lint-staged": "^10.0.2",
     "mocha": "^8.0.1",
-    "mocha-loader": "^5.1.1",
-    "multi-entry-loader": "^1.1.2",
     "node-fetch": "^2.5.0",
     "nyc": "^15.0.0",
     "prettier": "^2.0.5",
     "resolve": "^1.15.0",
     "rimraf": "^3.0.0",
-    "typescript": "^3.9.7",
+    "typedoc": "^0.20.5",
+    "typescript": "^4.2.3",
     "web-annotation-tests": "https://github.com/w3c/web-annotation-tests",
     "webpack": "^4.41.5",
     "webpack-cli": "^3.3.10",
     "webpack-dev-server": "^3.10.1"
   },
   "engines": {
-    "node": "^10 || ^11 || ^12 || >=13.7",
+    "node": "^12.20 || ^14.15 || ^15.4 || ^16.0",
     "yarn": "^1.5.0"
   }
 }
diff --git a/packages/apache-annotator/.npmignore b/packages/apache-annotator/.npmignore
index 281df39..58fc595 100644
--- a/packages/apache-annotator/.npmignore
+++ b/packages/apache-annotator/.npmignore
@@ -1,2 +1,5 @@
-src
-test
+*.d.ts.map
+tsconfig.json
+tsconfig.tsbuildinfo
+/src
+/test
diff --git a/packages/apache-annotator/package.json b/packages/apache-annotator/package.json
index 4c29036..4231a26 100644
--- a/packages/apache-annotator/package.json
+++ b/packages/apache-annotator/package.json
@@ -10,30 +10,17 @@
   },
   "license": "Apache-2.0",
   "author": "Apache Software Foundation",
+  "type": "module",
   "exports": {
-    ".": {
-      "import": "./lib/index.mjs",
-      "require": "./lib/index.js"
-    },
-    "./dom": {
-      "import": "./lib/dom/index.mjs",
-      "require": "./lib/dom/index.js"
-    },
-    "./selector": {
-      "import": "./lib/selector/index.mjs",
-      "require": "./lib/selector/index.js"
-    }
+    "./*": "./lib/*.js"
   },
-  "main": "./lib/index.js",
-  "module": "./lib/index.mjs",
-  "types": "./lib/index.d.ts",
   "dependencies": {
     "@apache-annotator/dom": "^0.1.0",
     "@apache-annotator/selector": "^0.1.0",
-    "@babel/runtime-corejs3": "^7.12.5"
+    "@babel/runtime-corejs3": "^7.13.10"
   },
   "engines": {
-    "node": "^10 || ^11 || ^12 || >=13.7"
+    "node": "^12.20 || ^14.15 || ^15.4 || ^16.0"
   },
   "publishConfig": {
     "access": "public"
diff --git a/packages/apache-annotator/src/dom.ts b/packages/apache-annotator/src/dom.ts
new file mode 100644
index 0000000..55bedea
--- /dev/null
+++ b/packages/apache-annotator/src/dom.ts
@@ -0,0 +1,34 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This module provides functions for handling annotations in the context of an
+ * HTML DOM; in other words, a web page.
+ *
+ * The module’s main functionality is *matching* (or *‘anchoring’*) a {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors
+ * | Selector} to the DOM, i.e. finding which piece of a web page it refers to;
+ * and, vice versa, *describing* a selection of the page as a Selector.
+ *
+ * @module
+ */
+
+export * from '@apache-annotator/dom';
diff --git a/packages/apache-annotator/src/dom/index.ts b/packages/apache-annotator/src/dom/index.ts
deleted file mode 100644
index 4b336cb..0000000
--- a/packages/apache-annotator/src/dom/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
- * SPDX-License-Identifier: Apache-2.0
- */
- export * from '@apache-annotator/dom';
-
diff --git a/packages/apache-annotator/src/index.ts b/packages/apache-annotator/src/index.ts
deleted file mode 100644
index fe85978..0000000
--- a/packages/apache-annotator/src/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
- * SPDX-License-Identifier: Apache-2.0
- */
-
-export * as dom from '@apache-annotator/dom';
-export * as selector from '@apache-annotator/selector';
-
-
diff --git a/packages/apache-annotator/src/selector.ts b/packages/apache-annotator/src/selector.ts
new file mode 100644
index 0000000..2bae525
--- /dev/null
+++ b/packages/apache-annotator/src/selector.ts
@@ -0,0 +1,35 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This module provides types and generic functions for handling {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors
+ * | Selector}s.
+ *
+ * Annotation tool developers should not need most of the functions contained
+ * in this module, but would instead mainly use the module made for the specific
+ * context (document type) they are dealing with. See {@link dom}, currently the
+ * only such module.
+ *
+ * @module
+ */
+
+export * from '@apache-annotator/selector';
diff --git a/packages/apache-annotator/src/selector/index.ts b/packages/apache-annotator/src/selector/index.ts
deleted file mode 100644
index ef37ee3..0000000
--- a/packages/apache-annotator/src/selector/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
- * SPDX-License-Identifier: Apache-2.0
- */
- export * from '@apache-annotator/selector';
-
diff --git a/packages/apache-annotator/tsconfig.json b/packages/apache-annotator/tsconfig.json
index fd0b067..0ac1cf1 100644
--- a/packages/apache-annotator/tsconfig.json
+++ b/packages/apache-annotator/tsconfig.json
@@ -7,6 +7,6 @@
   },
   "references": [
     { "path": "../dom" },
-    { "path": "../selector" },
+    { "path": "../selector" }
   ]
 }
diff --git a/packages/dom/.npmignore b/packages/dom/.npmignore
index 281df39..58fc595 100644
--- a/packages/dom/.npmignore
+++ b/packages/dom/.npmignore
@@ -1,2 +1,5 @@
-src
-test
+*.d.ts.map
+tsconfig.json
+tsconfig.tsbuildinfo
+/src
+/test
diff --git a/packages/dom/@types/optimal-select/index.d.ts b/packages/dom/@types/optimal-select/index.d.ts
new file mode 100644
index 0000000..ff7d826
--- /dev/null
+++ b/packages/dom/@types/optimal-select/index.d.ts
@@ -0,0 +1,31 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Partial declaration, just to cover the pieces we need.
+declare module 'optimal-select' {
+  export default function optimalSelect(
+    element: Element,
+    options: {
+      root: Node,
+    },
+  ): string;
+}
diff --git a/packages/dom/package.json b/packages/dom/package.json
index 588b819..a6ae76d 100644
--- a/packages/dom/package.json
+++ b/packages/dom/package.json
@@ -10,21 +10,18 @@
   },
   "license": "Apache-2.0",
   "author": "Apache Software Foundation",
-  "exports": {
-    "import": "./lib/index.mjs",
-    "require": "./lib/index.js"
-  },
+  "type": "module",
+  "exports": "./lib/index.js",
   "main": "./lib/index.js",
-  "module": "./lib/index.mjs",
-  "types": "./lib/index.d.ts",
   "dependencies": {
-    "@babel/runtime-corejs3": "^7.12.5"
+    "@babel/runtime-corejs3": "^7.13.10",
+    "optimal-select": "^4.0.1"
   },
   "devDependencies": {
     "@apache-annotator/selector": "^0.1.0"
   },
   "engines": {
-    "node": "^10 || ^11 || ^12 || >=13.7"
+    "node": "^12.20 || ^14.15 || ^15.4 || ^16.0"
   },
   "publishConfig": {
     "access": "public"
diff --git a/packages/dom/src/css.ts b/packages/dom/src/css.ts
index 70b63dc..9a1bdec 100644
--- a/packages/dom/src/css.ts
+++ b/packages/dom/src/css.ts
@@ -20,13 +20,61 @@
  * under the License.
  */
 
+import optimalSelect from 'optimal-select';
 import type { CssSelector, Matcher } from '@apache-annotator/selector';
 import { ownerDocument } from './owner-document';
+import { toRange } from './to-range';
 
+/**
+ * Find the elements corresponding to the given {@link
+ * CssSelector}.
+ *
+ * The given CssSelector returns all elements within `scope` that it matches.
+ *
+ * The function is curried, taking first the selector and then the scope.
+ *
+ * As there may be multiple matches for a given selector, the matcher will
+ * return an (async) iterable that produces each match in the order they are
+ * found in the document.
+ *
+ * Note that the Web Annotation specification does not mention whether an
+ * ‘ambiguous’ CssSelector should indeed match all elements that match the
+ * selector value, or perhaps only the first. This implementation returns all
+ * matches to give users the freedom to follow either interpretation. This is
+ * also in line with more clearly defined behaviour of the TextQuoteSelector:
+ *
+ * > “If […] the user agent discovers multiple matching text sequences, then the
+ * > selection SHOULD be treated as matching all of the matches.”
+ *
+ * Note that if `scope` is *not* a Document, the [Web Annotation Data Model](https://www.w3.org/TR/2017/REC-annotation-model-20170223/#css-selector)
+ * leaves the behaviour undefined. This implementation will, in such a case,
+ * evaluate the selector relative to the document containing the scope, but only
+ * return those matches that are fully enclosed within the scope. There might be
+ * edge cases where this is not a perfect inverse of {@link describeCss}.
+ *
+ * @example
+ * ```
+ * const matches = createCssSelectorMatcher({
+ *   type: 'CssSelector',
+ *   value: '#target',
+ * });
+ * for await (const match of matches) {
+ *   console.log(match);
+ * }
+ * // <div id="target" …>
+ * ```
+ *
+ * @param selector - The {@link CssSelector} to be anchored.
+ * @returns A {@link Matcher} function that applies `selector` to a given
+ * `scope`.
+ *
+ * @public
+ */
 export function createCssSelectorMatcher(
   selector: CssSelector,
-): Matcher<Range, Range> {
+): Matcher<Node | Range, Element> {
   return async function* matchAll(scope) {
+    scope = toRange(scope);
     const document = ownerDocument(scope);
     for (const element of document.querySelectorAll(selector.value)) {
       const range = document.createRange();
@@ -36,8 +84,39 @@
         scope.isPointInRange(range.startContainer, range.startOffset) &&
         scope.isPointInRange(range.endContainer, range.endOffset)
       ) {
-        yield range;
+        yield element;
       }
     }
   };
 }
+
+/**
+ * Returns a {@link CssSelector} that unambiguously describes the given
+ * element, within the given scope.
+ *
+ * @example
+ * ```
+ * const target = document.getElementById('targetelement').firstElementChild;
+ * const selector = await describeCss(target);
+ * console.log(selector);
+ * // {
+ * //   type: 'CssSelector',
+ * //   value: '#targetelement > :nth-child(1)'
+ * // }
+ * ```
+ *
+ * @param element - The element that the selector should describe.
+ * @param scope - The node that serves as the ‘document’ for purposes of finding
+ * an unambiguous selector. Defaults to the Document that contains `element`.
+ * @returns The selector unambiguously describing `element` within `scope`.
+ */
+export async function describeCss(
+  element: HTMLElement,
+  scope: Node = element.ownerDocument,
+): Promise<CssSelector> {
+  const selector = optimalSelect(element, { root: scope });
+  return {
+    type: 'CssSelector',
+    value: selector,
+  };
+}
diff --git a/packages/dom/src/highlight-range.ts b/packages/dom/src/highlight-text.ts
similarity index 80%
rename from packages/dom/src/highlight-range.ts
rename to packages/dom/src/highlight-text.ts
index f3345f5..aebe2d9 100644
--- a/packages/dom/src/highlight-range.ts
+++ b/packages/dom/src/highlight-text.ts
@@ -21,24 +21,37 @@
  */
 
 import { ownerDocument } from './owner-document';
+import { toRange } from './to-range';
 
-// Wrap each text node in a given DOM Range with a <mark> or other element.
-// Breaks start and/or end node if needed.
-// Returns a function that cleans up the created highlight (not a perfect undo: split text nodes are
-// not merged again; if desired, you could run range.commonAncestorContainer.normalize() afterwards).
-//
-// Parameters:
-// - range: a DOM Range object. Note that as highlighting modifies the DOM, the range may be
-//   unusable afterwards
-// - tagName: the element used to wrap text nodes. Defaults to 'mark'.
-// - attributes: an Object defining any attributes to be set on the wrapper elements.
-export function highlightRange(
-  range: Range,
+/**
+ * Wrap each text node in a given Node or Range with a `<mark>` or other
+ * element.
+ *
+ * If a Range is given that starts and/or ends within a Text node, that node
+ * will be split in order to only wrap the contained part in the mark element.
+ *
+ * The highlight can be removed again by calling the function that cleans up the
+ * wrapper elements. Note that this might not perfectly restore the DOM to its
+ * previous state: text nodes that were split are not merged again. One could
+ * consider running `range.commonAncestorContainer.normalize()` afterwards to
+ * join all adjacent text nodes.
+ *
+ * @param target - The Node/Range containing the text. If it is a Range, note
+ * that as highlighting modifies the DOM, the Range may be unusable afterwards.
+ * @param tagName - The element used to wrap text nodes. Defaults to `'mark'`.
+ * @param attributes - An object defining any attributes to be set on the
+ * wrapper elements, e.g. its `class`.
+ * @returns A function that removes the created highlight.
+ *
+ * @public
+ */
+export function highlightText(
+  target: Node | Range,
   tagName = 'mark',
   attributes: Record<string, string> = {},
 ): () => void {
   // First put all nodes in an array (splits start and end nodes if needed)
-  const nodes = textNodesInRange(range);
+  const nodes = textNodesInRange(toRange(target));
 
   // Highlight each node
   const highlightElements: HTMLElement[] = [];
diff --git a/packages/dom/src/index.ts b/packages/dom/src/index.ts
index 7ecb4ef..33a4cb8 100644
--- a/packages/dom/src/index.ts
+++ b/packages/dom/src/index.ts
@@ -24,4 +24,4 @@
 export * from './range';
 export * from './text-quote';
 export * from './text-position';
-export * from './highlight-range';
+export * from './highlight-text';
diff --git a/packages/dom/src/normalize-range.ts b/packages/dom/src/normalize-range.ts
index d5705a7..1094540 100644
--- a/packages/dom/src/normalize-range.ts
+++ b/packages/dom/src/normalize-range.ts
@@ -22,10 +22,12 @@
 
 import { ownerDocument } from './owner-document';
 
-// TextRange is a Range that guarantees to always have Text nodes as its start
-// and end nodes. To ensure the type remains correct, it also restricts usage
-// of methods that would modify these nodes (note that a user can simply cast
-// the TextRange back to a Range to remove these restrictions).
+/**
+ * TextRange is a Range that guarantees to always have Text nodes as its start
+ * and end nodes. To ensure the type remains correct, it also restricts usage
+ * of methods that would modify these nodes (note that a user can simply cast
+ * the TextRange back to a Range to remove these restrictions).
+ */
 export interface TextRange extends Range {
   readonly startContainer: Text;
   readonly endContainer: Text;
@@ -46,17 +48,24 @@
   surroundContents(newParent: never): void;
 }
 
-// Normalise a range such that both its start and end are text nodes, and that
-// if there are equivalent text selections it takes the narrowest option (i.e.
-// it prefers the start not to be at the end of a text node, and vice versa).
-//
-// If there is no text between the start and end, they thus collapse onto one a
-// single position; and if there are multiple equivalent positions, it takes the
-// first one; or, if scope is passed, the first equivalent falling within scope.
-//
-// Note that if the given range does not contain non-empty text nodes, it will
-// end up pointing at a text node outside of it (before it if possible, else
-// after). If the document does not contain any text nodes, an error is thrown.
+/**
+ * Normalise a {@link https://developer.mozilla.org/en-US/docs/Web/API/Range |
+ * Range} such that ranges spanning the same text become exact equals.
+ *
+ * *Note: in this context ‘text’ means any characters, including whitespace.*
+
+ * Normalises a range such that both its start and end are text nodes, and that
+ * if there are equivalent text selections it takes the narrowest option (i.e.
+ * it prefers the start not to be at the end of a text node, and vice versa).
+ *
+ * If there is no text between the start and end, they thus collapse onto one a
+ * single position; and if there are multiple equivalent positions, it takes the
+ * first one; or, if scope is passed, the first equivalent falling within scope.
+ *
+ * Note that if the given range does not contain non-empty text nodes, it may
+ * end up pointing at a text node outside of it (before it if possible, else
+ * after). If the document does not contain any text nodes, an error is thrown.
+ */
 export function normalizeRange(range: Range, scope?: Range): TextRange {
   const document = ownerDocument(range);
   const walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT, {
diff --git a/packages/dom/src/owner-document.ts b/packages/dom/src/owner-document.ts
index bc5f03e..1991c94 100644
--- a/packages/dom/src/owner-document.ts
+++ b/packages/dom/src/owner-document.ts
@@ -20,8 +20,17 @@
  * under the License.
  */
 
-export function ownerDocument(range: Range): Document {
-  const { startContainer } = range;
+/**
+ * Get the ownerDocument for either a range or a node.
+ *
+ * @param nodeOrRange the node or range for which to get the owner document.
+ */
+export function ownerDocument(nodeOrRange: Node | Range): Document {
+  const node = isRange(nodeOrRange) ? nodeOrRange.startContainer : nodeOrRange;
   // node.ownerDocument is null iff node is itself a Document.
-  return startContainer.ownerDocument ?? (startContainer as Document);
+  return node.ownerDocument ?? (node as Document);
+}
+
+function isRange(nodeOrRange: Node | Range): nodeOrRange is Range {
+  return 'startContainer' in nodeOrRange;
 }
diff --git a/packages/dom/src/range/cartesian.ts b/packages/dom/src/range/cartesian.ts
index 367abeb..df6af23 100644
--- a/packages/dom/src/range/cartesian.ts
+++ b/packages/dom/src/range/cartesian.ts
@@ -40,46 +40,51 @@
     return generator();
   });
 
-  // Track the number of non-exhausted iterators.
-  let active = iterators.length;
+  try {
+    // Track the number of non-exhausted iterators.
+    let active = iterators.length;
 
-  // Track all the values of each iterator in a log.
-  const logs = iterators.map(() => []) as T[][];
+    // Track all the values of each iterator in a log.
+    const logs = iterators.map(() => []) as T[][];
 
-  // Track the promise of the next value of each iterator.
-  const nexts = iterators.map((it) => it.next());
+    // Track the promise of the next value of each iterator.
+    const nexts = iterators.map((it) => it.next());
 
-  // Iterate the values of all the iterators in parallel and yield tuples from
-  // the partial product of each new value and the existing logs of the other
-  // iterators.
-  while (active) {
-    // Wait for the next result.
-    const result = await Promise.race(nexts);
-    const { index } = result.value;
+    // Iterate the values of all the iterators in parallel and yield tuples from
+    // the partial product of each new value and the existing logs of the other
+    // iterators.
+    while (active) {
+      // Wait for the next result.
+      const result = await Promise.race(nexts);
+      const { index } = result.value;
 
-    // If the iterator has exhausted all the values, set the promise
-    // of its next value to never resolve.
-    if (result.done) {
-      active--;
-      nexts[index] = new Promise(() => undefined);
-      continue;
+      // If the iterator has exhausted all the values, set the promise
+      // of its next value to never resolve.
+      if (result.done) {
+        active--;
+        nexts[index] = new Promise(() => undefined);
+        continue;
+      }
+
+      // Append the new value to the log.
+      const { value } = result.value;
+      logs[index].push(value);
+
+      // Record the promise of the next value.
+      nexts[index] = iterators[index].next();
+
+      // Create a scratch input for computing a partial product.
+      const scratch = [...logs];
+      scratch[index] = [value];
+
+      // Synchronously compute and yield tuples of the partial product.
+      yield* scratch.reduce(
+        (acc, next) => acc.flatMap((v) => next.map((w) => [...v, w])),
+        [[]] as T[][],
+      );
     }
-
-    // Append the new value to the log.
-    const { value } = result.value;
-    logs[index].push(value);
-
-    // Record the promise of the next value.
-    nexts[index] = iterators[index].next();
-
-    // Create a scratch input for computing a partial product.
-    const scratch = [...logs];
-    scratch[index] = [value];
-
-    // Synchronously compute and yield tuples of the partial product.
-    yield* scratch.reduce(
-      (acc, next) => acc.flatMap((v) => next.map((w) => [...v, w])),
-      [[]] as T[][],
-    );
+  } finally {
+    const closeAll = iterators.map((it, index) => it.return({ index }));
+    await Promise.all(closeAll);
   }
 }
diff --git a/packages/dom/src/range/match.ts b/packages/dom/src/range/match.ts
index ddea2cf..83f33d9 100644
--- a/packages/dom/src/range/match.ts
+++ b/packages/dom/src/range/match.ts
@@ -26,11 +26,79 @@
   Selector,
 } from '@apache-annotator/selector';
 import { ownerDocument } from '../owner-document';
+import { toRange } from '../to-range';
 import { cartesian } from './cartesian';
 
+/**
+ * Find the range(s) corresponding to the given {@link RangeSelector}.
+ *
+ * As a RangeSelector itself nests two further selectors, one needs to pass a
+ * `createMatcher` function that will be used to process those nested selectors.
+ *
+ * The function is curried, taking first the `createMatcher` function, then the
+ * selector, and then the scope.
+ *
+ * As there may be multiple matches for the start & end selectors, the resulting
+ * matcher will return an (async) iterable, that produces a match for each
+ * possible pair of matches of the nested selectors (except those where its end
+ * would precede its start). *(Note that this behaviour is a rather free
+ * interpretation of the Web Annotation Data Model spec, which is silent about
+ * the possibility of multiple matches for RangeSelectors)*
+ *
+ * @example
+ * By using a matcher for {@link TextQuoteSelector}s, one
+ * could create a matcher for text quotes with ellipsis to select a phrase
+ * “ipsum … amet,”:
+ * ```
+ * const selector = {
+ *   type: 'RangeSelector',
+ *   startSelector: {
+ *     type: 'TextQuoteSelector',
+ *     exact: 'ipsum ',
+ *   },
+ *   endSelector: {
+ *     type: 'TextQuoteSelector',
+ *     // Because the end of a RangeSelector is *exclusive*, we will present the
+ *     // latter part of the quote as the *prefix* so it will be part of the
+ *     // match.
+ *     exact: '',
+ *     prefix: ' amet,',
+ *   }
+ * };
+ * const createRangeSelectorMatcher =
+ *   makeCreateRangeSelectorMatcher(createTextQuoteMatcher);
+ * const match = createRangeSelectorMatcher(selector)(document.body);
+ * console.log(match)
+ * // ⇒ Range { startContainer: #text, startOffset: 6, endContainer: #text,
+ * //   endOffset: 27, … }
+ * ```
+ *
+ * @example
+ * To support RangeSelectors that might themselves contain RangeSelectors,
+ * recursion can be created by supplying the resulting matcher creator function
+ * as the `createMatcher` parameter:
+ * ```
+ * const createWhicheverMatcher = (selector) => {
+ *   const innerCreateMatcher = {
+ *     TextQuoteSelector: createTextQuoteSelectorMatcher,
+ *     TextPositionSelector: createTextPositionSelectorMatcher,
+ *     RangeSelector: makeCreateRangeSelectorMatcher(createWhicheverMatcher),
+ *   }[selector.type];
+ *   return innerCreateMatcher(selector);
+ * });
+ * ```
+ *
+ * @param createMatcher - The function used to process nested selectors.
+ * @returns A function that, given a RangeSelector `selector`, creates a {@link
+ * Matcher} function that can apply it to a given `scope`.
+ *
+ * @public
+ */
 export function makeCreateRangeSelectorMatcher(
-  createMatcher: <T extends Selector>(selector: T) => Matcher<Range, Range>,
-): (selector: RangeSelector) => Matcher<Range, Range> {
+  createMatcher: <T extends Selector, TMatch extends Node | Range>(
+    selector: T,
+  ) => Matcher<Node | Range, TMatch>,
+): (selector: RangeSelector) => Matcher<Node | Range, Range> {
   return function createRangeSelectorMatcher(selector) {
     const startMatcher = createMatcher(selector.startSelector);
     const endMatcher = createMatcher(selector.endSelector);
@@ -41,10 +109,14 @@
 
       const pairs = cartesian(startMatches, endMatches);
 
-      for await (const [start, end] of pairs) {
-        const result = ownerDocument(scope).createRange();
+      for await (let [start, end] of pairs) {
+        start = toRange(start);
+        end = toRange(end);
 
+        const result = ownerDocument(scope).createRange();
         result.setStart(start.startContainer, start.startOffset);
+        // Note that a RangeSelector’s match *excludes* the endSelector’s match,
+        // hence we take the end’s startContainer & startOffset.
         result.setEnd(end.startContainer, end.startOffset);
 
         if (!result.collapsed) yield result;
diff --git a/packages/dom/src/text-node-chunker.ts b/packages/dom/src/text-node-chunker.ts
index 72a8913..fa3de07 100644
--- a/packages/dom/src/text-node-chunker.ts
+++ b/packages/dom/src/text-node-chunker.ts
@@ -23,6 +23,7 @@
 import type { Chunk, Chunker, ChunkRange } from '@apache-annotator/selector';
 import { normalizeRange } from './normalize-range';
 import { ownerDocument } from './owner-document';
+import { toRange } from './to-range';
 
 export interface PartialTextNode extends Chunk<string> {
   readonly node: Text;
@@ -46,6 +47,7 @@
 }
 
 export class TextNodeChunker implements Chunker<PartialTextNode> {
+  private scope: Range;
   private iter: NodeIterator;
 
   get currentChunk(): PartialTextNode {
@@ -118,13 +120,14 @@
   /**
    * @param scope A Range that overlaps with at least one text node.
    */
-  constructor(private scope: Range) {
+  constructor(scope: Node | Range) {
+    this.scope = toRange(scope);
     this.iter = ownerDocument(scope).createNodeIterator(
-      scope.commonAncestorContainer,
+      this.scope.commonAncestorContainer,
       NodeFilter.SHOW_TEXT,
       {
-        acceptNode(node: Text) {
-          return scope.intersectsNode(node)
+        acceptNode: (node: Text) => {
+          return this.scope.intersectsNode(node)
             ? NodeFilter.FILTER_ACCEPT
             : NodeFilter.FILTER_REJECT;
         },
diff --git a/packages/dom/src/text-position/describe.ts b/packages/dom/src/text-position/describe.ts
index c1b5055..3ad3bec 100644
--- a/packages/dom/src/text-position/describe.ts
+++ b/packages/dom/src/text-position/describe.ts
@@ -24,24 +24,48 @@
 import { describeTextPosition as abstractDescribeTextPosition } from '@apache-annotator/selector';
 import { ownerDocument } from '../owner-document';
 import { TextNodeChunker } from '../text-node-chunker';
+import { toRange } from '../to-range';
 
+/**
+ * Returns a {@link TextPositionSelector} that points at the target text within
+ * the given scope.
+ *
+ * When no scope is given, the position is described relative to the document
+ * as a whole. Note this means all the characters in all Text nodes are counted
+ * to determine the target’s position, including those in the `<head>` and
+ * whitespace, hence even a minor modification could make the selector point to
+ * a different text than its original target.
+ *
+ * @example
+ * ```
+ * const target = window.getSelection().getRangeAt(0);
+ * const selector = await describeTextPosition(target);
+ * console.log(selector);
+ * // {
+ * //   type: 'TextPositionSelector',
+ * //   start: 702,
+ * //   end: 736
+ * // }
+ * ```
+ *
+ * @param range - The {@link https://developer.mozilla.org/en-US/docs/Web/API/Range
+ * | Range} whose text content will be described.
+ * @param scope - A Node or Range that serves as the ‘document’ for purposes of
+ * finding occurrences and determining prefix and suffix. Defaults to the full
+ * Document that contains `range`.
+ * @returns The selector describing `range` within `scope`.
+ *
+ * @public
+ */
 export async function describeTextPosition(
   range: Range,
-  maybeScope?: Range,
+  scope?: Node | Range,
 ): Promise<TextPositionSelector> {
-  // Default to search in the whole document.
-  let scope: Range;
-  if (maybeScope !== undefined) {
-    scope = maybeScope;
-  } else {
-    const document = ownerDocument(range);
-    scope = document.createRange();
-    scope.selectNodeContents(document);
-  }
+  scope = toRange(scope ?? ownerDocument(range));
 
   const textChunks = new TextNodeChunker(scope);
   if (textChunks.currentChunk === null)
-    throw new RangeError('Range does not contain any Text nodes.');
+    throw new RangeError('Scope does not contain any Text nodes.');
 
   return await abstractDescribeTextPosition(
     textChunks.rangeToChunkRange(range),
diff --git a/packages/dom/src/text-position/match.ts b/packages/dom/src/text-position/match.ts
index a45f7b5..b171678 100644
--- a/packages/dom/src/text-position/match.ts
+++ b/packages/dom/src/text-position/match.ts
@@ -24,9 +24,38 @@
 import { textPositionSelectorMatcher as abstractTextPositionSelectorMatcher } from '@apache-annotator/selector';
 import { TextNodeChunker } from '../text-node-chunker';
 
+/**
+ * Find the range of text corresponding to the given {@link
+ * TextPositionSelector}.
+ *
+ * The start and end positions are measured relative to the first text character
+ * in the given scope.
+ *
+ * The function is curried, taking first the selector and then the scope.
+ *
+ * Its end result is an (async) generator producing a single {@link https://developer.mozilla.org/en-US/docs/Web/API/Range
+ * | Range} to represent the match (unlike e.g. a {@link TextQuoteSelector}, a
+ * TextPositionSelector cannot have multiple matches).
+ *
+ * @example
+ * ```
+ * const selector = { type: 'TextPositionSelector', start: 702, end: 736 };
+ * const scope = document.body;
+ * const matches = textQuoteSelectorMatcher(selector)(scope);
+ * const match = (await matches.next()).value;
+ * // ⇒ Range { startContainer: #text, startOffset: 64, endContainer: #text,
+ * //   endOffset: 98, … }
+ * ```
+ *
+ * @param selector - The {@link TextPositionSelector} to be anchored.
+ * @returns A {@link Matcher} function that applies `selector` within a given
+ * `scope`.
+ *
+ * @public
+ */
 export function createTextPositionSelectorMatcher(
   selector: TextPositionSelector,
-): Matcher<Range, Range> {
+): Matcher<Node | Range, Range> {
   const abstractMatcher = abstractTextPositionSelectorMatcher(selector);
 
   return async function* matchAll(scope) {
diff --git a/packages/dom/src/text-quote/describe.ts b/packages/dom/src/text-quote/describe.ts
index 544dd0b..987b7fa 100644
--- a/packages/dom/src/text-quote/describe.ts
+++ b/packages/dom/src/text-quote/describe.ts
@@ -27,27 +27,54 @@
 import { describeTextQuote as abstractDescribeTextQuote } from '@apache-annotator/selector';
 import { ownerDocument } from '../owner-document';
 import { TextNodeChunker } from '../text-node-chunker';
+import { toRange } from '../to-range';
 
+/**
+ * Returns a {@link TextQuoteSelector} that unambiguously describes the given
+ * range of text, within the given scope.
+ *
+ * The selector will contain the *exact* target quote, and in case this quote
+ * appears multiple times in the text, sufficient context around the quote will
+ * be included in the selector’s *prefix* and *suffix* attributes to
+ * disambiguate. By default, more prefix and suffix are included than strictly
+ * required; both in order to be robust against slight modifications, and in an
+ * attempt to not end halfway a word (mainly for the sake of human readability).
+ *
+ * @example
+ * ```
+ * const target = window.getSelection().getRangeAt(0);
+ * const selector = await describeTextQuote(target);
+ * console.log(selector);
+ * // {
+ * //   type: 'TextQuoteSelector',
+ * //   exact: 'ipsum',
+ * //   prefix: 'Lorem ',
+ * //   suffix: ' dolor'
+ * // }
+ * ```
+ *
+ * @param range - The {@link https://developer.mozilla.org/en-US/docs/Web/API/Range
+ * | Range} whose text content will be described
+ * @param scope - A Node or Range that serves as the ‘document’ for purposes of
+ * finding occurrences and determining prefix and suffix. Defaults to the full
+ * Document that contains `range`.
+ * @param options - Options to fine-tune the function’s behaviour.
+ * @returns The selector unambiguously describing `range` within `scope`.
+ *
+ * @public
+ */
 export async function describeTextQuote(
   range: Range,
-  maybeScope?: Range,
+  scope?: Node | Range,
   options: DescribeTextQuoteOptions = {},
 ): Promise<TextQuoteSelector> {
-  // Default to search in the whole document.
-  let scope: Range;
-  if (maybeScope !== undefined) {
-    scope = maybeScope;
-  } else {
-    const document = ownerDocument(range);
-    scope = document.createRange();
-    scope.selectNodeContents(document);
-  }
+  const scopeAsRange = toRange(scope ?? ownerDocument(range));
 
-  const chunker = new TextNodeChunker(scope);
+  const chunker = new TextNodeChunker(scopeAsRange);
 
   return await abstractDescribeTextQuote(
     chunker.rangeToChunkRange(range),
-    () => new TextNodeChunker(scope),
+    () => new TextNodeChunker(scopeAsRange),
     options,
   );
 }
diff --git a/packages/dom/src/text-quote/match.ts b/packages/dom/src/text-quote/match.ts
index e1f3781..9692106 100644
--- a/packages/dom/src/text-quote/match.ts
+++ b/packages/dom/src/text-quote/match.ts
@@ -24,9 +24,52 @@
 import { textQuoteSelectorMatcher as abstractTextQuoteSelectorMatcher } from '@apache-annotator/selector';
 import { TextNodeChunker, EmptyScopeError } from '../text-node-chunker';
 
+/**
+ * Find occurrences in a text matching the given {@link
+ * TextQuoteSelector}.
+ *
+ * This performs an exact search for the selector’s quote (including prefix and
+ * suffix) within the text contained in the given scope (a  {@link
+ * https://developer.mozilla.org/en-US/docs/Web/API/Range | Range}).
+ *
+ * Note the match is based on strict character-by-character equivalence, i.e.
+ * it is sensitive to whitespace, capitalisation, etc.
+ *
+ * The function is curried, taking first the selector and then the scope.
+ *
+ * As there may be multiple matches for a given selector (when its prefix and
+ * suffix attributes are not sufficient to disambiguate it), the matcher will
+ * return an (async) generator that produces each match in the order they are
+ * found in the text.
+ *
+ * *XXX Modifying the DOM (e.g. to highlight the text) while the search is still
+ * running can mess up and result in an error or an infinite loop. See [issue
+ * #112](https://github.com/apache/incubator-annotator/issues/112).*
+ *
+ * @example
+ * ```
+ * // Find the word ‘banana’.
+ * const selector = { type: 'TextQuoteSelector', exact: 'banana' };
+ * const scope = document.body;
+ *
+ * // Read all matches.
+ * const matches = textQuoteSelectorMatcher(selector)(scope);
+ * for await (match of matches) console.log(match);
+ * // ⇒ Range { startContainer: #text, startOffset: 187, endContainer: #text,
+ * //   endOffset: 193, … }
+ * // ⇒ Range { startContainer: #text, startOffset: 631, endContainer: #text,
+ * //   endOffset: 637, … }
+ * ```
+ *
+ * @param selector - The {@link TextQuoteSelector} to be anchored.
+ * @returns A {@link Matcher} function that applies `selector` within a given
+ * `scope`.
+ *
+ * @public
+ */
 export function createTextQuoteSelectorMatcher(
   selector: TextQuoteSelector,
-): Matcher<Range, Range> {
+): Matcher<Node | Range, Range> {
   const abstractMatcher = abstractTextQuoteSelectorMatcher(selector);
 
   return async function* matchAll(scope) {
@@ -34,8 +77,8 @@
     try {
       textChunks = new TextNodeChunker(scope);
     } catch (err) {
-      if (err instanceof EmptyScopeError) return;
       // An empty range contains no matches.
+      if (err instanceof EmptyScopeError) return;
       else throw err;
     }
 
diff --git a/packages/dom/src/to-range.ts b/packages/dom/src/to-range.ts
new file mode 100644
index 0000000..a2b92da
--- /dev/null
+++ b/packages/dom/src/to-range.ts
@@ -0,0 +1,47 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { ownerDocument } from './owner-document';
+
+/**
+ * Returns a range that exactly selects the contents of the given node.
+ *
+ * This function is idempotent: If the given argument is already a range, it
+ * simply returns that range.
+ *
+ * @param nodeOrRange The node/range to convert to a range if it is not already
+ * a range.
+ */
+export function toRange(nodeOrRange: Node | Range): Range {
+  if (isRange(nodeOrRange)) {
+    return nodeOrRange;
+  } else {
+    const node = nodeOrRange;
+    const range = ownerDocument(node).createRange();
+    range.selectNodeContents(node);
+    return range;
+  }
+}
+
+function isRange(nodeOrRange: Node | Range): nodeOrRange is Range {
+  return 'startContainer' in nodeOrRange;
+}
diff --git a/packages/dom/test/css/describe.test.ts b/packages/dom/test/css/describe.test.ts
new file mode 100644
index 0000000..ab535bb
--- /dev/null
+++ b/packages/dom/test/css/describe.test.ts
@@ -0,0 +1,60 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { assert } from 'chai';
+import { describeCss } from '../../src/css';
+import { evaluateXPath } from '../utils';
+import { testCases } from './match-cases';
+
+const domParser = new DOMParser();
+
+describe('describeCss', () => {
+  describe('inverts test cases of css matcher', () => {
+    for (const [name, { html, scopeXPath, expected }] of Object.entries(
+      testCases,
+    )) {
+      for (let i = 0; i < expected.length; i++) {
+        const elementXPath = expected[i];
+        it(`case: '${name}' (${i + 1}/${expected.length})`, async () => {
+          const doc = domParser.parseFromString(html, 'text/html');
+          const element = evaluateXPath(doc, elementXPath) as HTMLElement;
+          const scopeElement = scopeXPath
+            ? (evaluateXPath(doc, scopeXPath) as HTMLElement)
+            : undefined;
+          const cssSelector = await describeCss(element, scopeElement);
+
+          // We do not require a specific value for the selector, just
+          // that it uniquely matches the same element again.
+          const matchingElements = (scopeElement ?? doc).querySelectorAll(
+            cssSelector.value,
+          );
+          assert.equal(
+            matchingElements.length,
+            1,
+            'Expected a selector with a single match',
+          );
+          assert.equal(matchingElements[0], element);
+        });
+      }
+    }
+  });
+});
diff --git a/packages/dom/test/css/match-cases.ts b/packages/dom/test/css/match-cases.ts
new file mode 100644
index 0000000..becb121
--- /dev/null
+++ b/packages/dom/test/css/match-cases.ts
@@ -0,0 +1,58 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { CssSelector } from '@apache-annotator/selector';
+
+export const testCases: {
+  [name: string]: {
+    html: string;
+    selector: CssSelector;
+    scopeXPath?: string;
+    expected: string[];
+  };
+} = {
+  simple: {
+    html: '<b>lorem <i>ipsum</i> dolor <i>amet</i> yada <i>yada</i></b>',
+    selector: {
+      type: 'CssSelector',
+      value: 'i:nth-child(2)',
+    },
+    expected: ['//b/i[2]'],
+  },
+  'multiple matches': {
+    html: '<b>lorem <i>ipsum</i> dolor <i>amet</i> yada <i>yada</i></b>',
+    selector: {
+      type: 'CssSelector',
+      value: 'i',
+    },
+    expected: ['//b/i[1]', '//b/i[2]', '//b/i[3]'],
+  },
+  'with scope': {
+    html: '<b>lorem <i>ipsum</i> dolor <u><i>amet</i> yada <i>yada</i></u></b>',
+    selector: {
+      type: 'CssSelector',
+      value: 'i',
+    },
+    scopeXPath: '//u',
+    expected: ['//u/i[1]', '//u/i[2]'],
+  },
+};
diff --git a/packages/dom/test/css/match.test.ts b/packages/dom/test/css/match.test.ts
new file mode 100644
index 0000000..3e379ba
--- /dev/null
+++ b/packages/dom/test/css/match.test.ts
@@ -0,0 +1,61 @@
+/**
+ * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+ * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { assert } from 'chai';
+import type { CssSelector } from '@apache-annotator/selector';
+import { createCssSelectorMatcher } from '../../src/css';
+import { evaluateXPath } from '../utils';
+import { testCases } from './match-cases';
+
+const domParser = new DOMParser();
+
+describe('CreateCssSelectorMatcher', () => {
+  for (const [name, { html, selector, scopeXPath, expected }] of Object.entries(
+    testCases,
+  )) {
+    it(`works for case: '${name}'`, async () => {
+      const doc = domParser.parseFromString(html, 'text/html');
+
+      const scopeElement = scopeXPath ? evaluateXPath(doc, scopeXPath) : doc;
+      const scope = doc.createRange();
+      scope.selectNodeContents(scopeElement);
+
+      await testMatcher(doc, scope, selector, expected);
+    });
+  }
+});
+
+async function testMatcher(
+  doc: Document,
+  scope: Range,
+  selector: CssSelector,
+  expected: string[],
+) {
+  const matcher = createCssSelectorMatcher(selector);
+  const matches = [];
+  for await (const value of matcher(scope)) matches.push(value);
+  assert.equal(matches.length, expected.length, 'Unexpected number of matches');
+  matches.forEach((match, i) => {
+    const expectedElement = evaluateXPath(doc, expected[i]);
+    assert.equal(match, expectedElement);
+  });
+}
diff --git a/packages/dom/test/highlight-range/highlight-range.test.ts b/packages/dom/test/highlight-text/highlight-text.test.ts
similarity index 89%
rename from packages/dom/test/highlight-range/highlight-range.test.ts
rename to packages/dom/test/highlight-text/highlight-text.test.ts
index 12adb23..df86aa3 100644
--- a/packages/dom/test/highlight-range/highlight-range.test.ts
+++ b/packages/dom/test/highlight-text/highlight-text.test.ts
@@ -21,11 +21,11 @@
  */
 
 import { assert } from 'chai';
-import { highlightRange } from '../../src/highlight-range';
+import { highlightText } from '../../src/highlight-text';
 import type { RangeInfo } from '../utils';
 import { hydrateRange, evaluateXPath } from '../utils';
 
-const domParser = new window.DOMParser();
+const domParser = new DOMParser();
 
 const testCases: {
   [name: string]: {
@@ -107,7 +107,7 @@
   },
 };
 
-describe('highlightRange', () => {
+describe('highlightText', () => {
   for (const [
     name,
     { inputHtml, range, tagName, attributes, expectedHtml },
@@ -115,8 +115,8 @@
     it(`works for case: ${name}`, () => {
       const doc = domParser.parseFromString(inputHtml, 'text/html');
 
-      // Invoke highlightRange for the specified Range, and check the result.
-      const removeHighlights = highlightRange(
+      // Invoke highlightText for the specified Range, and check the result.
+      const removeHighlights = highlightText(
         hydrateRange(range, doc),
         tagName,
         attributes,
@@ -140,7 +140,7 @@
     range.setStart(evaluateXPath(doc, '//b/text()[1]'), 12); // before 'dolor am'
     range.setEnd(evaluateXPath(doc, '//b/text()[2]'), 20 - 15); // after 'dolor am'
 
-    const removeHighlights = highlightRange(range);
+    const removeHighlights = highlightText(range);
     const expectedHtml =
       '<b>lorem ipsum <mark>dol</mark><mark>or am</mark>et yada yada</b>';
     assert.equal(doc.body.innerHTML, expectedHtml);
@@ -161,7 +161,7 @@
     range.setStart(evaluateXPath(doc, '//b/text()[1]'), 12); // before 'dolor am'
     range.setEnd(evaluateXPath(doc, '//b/text()[3]'), 20 - 15); // after 'dolor am'
 
-    const removeHighlights = highlightRange(range);
+    const removeHighlights = highlightText(range);
     const expectedHtml =
       '<b>lorem ipsum <mark>dol</mark><mark></mark><mark>or am</mark>et yada yada</b>';
     assert.equal(doc.body.innerHTML, expectedHtml);
@@ -177,7 +177,7 @@
     const range = doc.createRange();
     range.selectNode(evaluateXPath(doc, '//img'));
 
-    const removeHighlights = highlightRange(range);
+    const removeHighlights = highlightText(range);
     assert.equal(doc.body.innerHTML, inputHtml);
 
     removeHighlights();
@@ -189,11 +189,8 @@
     const { range: range2, expectedHtml } = testCases['overlapping highlight'];
     const doc = domParser.parseFromString(inputHtml, 'text/html');
 
-    const removeHighlights1 = highlightRange(hydrateRange(range, doc));
-    const removeHighlights2 = highlightRange(
-      hydrateRange(range2, doc),
-      'mark2',
-    );
+    const removeHighlights1 = highlightText(hydrateRange(range, doc));
+    const removeHighlights2 = highlightText(hydrateRange(range2, doc), 'mark2');
     assert.equal(doc.body.innerHTML, expectedHtml);
 
     removeHighlights1();
@@ -206,11 +203,8 @@
     const { range: range2, expectedHtml } = testCases['overlapping highlight'];
     const doc = domParser.parseFromString(inputHtml, 'text/html');
 
-    const removeHighlights1 = highlightRange(hydrateRange(range, doc));
-    const removeHighlights2 = highlightRange(
-      hydrateRange(range2, doc),
-      'mark2',
-    );
+    const removeHighlights1 = highlightText(hydrateRange(range, doc));
+    const removeHighlights2 = highlightText(hydrateRange(range2, doc), 'mark2');
     assert.equal(doc.body.innerHTML, expectedHtml);
 
     removeHighlights2();
diff --git a/packages/dom/test/range/cartesian.test.ts b/packages/dom/test/range/cartesian.test.ts
index 11b8362..5e7958d 100644
--- a/packages/dom/test/range/cartesian.test.ts
+++ b/packages/dom/test/range/cartesian.test.ts
@@ -58,4 +58,33 @@
 
     assert.sameDeepMembers(actual, expected, 'yields the expected items');
   });
+
+  it('re-raises exceptions and closes iterators', async () => {
+    let didClose = false;
+    const error = new Error();
+
+    async function* throws() {
+      yield 1;
+      throw error;
+    }
+
+    async function* works() {
+      try {
+        yield 2;
+        yield 3;
+      } finally {
+        didClose = true;
+      }
+    }
+
+    try {
+      // eslint-disable-next-line
+      const cart = cartesian(throws(), works());
+      await cart.next();
+      await cart.next();
+    } catch (e) {
+      assert.strictEqual(error, e, 're-raises an error from an iterable');
+      assert.isTrue(didClose, 'closes the iterators');
+    }
+  });
 });
diff --git a/packages/dom/test/text-position/describe.test.ts b/packages/dom/test/text-position/describe.test.ts
index f858dca..a8ecaf0 100644
--- a/packages/dom/test/text-position/describe.test.ts
+++ b/packages/dom/test/text-position/describe.test.ts
@@ -25,7 +25,7 @@
 import { hydrateRange } from '../utils';
 import { testCases } from './match-cases';
 
-const domParser = new window.DOMParser();
+const domParser = new DOMParser();
 
 describe('createTextPositionSelectorMatcher', () => {
   describe('inverts test cases of text position matcher', () => {
@@ -35,11 +35,9 @@
       const range = expected[0];
       it(`case: '${name}'`, async () => {
         const doc = domParser.parseFromString(html, 'text/html');
-        const scope = doc.createRange();
-        scope.selectNodeContents(doc);
         const result = await describeTextPosition(
           hydrateRange(range, doc),
-          scope,
+          doc,
         );
         assert.deepEqual(result, selector);
       });
diff --git a/packages/dom/test/text-position/match.test.ts b/packages/dom/test/text-position/match.test.ts
index 7f79cdf..f0251d7 100644
--- a/packages/dom/test/text-position/match.test.ts
+++ b/packages/dom/test/text-position/match.test.ts
@@ -23,11 +23,11 @@
 import { assert } from 'chai';
 import type { TextPositionSelector } from '@apache-annotator/selector';
 import { createTextPositionSelectorMatcher } from '../../src/text-position/match';
-import { evaluateXPath } from '../utils';
+import { evaluateXPath, assertRangeEquals } from '../utils';
 import type { RangeInfo } from '../utils';
 import { testCases } from './match-cases';
 
-const domParser = new window.DOMParser();
+const domParser = new DOMParser();
 
 describe('createTextPositionSelectorMatcher', () => {
   for (const [name, { html, selector, expected }] of Object.entries(
@@ -35,28 +35,20 @@
   )) {
     it(`works for case: '${name}'`, async () => {
       const doc = domParser.parseFromString(html, 'text/html');
-
-      const scope = doc.createRange();
-      scope.selectNodeContents(doc);
-
-      await testMatcher(doc, scope, selector, expected);
+      await testMatcher(doc, selector, expected);
     });
   }
 
   it('handles adjacent text nodes', async () => {
     const { html, selector } = testCases['simple'];
     const doc = domParser.parseFromString(html, 'text/html');
-
-    const scope = doc.createRange();
-    scope.selectNodeContents(doc);
-
     const textNode = evaluateXPath(doc, '//b/text()') as Text;
 
     textNode.splitText(16);
     // console.log([...textNode.parentNode.childNodes].map(node => node.textContent))
     // → [ 'l😃rem ipsum dol', 'or amet yada yada' ]
 
-    await testMatcher(doc, scope, selector, [
+    await testMatcher(doc, selector, [
       {
         startContainerXPath: '//b/text()[1]',
         startOffset: 13,
@@ -70,9 +62,6 @@
     const { html, selector } = testCases['simple'];
     const doc = domParser.parseFromString(html, 'text/html');
 
-    const scope = doc.createRange();
-    scope.selectNodeContents(doc);
-
     const textNode = evaluateXPath(doc, '//b/text()') as Text;
     textNode.splitText(textNode.length);
     textNode.splitText(21);
@@ -85,7 +74,7 @@
     // console.log([...textNode.parentNode.childNodes].map(node => node.textContent))
     // → [ '', 'l😃rem ipsum ', '', 'dolor', '', ' am', '', 'et yada yada', '' ]
 
-    await testMatcher(doc, scope, selector, [
+    await testMatcher(doc, selector, [
       {
         startContainerXPath: '//b/text()[4]', // "dolor"
         startOffset: 0,
@@ -102,7 +91,7 @@
     const scope = doc.createRange();
     scope.selectNodeContents(evaluateXPath(doc, '//b/text()'));
 
-    await testMatcher(doc, scope, selector, expected);
+    await testMatcher(scope, selector, expected);
   });
 
   it('works when scope starts with an empty text node, matching its first characters', async () => {
@@ -115,7 +104,7 @@
     const scope = doc.createRange();
     scope.selectNodeContents(evaluateXPath(doc, '//b'));
 
-    await testMatcher(doc, scope, selector, [
+    await testMatcher(scope, selector, [
       {
         startContainerXPath: '//b/text()[2]',
         startOffset: 0,
@@ -141,7 +130,7 @@
       end: 14,
     };
 
-    await testMatcher(doc, scope, selector, expected);
+    await testMatcher(scope, selector, expected);
   });
 
   it('works when scope has both ends inside text nodes', async () => {
@@ -159,7 +148,7 @@
       end: 12,
     };
 
-    await testMatcher(doc, scope, selector, expected);
+    await testMatcher(scope, selector, expected);
   });
 
   it('works when scope has both ends inside an element', async () => {
@@ -174,55 +163,19 @@
       start: 6,
       end: 14,
     };
-    await testMatcher(doc, scope, selector, expected);
+    await testMatcher(scope, selector, expected);
   });
 });
 
 async function testMatcher(
-  doc: Document,
-  scope: Range,
+  scope: Node | Range,
   selector: TextPositionSelector,
   expected: RangeInfo[],
 ) {
   const matcher = createTextPositionSelectorMatcher(selector);
-  const matches = [];
-  for await (const value of matcher(scope)) matches.push(value);
-  assert.equal(matches.length, expected.length);
-  matches.forEach((match, i) => {
-    const expectedRange = expected[i];
-    const expectedStartContainer = evaluateXPath(
-      doc,
-      expectedRange.startContainerXPath,
-    );
-    const expectedEndContainer = evaluateXPath(
-      doc,
-      expectedRange.endContainerXPath,
-    );
-    assert(
-      match.startContainer === expectedStartContainer,
-      `unexpected start container: ${prettyNodeName(match.startContainer)}; ` +
-        `expected ${prettyNodeName(expectedStartContainer)}`,
-    );
-    assert.equal(match.startOffset, expectedRange.startOffset);
-    assert(
-      match.endContainer ===
-        evaluateXPath(doc, expectedRange.endContainerXPath),
-      `unexpected end container: ${prettyNodeName(match.endContainer)}; ` +
-        `expected ${prettyNodeName(expectedEndContainer)}`,
-    );
-    assert.equal(match.endOffset, expectedRange.endOffset);
-  });
-}
-
-function prettyNodeName(node: Node) {
-  switch (node.nodeType) {
-    case Node.TEXT_NODE: {
-      const text = (node as Text).nodeValue || '';
-      return `#text "${text.length > 50 ? text.substring(0, 50) + '…' : text}"`;
-    }
-    case Node.ELEMENT_NODE:
-      return `<${(node as Element).tagName.toLowerCase()}>`;
-    default:
-      return node.nodeName.toLowerCase();
+  let count = 0;
+  for await (const match of matcher(scope)) {
+    assertRangeEquals(match, expected[count++]);
   }
+  assert.equal(count, expected.length, 'Wrong number of matches.');
 }
diff --git a/packages/dom/test/text-quote/describe.test.ts b/packages/dom/test/text-quote/describe.test.ts
index b76015a..b5439ee 100644
--- a/packages/dom/test/text-quote/describe.test.ts
+++ b/packages/dom/test/text-quote/describe.test.ts
@@ -32,7 +32,7 @@
 } from './describe-cases';
 import { testCases as testMatchCases } from './match-cases';
 
-const domParser = new window.DOMParser();
+const domParser = new DOMParser();
 
 function runTestCases(testCases: DescribeTextQuoteTestCases) {
   for (const [name, { html, range, expected, options }] of Object.entries(
@@ -40,11 +40,9 @@
   )) {
     it(`works for case: ${name}`, async () => {
       const doc = domParser.parseFromString(html, 'text/html');
-      const scope = doc.createRange();
-      scope.selectNodeContents(doc);
       const result = await describeTextQuote(
         hydrateRange(range, doc),
-        scope,
+        doc,
         options,
       );
       assert.deepEqual(result, expected);
@@ -122,6 +120,20 @@
     assert.deepEqual(result, expected);
   });
 
+  it('works if range does not contain Text nodes', async () => {
+    const html = `<b>Try quoting this image: <img/> — would that work?</b>`;
+    const doc = domParser.parseFromString(html, 'text/html');
+    const range = document.createRange();
+    range.selectNode(evaluateXPath(doc, '//img'));
+    const result = await describeTextQuote(range, doc);
+    assert.deepEqual(result, {
+      type: 'TextQuoteSelector',
+      exact: '',
+      prefix: 'image: ',
+      suffix: ' —',
+    });
+  });
+
   describe('inverts test cases of text quote matcher', () => {
     const applicableTestCases = Object.entries(testMatchCases).filter(
       ([_, { expected }]) => expected.length > 0,
@@ -130,11 +142,9 @@
     for (const [name, { html, selector, expected }] of applicableTestCases) {
       it(`case: '${name}'`, async () => {
         const doc = domParser.parseFromString(html, 'text/html');
-        const scope = doc.createRange();
-        scope.selectNodeContents(doc);
         for (const rangeInfo of expected) {
           const range = hydrateRange(rangeInfo, doc);
-          const result = await describeTextQuote(range, scope);
+          const result = await describeTextQuote(range, doc);
           assert.equal(result.exact, selector.exact);
           // Our result may have a different combination of prefix/suffix; only check for obvious inconsistency.
           if (selector.prefix && result.prefix)
diff --git a/packages/dom/test/text-quote/match-cases.ts b/packages/dom/test/text-quote/match-cases.ts
index cc88c62..7cbfa1a 100644
--- a/packages/dom/test/text-quote/match-cases.ts
+++ b/packages/dom/test/text-quote/match-cases.ts
@@ -121,7 +121,7 @@
       },
     ],
   },
-  'two matches': {
+  'two matches in one node': {
     html: '<b>lorem ipsum dolor amet yada yada</b>',
     selector: {
       type: 'TextQuoteSelector',
@@ -142,7 +142,34 @@
       },
     ],
   },
-  'overlapping matches': {
+  'matches in multiple nodes': {
+    html: `<p>Match again and <b>again </b>and <i>again</i>!`,
+    selector: {
+      type: 'TextQuoteSelector',
+      exact: 'again',
+    },
+    expected: [
+      {
+        startContainerXPath: '//p/text()[1]',
+        startOffset: 6,
+        endContainerXPath: '//p/text()[1]',
+        endOffset: 11,
+      },
+      {
+        startContainerXPath: '//b/text()',
+        startOffset: 0,
+        endContainerXPath: '//b/text()',
+        endOffset: 5,
+      },
+      {
+        startContainerXPath: '//i/text()',
+        startOffset: 0,
+        endContainerXPath: '//i/text()',
+        endOffset: 5,
+      },
+    ],
+  },
+  'overlapping matches in one node': {
     html: '<b>bananas</b>',
     selector: {
       type: 'TextQuoteSelector',
@@ -163,6 +190,27 @@
       },
     ],
   },
+  'overlapping matches stretching multiple nodes': {
+    html: '<b>bana<i>na</i>nas</b>',
+    selector: {
+      type: 'TextQuoteSelector',
+      exact: 'anana',
+    },
+    expected: [
+      {
+        startContainerXPath: '//b/text()[1]',
+        startOffset: 1,
+        endContainerXPath: '//i/text()',
+        endOffset: 2,
+      },
+      {
+        startContainerXPath: '//b/text()[1]',
+        startOffset: 3,
+        endContainerXPath: '//b/text()[2]',
+        endOffset: 2,
+      },
+    ],
+  },
   'no matches': {
     html: '<b>lorem ipsum dolor amet yada yada</b>',
     selector: {
diff --git a/packages/dom/test/text-quote/match.test.ts b/packages/dom/test/text-quote/match.test.ts
index bcd2578..aef6261 100644
--- a/packages/dom/test/text-quote/match.test.ts
+++ b/packages/dom/test/text-quote/match.test.ts
@@ -23,11 +23,11 @@
 import { assert } from 'chai';
 import type { TextQuoteSelector } from '@apache-annotator/selector';
 import { createTextQuoteSelectorMatcher } from '../../src/text-quote/match';
-import { evaluateXPath } from '../utils';
+import { evaluateXPath, assertRangeEquals } from '../utils';
 import type { RangeInfo } from '../utils';
 import { testCases } from './match-cases';
 
-const domParser = new window.DOMParser();
+const domParser = new DOMParser();
 
 describe('createTextQuoteSelectorMatcher', () => {
   for (const [name, { html, selector, expected }] of Object.entries(
@@ -35,21 +35,24 @@
   )) {
     it(`works for case: '${name}'`, async () => {
       const doc = domParser.parseFromString(html, 'text/html');
-
-      const scope = doc.createRange();
-      scope.selectNodeContents(doc);
-
-      await testMatcher(doc, scope, selector, expected);
+      await testMatcher(doc, doc, selector, expected);
     });
   }
 
+  describe.skip('Is resistant to splitting text nodes', () => {
+    for (const [name, { html, selector, expected }] of Object.entries(
+      testCases,
+    )) {
+      it(`for case: '${name}'`, async () => {
+        const doc = domParser.parseFromString(html, 'text/html');
+        await testMatcher(doc, doc, selector, expected, true);
+      });
+    }
+  });
+
   it('handles adjacent text nodes', async () => {
     const { html, selector } = testCases['simple'];
     const doc = domParser.parseFromString(html, 'text/html');
-
-    const scope = doc.createRange();
-    scope.selectNodeContents(doc);
-
     const textNode = evaluateXPath(doc, '//b/text()') as Text;
 
     for (let index = textNode.length - 1; index > 0; index--)
@@ -57,7 +60,7 @@
     // console.log([...textNode.parentNode.childNodes].map(node => node.textContent))
     // → 'l',  'o', 'r', 'e', 'm', …
 
-    await testMatcher(doc, scope, selector, [
+    await testMatcher(doc, doc, selector, [
       {
         startContainerXPath: '//b/text()[13]',
         startOffset: 0,
@@ -70,10 +73,6 @@
   it('handles empty text nodes', async () => {
     const { html, selector } = testCases['simple'];
     const doc = domParser.parseFromString(html, 'text/html');
-
-    const scope = doc.createRange();
-    scope.selectNodeContents(doc);
-
     const textNode = evaluateXPath(doc, '//b/text()') as Text;
     textNode.splitText(textNode.length);
     textNode.splitText(20);
@@ -86,7 +85,7 @@
     // console.log([...textNode.parentNode.childNodes].map(node => node.textContent))
     // → '', 'lorem ipsum ', '', 'dolor', '', ' am', '', 'et yada yada', ''
 
-    await testMatcher(doc, scope, selector, [
+    await testMatcher(doc, doc, selector, [
       {
         startContainerXPath: '//b/text()[4]', // "dolor"
         startOffset: 0,
@@ -189,49 +188,19 @@
 
 async function testMatcher(
   doc: Document,
-  scope: Range,
+  scope: Node | Range,
   selector: TextQuoteSelector,
   expected: RangeInfo[],
+  mutateDom = false,
 ) {
   const matcher = createTextQuoteSelectorMatcher(selector);
-  const matches = [];
-  for await (const value of matcher(scope)) matches.push(value);
-  assert.equal(matches.length, expected.length, 'Wrong number of matches.');
-  matches.forEach((match, i) => {
-    const expectedRange = expected[i];
-    const expectedStartContainer = evaluateXPath(
-      doc,
-      expectedRange.startContainerXPath,
-    );
-    const expectedEndContainer = evaluateXPath(
-      doc,
-      expectedRange.endContainerXPath,
-    );
-    assert(
-      match.startContainer === expectedStartContainer,
-      `unexpected start container: ${prettyNodeName(match.startContainer)}; ` +
-        `expected ${prettyNodeName(expectedStartContainer)}`,
-    );
-    assert.equal(match.startOffset, expectedRange.startOffset);
-    assert(
-      match.endContainer ===
-        evaluateXPath(doc, expectedRange.endContainerXPath),
-      `unexpected end container: ${prettyNodeName(match.endContainer)}; ` +
-        `expected ${prettyNodeName(expectedEndContainer)}`,
-    );
-    assert.equal(match.endOffset, expectedRange.endOffset);
-  });
-}
-
-function prettyNodeName(node: Node) {
-  switch (node.nodeType) {
-    case Node.TEXT_NODE: {
-      const text = (node as Text).nodeValue || '';
-      return `#text "${text.length > 50 ? text.substring(0, 50) + '…' : text}"`;
+  let count = 0;
+  for await (const match of matcher(scope)) {
+    assertRangeEquals(match, expected[count++]);
+    if (mutateDom) {
+      const wrapperNode = doc.createElement('mark');
+      match.surroundContents(wrapperNode);
     }
-    case Node.ELEMENT_NODE:
-      return `<${(node as Element).tagName.toLowerCase()}>`;
-    default:
-      return node.nodeName.toLowerCase();
   }
+  assert.equal(count, expected.length, 'Wrong number of matches.');
 }
diff --git a/packages/dom/test/utils.ts b/packages/dom/test/utils.ts
index 66a9700..ae7dd9c 100644
--- a/packages/dom/test/utils.ts
+++ b/packages/dom/test/utils.ts
@@ -1,4 +1,4 @@
-/** 
+/**
  * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
  * SPDX-License-Identifier: Apache-2.0
  * @license
@@ -21,6 +21,7 @@
  */
 
 import { assert } from 'chai';
+import { ownerDocument } from '../src/owner-document';
 
 // RangeInfo serialises a Range’s start and end containers as XPaths.
 export type RangeInfo = {
@@ -60,3 +61,65 @@
   );
   return range;
 }
+
+export function assertRangeEquals(match: Range, expected: RangeInfo): void {
+  const doc = ownerDocument(match);
+  if (expected === undefined) {
+    assert.fail(`Unexpected match: ${prettyRange(match)}`);
+  }
+  const expectedStartContainer = evaluateXPath(
+    doc,
+    expected.startContainerXPath,
+  );
+  const expectedEndContainer = evaluateXPath(doc, expected.endContainerXPath);
+  assert(
+    match.startContainer === expectedStartContainer,
+    `unexpected start container: ${prettyNodeName(match.startContainer)}; ` +
+      `expected ${prettyNodeName(expectedStartContainer)}`,
+  );
+  assert.equal(match.startOffset, expected.startOffset);
+  assert(
+    match.endContainer === evaluateXPath(doc, expected.endContainerXPath),
+    `unexpected end container: ${prettyNodeName(match.endContainer)}; ` +
+      `expected ${prettyNodeName(expectedEndContainer)}`,
+  );
+  assert.equal(match.endOffset, expected.endOffset);
+}
+
+function prettyNodeName(node: Node) {
+  switch (node.nodeType) {
+    case Node.TEXT_NODE: {
+      const text = (node as Text).nodeValue || '';
+      return `#text "${text.length > 50 ? text.substring(0, 50) + '…' : text}"`;
+    }
+    case Node.ELEMENT_NODE:
+      return `<${(node as Element).tagName.toLowerCase()}>`;
+    default:
+      return node.nodeName.toLowerCase();
+  }
+}
+
+function prettyRange(range: Range): string {
+  let s = 'Range(';
+  if (
+    range.startContainer.nodeType === Node.TEXT_NODE &&
+    range.startContainer.parentNode
+  )
+    s += prettyNodeName(range.startContainer.parentNode) + ' → ';
+  s += prettyNodeName(range.startContainer) + `: ${range.startOffset}`;
+  if (range.endContainer !== range.startContainer) {
+    s += ' … ';
+    if (
+      range.endContainer.nodeType === Node.TEXT_NODE &&
+      range.endContainer.parentNode &&
+      range.endContainer.parentNode !== range.startContainer.parentNode
+    )
+      s += prettyNodeName(range.endContainer.parentNode) + ' → ';
+    s += prettyNodeName(range.endContainer) + ' : ';
+  } else {
+    s += '…';
+  }
+  s += range.endOffset;
+  s += ')';
+  return s;
+}
diff --git a/packages/dom/tsconfig.json b/packages/dom/tsconfig.json
index 02e0fcf..e26d55e 100644
--- a/packages/dom/tsconfig.json
+++ b/packages/dom/tsconfig.json
@@ -1,6 +1,6 @@
 {
   "extends": "../../tsconfig.base.json",
-  "include": ["src"],
+  "include": ["src", "./@types"],
   "compilerOptions": {
     "outDir": "lib",
     "rootDir": "src"
diff --git a/packages/selector/.npmignore b/packages/selector/.npmignore
index 281df39..58fc595 100644
--- a/packages/selector/.npmignore
+++ b/packages/selector/.npmignore
@@ -1,2 +1,5 @@
-src
-test
+*.d.ts.map
+tsconfig.json
+tsconfig.tsbuildinfo
+/src
+/test
diff --git a/packages/selector/package.json b/packages/selector/package.json
index d7f230e..e940911 100644
--- a/packages/selector/package.json
+++ b/packages/selector/package.json
@@ -10,18 +10,14 @@
   },
   "license": "Apache-2.0",
   "author": "Apache Software Foundation",
-  "exports": {
-    "import": "./lib/index.mjs",
-    "require": "./lib/index.js"
-  },
+  "type": "module",
+  "exports": "./lib/index.js",
   "main": "./lib/index.js",
-  "module": "./lib/index.mjs",
-  "types": "./lib/index.d.ts",
   "dependencies": {
-    "@babel/runtime-corejs3": "^7.12.5"
+    "@babel/runtime-corejs3": "^7.13.10"
   },
   "engines": {
-    "node": "^10 || ^11 || ^12 || >=13.7"
+    "node": "^12.20 || ^14.15 || ^15.4 || ^16.0"
   },
   "publishConfig": {
     "access": "public"
diff --git a/packages/selector/src/index.ts b/packages/selector/src/index.ts
index ad87f40..2976347 100644
--- a/packages/selector/src/index.ts
+++ b/packages/selector/src/index.ts
@@ -31,10 +31,22 @@
 } from './types';
 export * from './text';
 
+/**
+ * Wrap a matcher creation function so that it supports refinement of selection.
+ *
+ * See {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection
+ * | §4.2.9 Refinement of Selection} in the Web Annotation Data Model.
+ *
+ * @param matcherCreator - The function to wrap; it will be executed both for
+ * {@link Selector}s passed to the returned wrapper function, and for any
+ * refining Selector those might contain (and any refinement of that, etc.).
+ *
+ * @public
+ */
 export function makeRefinable<
   // Any subtype of Selector can be made refinable; but note we limit the value
   // of refinedBy because it must also be accepted by matcherCreator.
-  TSelector extends Selector & { refinedBy: TSelector },
+  TSelector extends Selector & { refinedBy?: TSelector },
   TScope,
   // To enable refinement, the implementation’s Match object must be usable as a
   // Scope object itself.
diff --git a/packages/selector/src/text/chunker.ts b/packages/selector/src/text/chunker.ts
index 21a6f07..0238f13 100644
--- a/packages/selector/src/text/chunker.ts
+++ b/packages/selector/src/text/chunker.ts
@@ -20,18 +20,54 @@
  * under the License.
  */
 
-// A Chunk represents a fragment (typically a string) of some document.
-// Subclasses can add further attributes to map the chunk to its position in the
-// data structure it came from (e.g. a DOM node).
+/**
+ * Represents a piece of text in any kind of ‘file’.
+ *
+ * Its purpose is to enable generic algorithms to deal with text content of any
+ * type of ‘file’ that consists of many pieces of text (e.g. a DOM, PDF, …).
+ * Each Chunk represents one piece of text ({@link Chunk.data}). An object
+ * implementing this interface would typically have other attributes as well to
+ * map the chunk back to its position in the file (e.g. a Text node in the DOM).
+ *
+ * @typeParam TData - Piece of text, typically `string`
+ *
+ * @public
+ */
 export interface Chunk<TData> {
+  /**
+   * The piece of text this chunk represents.
+   */
   readonly data: TData;
   equals?(otherChunk: this): boolean;
 }
 
+/**
+ * Test two {@link Chunk}s for equality.
+ *
+ * Equality here means that both represent the same piece of text (i.e. at the
+ * same position) in the file. It compares using the custom {@link Chunk.equals}
+ * method if either chunk defines one, and falls back to checking the objects’
+ * identity (i.e. `chunk1 === chunk2`).
+ *
+ * @public
+ */
 export function chunkEquals(chunk1: Chunk<any>, chunk2: Chunk<any>): boolean {
-  return chunk1.equals ? chunk1.equals(chunk2) : chunk1 === chunk2;
+  if (chunk1.equals) return chunk1.equals(chunk2);
+  if (chunk2.equals) return chunk2.equals(chunk1);
+  return chunk1 === chunk2;
 }
 
+/**
+ * Points at a range of characters between two points inside {@link Chunk}s.
+ *
+ * Analogous to the DOM’s ({@link https://developer.mozilla.org/en-US/docs/Web/API/AbstractRange
+ * | Abstract}){@link https://developer.mozilla.org/en-US/docs/Web/API/Range |
+ * Range}. Each index expresses an offset inside the value of the corresponding
+ * {@link Chunk.data}, and can equal the length of that data in order to point
+ * to the position right after the chunk’s last character.
+ *
+ * @public
+ */
 export interface ChunkRange<TChunk extends Chunk<any>> {
   startChunk: TChunk;
   startIndex: number;
@@ -39,6 +75,24 @@
   endIndex: number;
 }
 
+/**
+ * Test two {@link ChunkRange}s for equality.
+ *
+ * Equality here means equality of each of their four properties (i.e.
+ * {@link startChunk}, {@link startIndex},
+ * {@link endChunk}, and {@link endIndex}).
+ * For the `startChunk`s and `endChunk`s, this function uses the custom
+ * {@link Chunk.equals} method if defined.
+ *
+ * Note that if the start/end of one range points at the end of a chunk, and the
+ * other to the start of a subsequent chunk, they are not considered equal, even
+ * though semantically they may be representing the same range of characters. To
+ * test for such semantic equivalence, ensure that both inputs are normalised:
+ * typically this means the range is shrunk to its narrowest equivalent, and (if
+ * it is empty) positioned at its first equivalent.
+ *
+ * @public
+ */
 export function chunkRangeEquals(
   range1: ChunkRange<any>,
   range2: ChunkRange<any>,
@@ -51,21 +105,55 @@
   );
 }
 
-// A Chunker lets one walk through the chunks of a document.
-// It is inspired by, and similar to, the DOM’s NodeIterator. (but unlike
-// NodeIterator, it has no concept of being ‘before’ or ‘after’ a chunk)
+/**
+ * Presents the pieces of text contained in some underlying ‘file’ as a sequence
+ * of {@link Chunk}s.
+ *
+ * Rather than presenting a list of all pieces, the `Chunker` provides methods
+ * to walk through the file piece by piece. This permits implementations to read
+ * and convert the file to `Chunk`s lazily.
+ *
+ * For those familiar with the DOM APIs, it is similar to a NodeIterator (but
+ * unlike NodeIterator, it has no concept of being ‘before’ or ‘after’ a chunk).
+ *
+ * @typeParam TChunk - (sub)type of `Chunk` being used.
+ *
+ * @public
+ */
 export interface Chunker<TChunk extends Chunk<any>> {
-  // The chunk currently being pointed at.
+  /**
+   * The chunk currently being pointed at.
+   *
+   * Initially, this should normally be the first chunk in the file.
+   */
   readonly currentChunk: TChunk;
 
-  // Move currentChunk to the chunk following it, and return that chunk.
-  // If there are no chunks following it, keep currentChunk unchanged and return null.
+  /**
+   * Point {@link currentChunk} at the chunk following it, and return that chunk.
+   * If there are no chunks following it, keep `currentChunk` unchanged and
+   * return null.
+   */
   nextChunk(): TChunk | null;
 
-  // Move currentChunk to the chunk preceding it, and return that chunk.
-  // If there are no preceding chunks, keep currentChunk unchanged and return null.
+  /**
+   * Point {@link currentChunk} at the chunk preceding it, and return that chunk.
+   * If there are no chunks preceding it, keep `currentChunk` unchanged and
+   * return null.
+   */
   previousChunk(): TChunk | null;
 
-  // Test if a given chunk is before the current chunk.
+  /**
+   * Test if a given `chunk` is before the {@link currentChunk|current
+   * chunk}.
+   *
+   * Returns true if `chunk` is before `this.currentChunk`, false otherwise
+   * (i.e. if `chunk` follows it or is the current chunk).
+   *
+   * The given `chunk` need not necessarily be obtained from the same `Chunker`,
+   * but the chunkers would need to represent the same file. Otherwise behaviour
+   * is unspecified (an implementation might throw or just return `false`).
+   *
+   * @param chunk - A chunk, typically obtained from the same `Chunker`.
+   */
   precedesCurrentChunk(chunk: TChunk): boolean;
 }
diff --git a/packages/selector/src/text/code-point-seeker.ts b/packages/selector/src/text/code-point-seeker.ts
index 150ccb9..96ce7ff 100644
--- a/packages/selector/src/text/code-point-seeker.ts
+++ b/packages/selector/src/text/code-point-seeker.ts
@@ -23,10 +23,34 @@
 import type { Chunk } from './chunker';
 import type { Seeker } from './seeker';
 
+/**
+ * Seeks through text counting Unicode *code points* instead of *code units*.
+ *
+ * Javascript characters correspond to 16 bits *code units*, hence two such
+ * ‘characters’ might together constitute a single Unicode character (i.e. a
+ * *code point*). The {@link CodePointSeeker} allows to ignore this
+ * variable-length encoding, by counting code points instead.
+ *
+ * It is made to wrap a {@link Seeker} that counts code units (presumably a
+ * {@link TextSeeker}), which must be passed to its {@link constructor}.
+ *
+ * When reading from the `CodePointSeeker`, the returned values is not a string
+ * but an array of strings, each containing one code point (thus each having a
+ * `length` that is either 1 or 2).
+ *
+ * @public
+ */
 export class CodePointSeeker<TChunk extends Chunk<string>>
   implements Seeker<TChunk, string[]> {
   position = 0;
 
+  /**
+   *
+   * @param raw  The {@link Seeker} to wrap, which counts in code *units* (e.g.
+   * a {@link TextSeeker}). It should have {@link Seeker.position | position}
+   * `0` and its methods must no longer be used directly if the
+   * `CodePointSeeker`’s position is to remain correct.
+   */
   constructor(public readonly raw: Seeker<TChunk>) {}
 
   seekBy(length: number): void {
diff --git a/packages/selector/src/text/describe-text-position.ts b/packages/selector/src/text/describe-text-position.ts
index f8a3b0b..cae5d83 100644
--- a/packages/selector/src/text/describe-text-position.ts
+++ b/packages/selector/src/text/describe-text-position.ts
@@ -25,6 +25,25 @@
 import { CodePointSeeker } from './code-point-seeker';
 import { TextSeeker } from './seeker';
 
+/**
+ * Returns a {@link TextPositionSelector} that points at the target text within
+ * the given scope.
+ *
+ * This is an abstract implementation of the function’s logic, which expects a
+ * generic {@link Chunker} to represent the text, and a {@link ChunkRange} to
+ * represent the target.
+ *
+ * See {@link dom.describeTextPosition} for a wrapper around
+ * this implementation which applies it to the text of an HTML DOM.
+ *
+ * @param target - The range of characters that the selector should describe
+ * @param scope - The text, presented as a {@link Chunker}, which contains the
+ * target range, and relative to which its position will be measured
+ * @returns The {@link TextPositionSelector} that describes `target` relative
+ * to `scope`
+ *
+ * @public
+ */
 export async function describeTextPosition<TChunk extends Chunk<string>>(
   target: ChunkRange<TChunk>,
   scope: Chunker<TChunk>,
diff --git a/packages/selector/src/text/describe-text-quote.ts b/packages/selector/src/text/describe-text-quote.ts
index bd5f512..bb9e744 100644
--- a/packages/selector/src/text/describe-text-quote.ts
+++ b/packages/selector/src/text/describe-text-quote.ts
@@ -27,6 +27,9 @@
 import { TextSeeker } from './seeker';
 import { textQuoteSelectorMatcher } from '.';
 
+/**
+ * @public
+ */
 export interface DescribeTextQuoteOptions {
   /**
    * Keep prefix and suffix to the minimum that is necessary to disambiguate
@@ -36,7 +39,7 @@
 
   /**
    * Add prefix and suffix to quotes below this length, such that the total of
-   * prefix + exact + suffix is at least this length.
+   * `prefix + exact + suffix` is at least this length.
    */
   minimumQuoteLength?: number;
 
@@ -51,29 +54,39 @@
  * Returns a {@link TextQuoteSelector} that points at the target quote in the
  * given text.
  *
- * @remarks
- * The selector will contain the *exact* target quote, and in case this quote
- * appears multiple times in the text, sufficient context around the quote will
- * be included in the selector’s *prefix* and *suffix* attributes to
- * disambiguate. By default, more prefix and suffix are included than strictly
- * required; both in order to be robust against slight modifications, and in an
- * attempt to not end halfway a word (mainly for the sake of human readability).
+ * The selector will contain the exact target quote. In case this quote appears
+ * multiple times in the text, sufficient context around the quote will be
+ * included in the selector’s `prefix` and `suffix` attributes to disambiguate.
+ * By default, more prefix and suffix are included than strictly required; both
+ * in order to be robust against slight modifications, and in an attempt to not
+ * end halfway a word (mainly for human readability).
+ *
+ * This is an abstract implementation of the function’s logic, which expects a
+ * generic {@link Chunker} to represent the text, and a {@link ChunkRange} to
+ * represent the target.
+ *
+ * See {@link dom.describeTextQuote} for a wrapper around this
+ * implementation which applies it to the text of an HTML DOM.
  *
  * @param target - The range of characters that the selector should describe
  * @param scope - The text containing the target range; or, more accurately, a
- * function creating {@link Chunker}s that allow walking through the text.
- * @param options
- * @returns the {@link TextQuoteSelector} that describes *target*.
+ * function that produces {@link Chunker}s corresponding to this text.
+ * @param options - Options to fine-tune the function’s behaviour.
+ * @returns The {@link TextQuoteSelector} that describes `target`.
+ *
+ * @public
  */
 export async function describeTextQuote<TChunk extends Chunk<string>>(
   target: ChunkRange<TChunk>,
   scope: () => Chunker<TChunk>,
-  {
+  options: DescribeTextQuoteOptions = {},
+): Promise<TextQuoteSelector> {
+  const {
     minimalContext = false,
     minimumQuoteLength = 0,
     maxWordLength = 50,
-  }: DescribeTextQuoteOptions = {},
-): Promise<TextQuoteSelector> {
+  } = options;
+
   // Create a seeker to read the target quote and the context around it.
   // TODO Possible optimisation: as it need not be an AbsoluteSeeker, a
   // different implementation could provide direct ‘jump’ access in seekToChunk
diff --git a/packages/selector/src/text/index.ts b/packages/selector/src/text/index.ts
index 0854a35..0287f48 100644
--- a/packages/selector/src/text/index.ts
+++ b/packages/selector/src/text/index.ts
@@ -1,6 +1,23 @@
-/*
+/**
  * SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
  * SPDX-License-Identifier: Apache-2.0
+ * @license
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 
 export * from './describe-text-quote';
diff --git a/packages/selector/src/text/match-text-position.ts b/packages/selector/src/text/match-text-position.ts
index 4cadb42..799b0a7 100644
--- a/packages/selector/src/text/match-text-position.ts
+++ b/packages/selector/src/text/match-text-position.ts
@@ -25,6 +25,34 @@
 import { CodePointSeeker } from './code-point-seeker';
 import { TextSeeker } from './seeker';
 
+/**
+ * Find the range of text corresponding to the given {@link TextPositionSelector}.
+ *
+ * This is an abstract implementation of the function’s logic, which expects a
+ * generic {@link Chunker} to represent the text, and returns an (async)
+ * generator producing a single {@link ChunkRange} to represent the match.
+ * (unlike e.g. TextQuoteSelector, it cannot result in multiple matches).
+ *
+ * See {@link dom.createTextPositionSelectorMatcher} for a
+ * wrapper around this implementation which applies it to the text of an HTML
+ * DOM.
+ *
+ * The function is curried, taking first the selector and then the text.
+ *
+ * @example
+ * ```
+ * const selector = { type: 'TextPositionSelector', start: 702, end: 736 };
+ * const matches = textPositionSelectorMatcher(selector)(textChunks);
+ * const match = (await matches.next()).value;
+ * console.log(match);
+ * // ⇒ { startChunk: { … }, startIndex: 64, endChunk: { … }, endIndex: 98 }
+ * ```
+ *
+ * @param selector - the {@link TextPositionSelector} to be anchored
+ * @returns a {@link Matcher} function that applies `selector` to a given text
+ *
+ * @public
+ */
 export function textPositionSelectorMatcher(
   selector: TextPositionSelector,
 ): <TChunk extends Chunk<any>>(
diff --git a/packages/selector/src/text/match-text-quote.ts b/packages/selector/src/text/match-text-quote.ts
index c7a75ec..e51cf03 100644
--- a/packages/selector/src/text/match-text-quote.ts
+++ b/packages/selector/src/text/match-text-quote.ts
@@ -23,6 +23,47 @@
 import type { TextQuoteSelector } from '../types';
 import type { Chunk, Chunker, ChunkRange } from './chunker';
 
+/**
+ * Find occurrences in a text matching the given {@link TextQuoteSelector}.
+ *
+ * This performs an exact search the selector’s quote (including prefix and
+ * suffix) within the given text.
+ *
+ * Note the match is based on strict character-by-character equivalence, i.e.
+ * it is sensitive to whitespace, capitalisation, etc.
+ *
+ * This is an abstract implementation of the function’s logic, which expects a
+ * generic {@link Chunker} to represent the text, and returns an (async)
+ * generator of {@link ChunkRange}s to represent the matches.
+ *
+ * See {@link dom.createTextQuoteSelectorMatcher} for a
+ * wrapper around this implementation which applies it to the text of an HTML
+ * DOM.
+ *
+ * The function is curried, taking first the selector and then the text.
+ *
+ * As there may be multiple matches for a given selector (when its prefix and
+ * suffix attributes are not sufficient to disambiguate it), the matcher will
+ * return an (async) generator that produces each match in the order they are
+ * found in the text.
+ *
+ * *XXX Modifying the Chunks while the search is still running can mess up and
+ * result in an error or an infinite loop. See [issue #112](https://github.com/apache/incubator-annotator/issues/112).*
+ *
+ * @example
+ * ```
+ * const selector = { type: 'TextQuoteSelector', exact: 'banana' };
+ * const matches = textQuoteSelectorMatcher(selector)(textChunks);
+ * for await (match of matches) console.log(match);
+ * // ⇒ { startChunk: { … }, startIndex: 187, endChunk: { … }, endIndex: 193 }
+ * // ⇒ { startChunk: { … }, startIndex: 631, endChunk: { … }, endIndex: 637 }
+ * ```
+ *
+ * @param selector - The {@link TextQuoteSelector} to be anchored
+ * @returns a {@link Matcher} function that applies `selector` to a given text
+ *
+ * @public
+ */
 export function textQuoteSelectorMatcher(
   selector: TextQuoteSelector,
 ): <TChunk extends Chunk<any>>(
@@ -36,7 +77,9 @@
     const suffix = selector.suffix || '';
     const searchPattern = prefix + exact + suffix;
 
-    // The code below runs a loop with three steps:
+    // The code below essentially just performs string.indexOf(searchPattern),
+    // but on a string that is chopped up in multiple chunks. It runs a loop
+    // containing three steps:
     // 1. Continue checking any partial matches from the previous chunk(s).
     // 2. Try find the whole pattern in the chunk (possibly multiple times).
     // 3. Check if this chunk ends with a partial match (or even multiple partial matches).
diff --git a/packages/selector/src/text/seeker.ts b/packages/selector/src/text/seeker.ts
index 539460a..56ddd97 100644
--- a/packages/selector/src/text/seeker.ts
+++ b/packages/selector/src/text/seeker.ts
@@ -29,7 +29,6 @@
  * Abstraction to seek (jump) or read to a position inside a ‘file’ consisting of a
  * sequence of data chunks.
  *
- * @remarks
  * This interface is a combination of three interfaces in one: for seeking to a
  * relative position, an absolute position, or a specific chunk. These three are
  * defined separately for clarity and flexibility, but normally used together.
@@ -41,6 +40,8 @@
  * @typeParam TData - Type of data this seeker’s read methods will return (not
  * necessarily the same as the `TData` parameter of {@link Chunk}, see e.g.
  * {@link CodePointSeeker})
+ *
+ * @public
  */
 export interface Seeker<
   TChunk extends Chunk<any>,
@@ -52,6 +53,8 @@
 
 /**
  * Seeks/reads by a given number of characters.
+ *
+ * @public
  */
 export interface RelativeSeeker<TData extends Iterable<any> = string> {
   /**
@@ -67,7 +70,7 @@
   /**
    * Read forward or backward by a number of characters.
    *
-   * @remarks Equal to {@link seekBy}, but returning the characters passed.
+   * Equal to {@link seekBy}, but returning the characters passed.
    *
    * @param length - The number of characters to read. A negative number moves
    * backwards in the file.
@@ -85,6 +88,8 @@
 
 /**
  * Seek/read to absolute positions in the file.
+ *
+ * @public
  */
 export interface AbsoluteSeeker<TData extends Iterable<any> = string> {
   /**
@@ -106,7 +111,7 @@
    * Read forward or backward from the current to the given position in the
    * file, returning the characters that have been passed.
    *
-   * @remarks Equal to {@link seekTo}, but returning the characters passed.
+   * Equal to {@link seekTo}, but returning the characters passed.
    *
    * @param target - The position to end up at.
    * @param roundUp - If true, then, after reading to the target position, read
@@ -126,6 +131,8 @@
  * Note that all offset numbers in this interface are representing units of the
  * {@link Chunk.data | data type of `TChunk`}; which might differ from that of
  * `TData`.
+ *
+ * @public
  */
 export interface ChunkSeeker<
   TChunk extends Chunk<any>,
@@ -134,7 +141,6 @@
   /**
    * The chunk containing the current position.
    *
-   * @remarks
    * When the position falls at the edge between two chunks, `currentChunk` is
    * always the later one (thus {@link offsetInChunk} would be zero). Note that
    * an empty chunk (for which position zero is at both its edges) can
@@ -162,7 +168,7 @@
   /**
    * Read to the start of a given chunk, or to an offset relative to that.
    *
-   * @remarks Equal to {@link seekToChunk}, but returning the characters passed.
+   * Equal to {@link seekToChunk}, but returning the characters passed.
    *
    * @param chunk - The chunk of the file to move to.
    * @param offset - The offset to move to, relative to the start of `chunk`.
@@ -174,10 +180,24 @@
   readToChunk(chunk: TChunk, offset?: number): TData;
 }
 
-// The TextSeeker takes a Chunker as input, and lets it be treated as a single
-// string. Seeking to a given numeric position will cause it to pull chunks from
-// the underlying Chunker, counting their lengths until the requested position
-// is reached.
+/**
+ * A TextSeeker is constructed around a {@link Chunker}, to let it be treated as
+ * a continuous sequence of characters.
+ *
+ * Seeking to a given numeric position will cause a `TextSeeker` to pull chunks
+ * from the underlying `Chunker`, counting their lengths until the requested
+ * position is reached. `Chunks` are not stored but simply read again when
+ * seeking backwards.
+ *
+ * The `Chunker` is presumed to read an unchanging file. If a chunk’s length
+ * would change while seeking, a TextSeeker’s absolute positioning would be
+ * incorrect.
+ *
+ * See {@link CodePointSeeker} for a {@link Seeker} that counts Unicode *code
+ * points* instead of Javascript’s ‘normal’ characters.
+ *
+ * @public
+ */
 export class TextSeeker<TChunk extends Chunk<string>>
   implements Seeker<TChunk> {
   // The chunk containing our current text position.
@@ -267,7 +287,7 @@
 
     // Now we know where the chunk is, walk to the requested offset.
     // Note we might have started inside the chunk, and the offset could even
-    // point to a position before or after the chunk.
+    // point at a position before or after the chunk.
     const targetPosition = this.currentChunkPosition + offset;
     if (!read) {
       this.seekTo(targetPosition);
@@ -314,7 +334,7 @@
           this.currentChunkPosition + this.currentChunk.data.length;
         if (endOfChunk <= target) {
           // The target is beyond the current chunk.
-          // (we use < not ≤: if the target is *at* the end of the chunk, possibly
+          // (we use ≤ not <: if the target is *at* the end of the chunk, possibly
           // because the current chunk is empty, we prefer to take the next chunk)
 
           const [data, nextChunk] = this._readToNextChunk();
diff --git a/packages/selector/src/types.ts b/packages/selector/src/types.ts
index c3eca11..5b3a755 100644
--- a/packages/selector/src/types.ts
+++ b/packages/selector/src/types.ts
@@ -20,15 +20,47 @@
  * under the License.
  */
 
+/**
+ * A {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors
+ * | Selector} object of the Web Annotation Data Model.
+ *
+ * Corresponds to RDF class {@link http://www.w3.org/ns/oa#Selector}
+ *
+ * @public
+ */
 export interface Selector {
+  /**
+   * A Selector can be refined by another Selector.
+   *
+   * See {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection
+   * | §4.2.9 Refinement of Selection} in the Web Annotation Data Model.
+   *
+   * Corresponds to RDF property {@link http://www.w3.org/ns/oa#refinedBy}
+   */
   refinedBy?: Selector;
 }
 
+/**
+ * The {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#css-selector
+ * | CssSelector} of the Web Annotation Data Model.
+ *
+ * Corresponds to RDF class {@link http://www.w3.org/ns/oa#CssSelector}
+ *
+ * @public
+ */
 export interface CssSelector extends Selector {
   type: 'CssSelector';
   value: string;
 }
 
+/**
+ * The {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-quote-selector
+ * | TextQuoteSelector} of the Web Annotation Data Model.
+ *
+ * Corresponds to RDF class {@link http://www.w3.org/ns/oa#TextQuoteSelector}
+ *
+ * @public
+ */
 export interface TextQuoteSelector extends Selector {
   type: 'TextQuoteSelector';
   exact: string;
@@ -36,18 +68,40 @@
   suffix?: string;
 }
 
+/**
+ * The {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-position-selector
+ * | TextPositionSelector} of the Web Annotation Data Model.
+ *
+ * Corresponds to RDF class {@link http://www.w3.org/ns/oa#TextPositionSelector}
+ *
+ * @public
+ */
 export interface TextPositionSelector extends Selector {
   type: 'TextPositionSelector';
   start: number; // more precisely: non-negative integer
   end: number; // more precisely: non-negative integer
 }
 
+/**
+ * The {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#range-selector
+ * | RangeSelector} of the Web Annotation Data Model.
+ *
+ * Corresponds to RDF class {@link http://www.w3.org/ns/oa#RangeSelector}
+ *
+ * @public
+ */
 export interface RangeSelector extends Selector {
   type: 'RangeSelector';
   startSelector: Selector;
   endSelector: Selector;
 }
 
+/**
+ * A function that finds the match(es) in the given (sub)document (the ‘scope’)
+ * corresponding to some (prespecified) selector(s).
+ *
+ * @public
+ */
 export interface Matcher<TScope, TMatch> {
   (scope: TScope): AsyncGenerator<TMatch, void, void>;
 }
diff --git a/test/data-model.test.ts b/test/data-model.test.ts
index 43a1bb2..92a566e 100644
--- a/test/data-model.test.ts
+++ b/test/data-model.test.ts
@@ -96,10 +96,10 @@
     }
   });
 
-  const assertions = MUSTS.assertions as [string];
+  const assertions = MUSTS['assertions'] as [string];
   assertions.forEach((schemaPath: string) => {
     const schema = requireJSON(`web-annotation-tests/${schemaPath}`);
-    it(schema.title as string, () => {
+    it(schema['title'] as string, () => {
       const valid = ajv.validate(schema, data);
       assert.isOk(valid, ajv.errorsText());
     });
diff --git a/tsconfig.base.json b/tsconfig.base.json
index e9f79ca..3070cfb 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -1,11 +1,12 @@
 {
   "compilerOptions": {
-    "allowSyntheticDefaultImports": true,
     "composite": true,
     "declaration": true,
     "declarationMap": true,
     "downlevelIteration": true,
     "emitDeclarationOnly": true,
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
     "isolatedModules": true,
     "lib": [
       "dom",
@@ -13,6 +14,8 @@
       "es2020"
     ],
     "moduleResolution": "node",
+    "noPropertyAccessFromIndexSignature": true,
+    "skipLibCheck": true,
     "strict": true,
     "target": "es2017"
   }
diff --git a/tsconfig.json b/tsconfig.json
index f250929..b9a2c0d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,12 +1,9 @@
 {
-  "extends": "./tsconfig.base.json",
-  "include": [
-    "test/**/*",
-    "packages/*/test/**/*",
-  ],
+  "files": [],
   "references": [
     { "path": "packages/apache-annotator" },
     { "path": "packages/dom" },
-    { "path": "packages/selector" }
+    { "path": "packages/selector" },
+    { "path": "tsconfig.test.json"}
   ]
 }
diff --git a/tsconfig.test.json b/tsconfig.test.json
new file mode 100644
index 0000000..f439fba
--- /dev/null
+++ b/tsconfig.test.json
@@ -0,0 +1,8 @@
+{
+  "extends": "./tsconfig.base.json",
+  "include": ["test", "packages/*/test"],
+  "references": [
+    { "path": "packages/dom" },
+    { "path": "packages/selector" }
+  ]
+}
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 0000000..76bc567
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,5 @@
+{
+  "disableSources": true,
+  "entryPoints": ["packages/apache-annotator/src/"],
+  "readme": "none"
+}
diff --git a/web/demo/index.html b/web/demo/index.html
deleted file mode 100644
index 6c86b4b..0000000
--- a/web/demo/index.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<!doctype html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <title>Apache Annotator (incubating) demo</title>
-  <link rel="stylesheet" href="../style.css"/>
-  <style>
-    a[data-run-example]:before {
-      content: '📌 ';
-    }
-
-    #source, #target {
-      padding: 1em;
-      border: 1px solid lightgrey;
-      background: white;
-    }
-
-    #info {
-      height: 15em;
-      overflow: scroll;
-      background: white;
-      color: #666666;
-      resize: vertical;
-    }
-
-    .columns {
-      background: aliceblue;
-    }
-  </style>
-  <script defer src="index.js"></script>
-</head>
-<body>
-  <header>
-    <h1>Apache Annotator <small>(incubating)</small></h1>
-  </header>
-  <nav>
-    <a href="../">← Back</a>
-  </nav>
-  <main>
-    <h1>Selector Demonstration</h1>
-
-    <p>This page demonstrates Web Annotation
-      <a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors" target="_blank">Selectors</a>,
-      standardised JSON objects that describe a selection inside a document with sufficient information to find it back.</p>
-      <p>This demo’s source code can be found <a href="https://gitbox.apache.org/repos/asf?p=incubator-annotator.git;a=tree;hb=HEAD;f=web/demo">in the project repo</a> (also mirrored <a href="https://github.com/apache/incubator-annotator/tree/master/web/demo">on GitHub</a>)</p>
-
-    <div class="columns full-width">
-      <div class="column">
-        <h2>Select text here</h2>
-        <p id="source" contenteditable>Hello, <em>annotated world!</em> 🙂 <b>To annotate, or <em>not</em> to annotate</b>, that is the question.</p>
-        <p>Try selecting some text in this paragraph above.
-          Upon a change of selection, a
-          <a rel="external" href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-quote-selector" target="_blank">TextQuoteSelector</a>
-          will be created, that describes what was selected.</p>
-          <form id="form">
-            The selector can work either
-            <br/>
-            <input type="radio" name="describeMode" value="TextQuote" id="describeModeTextQuote" checked>
-            <label for="describeModeTextQuote">by quoting the selected text</label>; or
-            </br>
-            <input type="radio" name="describeMode" value="TextPosition" id="describeModeTextPosition">
-            <label for="describeModeTextPosition">by counting the selected characters’ position in the text</label>.
-          </form>
-      </div>
-      <div class="column">
-        <h2>Text is found here</h2>
-        <p id="target" contenteditable><em>Hello, annotated</em> world! 🙂 To annotate, or not to annotate, <b><em>that</em> is the question.</b></p>
-        <p>The selector is ‘anchored’ here: the segment it describes is found and highlighted.</p>
-      </div>
-      <div class="column" style="min-width: 20em;">
-        <h2>The selector as JSON:</h2>
-        <pre id="info"></pre>
-      </div>
-    </div>
-    <p>Here are other selectors you can anchor in the text above:</p>
-    <ul>
-      <li><a href="#" data-run-example="0">An ambiguous selector (i.e. with multiple matches)</a>
-      <li>
-        <a href="#" data-run-example="1">RangeSelector</a>
-        (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#range-selector" target="_blank">spec</a>)
-      <li>
-        <a href="#" data-run-example="2">Refining a selector using another selector</a>
-        (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection" target="blank">spec</a>)
-      <li><a href="#" data-run-example="3">Any deeper nesting of the above</a>
-    </ul>
-  </main>
-</body>
-</html>
diff --git a/web/index.html b/web/index.html
index 85dae62..8ac55cf 100644
--- a/web/index.html
+++ b/web/index.html
@@ -1,4 +1,6 @@
 <!--
+SPDX-FileCopyrightText: 2016-2020 The Apache Software Foundation
+SPDX-License-Identifier: Apache-2.0
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
@@ -22,16 +24,83 @@
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
-  <title>Apache Annotator (incubating)</title>
-  <link rel="stylesheet" href="style.css">
+  <title>Apache Annotator (incubating) demo</title>
+  <link rel="stylesheet" href="style.css"/>
+  <style>
+    a[data-run-example]:before {
+      content: '📌 ';
+    }
+
+    #source, #target {
+      padding: 1em;
+      border: 1px solid lightgrey;
+      background: white;
+    }
+
+    #info {
+      height: 15em;
+      overflow: scroll;
+      background: white;
+      color: #666666;
+      resize: vertical;
+    }
+
+    .columns {
+      background: aliceblue;
+    }
+  </style>
+  <script defer src="main.js"></script>
 </head>
 <body>
+  <header>
+    <h1><a href="https://annotator.apache.org">Apache Annotator</a> <small>(incubating)</small></h1>
+  </header>
   <main>
-    <h1>Welcome to Apache Annotator (incubating)</h1>
-    <h2>Getting Started</h2>
+    <h1>Selector Demonstration</h1>
+
+    <p>This page demonstrates Web Annotation
+      <a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors" target="_blank">Selectors</a>,
+      standardised JSON objects that describe a selection inside a document with sufficient information to find it back.</p>
+      <p>This demo’s source code can be found <a href="https://gitbox.apache.org/repos/asf?p=incubator-annotator.git;a=tree;hb=HEAD;f=web">in the project repo</a> (also mirrored <a href="https://github.com/apache/incubator-annotator/tree/master/web">on GitHub</a>)</p>
+
+    <div class="columns full-width">
+      <div class="column">
+        <h2>Select text here</h2>
+        <p id="source" contenteditable>Hello, <em>annotated world!</em> 🙂 <b>To annotate, or <em>not</em> to annotate</b>, that is the question.</p>
+        <p>Try selecting some text in this paragraph above.
+          Upon a change of selection, a
+          <a rel="external" href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-quote-selector" target="_blank">TextQuoteSelector</a>
+          will be created, that describes what was selected.</p>
+          <form id="form">
+            The selector can work either
+            <br/>
+            <input type="radio" name="describeMode" value="TextQuote" id="describeModeTextQuote" checked>
+            <label for="describeModeTextQuote">by quoting the selected text</label>; or
+            </br>
+            <input type="radio" name="describeMode" value="TextPosition" id="describeModeTextPosition">
+            <label for="describeModeTextPosition">by counting the selected characters’ position in the text</label>.
+          </form>
+      </div>
+      <div class="column">
+        <h2>Text is found here</h2>
+        <p id="target" contenteditable><em>Hello, annotated</em> world! 🙂 To annotate, or not to annotate, <b><em>that</em> is the question.</b></p>
+        <p>The selector is ‘anchored’ here: the segment it describes is found and highlighted.</p>
+      </div>
+      <div class="column" style="min-width: 20em;">
+        <h2>The selector as JSON:</h2>
+        <pre id="info"></pre>
+      </div>
+    </div>
+    <p>Here are other selectors you can anchor in the text above:</p>
     <ul>
-      <li>Visit the <a href="demo/index.html">demonstration page</a>.
-      <li>Run the <a href="test/index.html">test suite</a>.
+      <li><a href="#" data-run-example="0">An ambiguous selector (i.e. with multiple matches)</a>
+      <li>
+        <a href="#" data-run-example="1">RangeSelector</a>
+        (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#range-selector" target="_blank">spec</a>)
+      <li>
+        <a href="#" data-run-example="2">Refining a selector using another selector</a>
+        (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection" target="blank">spec</a>)
+      <li><a href="#" data-run-example="3">Any deeper nesting of the above</a>
     </ul>
   </main>
 </body>
diff --git a/web/demo/index.js b/web/index.js
similarity index 75%
rename from web/demo/index.js
rename to web/index.js
index 5e0318b..009a43d 100644
--- a/web/demo/index.js
+++ b/web/index.js
@@ -28,7 +28,7 @@
   describeTextQuote,
   createTextPositionSelectorMatcher,
   describeTextPosition,
-  highlightRange,
+  highlightText,
 } from '@apache-annotator/dom';
 import { makeRefinable } from '@apache-annotator/selector';
 
@@ -85,11 +85,13 @@
   },
 ];
 
-const cleanupFunctions = [];
+let moduleState = {
+  cleanupFunctions: [],
+};
 
 function cleanup() {
   let removeHighlight;
-  while ((removeHighlight = cleanupFunctions.shift())) {
+  while ((removeHighlight = moduleState.cleanupFunctions.shift())) {
     removeHighlight();
   }
   target.normalize();
@@ -111,19 +113,18 @@
 });
 
 async function anchor(selector) {
-  const scope = document.createRange();
-  scope.selectNodeContents(target);
-
   const matchAll = createMatcher(selector);
   const ranges = [];
 
-  for await (const range of matchAll(scope)) {
+  // First collect all matches, and only then highlight them; to avoid
+  // modifying the DOM while the matcher is running.
+  for await (const range of matchAll(target)) {
     ranges.push(range);
   }
 
   for (const range of ranges) {
-    const removeHighlight = highlightRange(range);
-    cleanupFunctions.push(removeHighlight);
+    const removeHighlight = highlightText(range);
+    moduleState.cleanupFunctions.push(removeHighlight);
   }
 
   info.innerText += JSON.stringify(selector, null, 2) + '\n\n';
@@ -132,15 +133,13 @@
 async function onSelectionChange() {
   cleanup();
   const describeMode = form.describeMode.value;
-  const scope = document.createRange();
-  scope.selectNodeContents(source);
   const selection = document.getSelection();
   for (let i = 0; i < selection.rangeCount; i++) {
     const range = selection.getRangeAt(i);
     const selector =
       describeMode === 'TextPosition'
-        ? await describeTextPosition(range, scope)
-        : await describeTextQuote(range, scope, { minimumQuoteLength: 10 });
+        ? await describeTextPosition(range, source)
+        : await describeTextQuote(range, source, { minimumQuoteLength: 10 });
     await anchor(selector);
   }
 }
@@ -154,14 +153,26 @@
   event.preventDefault();
 }
 
-document.addEventListener('selectionchange', onSelectionChange);
-form.addEventListener('change', onSelectionChange);
-document.addEventListener('click', onSelectorExampleClick);
+function addEventListeners() {
+  document.addEventListener('selectionchange', onSelectionChange);
+  form.addEventListener('change', onSelectionChange);
+  document.addEventListener('click', onSelectorExampleClick);
+}
+addEventListeners();
+
+function removeEventListeners() {
+  document.removeEventListener('selectionchange', onSelectionChange);
+  form.removeEventListener('change', onSelectionChange);
+  document.removeEventListener('click', onSelectorExampleClick);
+}
 
 if (module.hot) {
   module.hot.accept();
-  module.hot.dispose(() => {
-    document.removeEventListener('selectionchange', onSelectionChange);
-    document.removeEventListener('click', onSelectorExampleClick);
+  module.hot.dispose((data) => {
+    removeEventListeners();
+    data.state = moduleState;
   });
+  if (module.hot.data?.state) {
+    moduleState = module.hot.data.state;
+  }
 }
diff --git a/web/test/index.html b/web/test/index.html
deleted file mode 100644
index 2d00bef..0000000
--- a/web/test/index.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<!doctype html>
-<html>
-  <meta charset="utf-8">
-  <title>Apache Annotator (incubating) test suite</title>
-  <script src="index.js"></script>
-</html>
diff --git a/web/webpack.config.js b/web/webpack.config.js
index b747b4c..5173882 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -20,24 +20,11 @@
  * under the License.
  */
 
-/* eslint-env node */
-
 const path = require('path');
 
 module.exports = {
-  context: path.resolve(__dirname),
-  entry: {
-    index: ['./index.html', './style.css'],
-    demo: ['./demo/index.html', './demo/index.js'],
-    test: [
-      './test/index.html',
-      'mocha-loader!multi-entry-loader?include=./packages/*/test/**/*.test.[jt]s!',
-    ],
-  },
-  resolve: {
-    extensions: ['.ts', '.js'],
-  },
-  devtool: 'inline-source-map',
+  context: __dirname,
+  entry: ['./index.html', './index.js', './style.css'],
   module: {
     rules: [
       {
@@ -59,8 +46,8 @@
     ],
   },
   output: {
+    // Note this directory is imported by the annotator website
     path: path.resolve(__dirname, 'dist'),
-    filename: '[name]/index.js',
   },
   devServer: {
     contentBase: false,
diff --git a/yarn.lock b/yarn.lock
index 519b856..50675a0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,10 +2,10 @@
 # yarn lockfile v1
 
 
-"@babel/cli@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.10.tgz#67a1015b1cd505bde1696196febf910c4c339a48"
-  integrity sha512-+y4ZnePpvWs1fc/LhZRTHkTesbXkyBYuOB+5CyodZqrEuETXi3zOVfpAQIdgC3lXbHLTDG9dQosxR9BhvLKDLQ==
+"@babel/cli@^7.13.14":
+  version "7.13.14"
+  resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.13.14.tgz#c395bc89ec4760c91f2027fa8b26f8b2bf42238f"
+  integrity sha512-zmEFV8WBRsW+mPQumO1/4b34QNALBVReaiHJOkxhUsdo/AvYM62c+SKSuLi2aZ42t3ocK6OI0uwUXRvrIbREZw==
   dependencies:
     commander "^4.0.1"
     convert-source-map "^1.1.0"
@@ -19,321 +19,202 @@
     "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents"
     chokidar "^3.4.0"
 
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
-  integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
+  integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
   dependencies:
-    "@babel/highlight" "^7.10.4"
+    "@babel/highlight" "^7.12.13"
 
-"@babel/code-frame@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
-  integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
+"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1"
+  integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==
+
+"@babel/core@^7.13.14", "@babel/core@^7.7.5":
+  version "7.13.14"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06"
+  integrity sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==
   dependencies:
-    "@babel/highlight" "^7.10.4"
-
-"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41"
-  integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==
-
-"@babel/core@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd"
-  integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==
-  dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/generator" "^7.12.10"
-    "@babel/helper-module-transforms" "^7.12.1"
-    "@babel/helpers" "^7.12.5"
-    "@babel/parser" "^7.12.10"
-    "@babel/template" "^7.12.7"
-    "@babel/traverse" "^7.12.10"
-    "@babel/types" "^7.12.10"
+    "@babel/code-frame" "^7.12.13"
+    "@babel/generator" "^7.13.9"
+    "@babel/helper-compilation-targets" "^7.13.13"
+    "@babel/helper-module-transforms" "^7.13.14"
+    "@babel/helpers" "^7.13.10"
+    "@babel/parser" "^7.13.13"
+    "@babel/template" "^7.12.13"
+    "@babel/traverse" "^7.13.13"
+    "@babel/types" "^7.13.14"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
-    gensync "^1.0.0-beta.1"
+    gensync "^1.0.0-beta.2"
     json5 "^2.1.2"
-    lodash "^4.17.19"
-    semver "^5.4.1"
+    semver "^6.3.0"
     source-map "^0.5.0"
 
-"@babel/core@^7.7.5":
-  version "7.11.6"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651"
-  integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==
+"@babel/generator@^7.13.9":
+  version "7.13.9"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39"
+  integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==
   dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/generator" "^7.11.6"
-    "@babel/helper-module-transforms" "^7.11.0"
-    "@babel/helpers" "^7.10.4"
-    "@babel/parser" "^7.11.5"
-    "@babel/template" "^7.10.4"
-    "@babel/traverse" "^7.11.5"
-    "@babel/types" "^7.11.5"
-    convert-source-map "^1.7.0"
-    debug "^4.1.0"
-    gensync "^1.0.0-beta.1"
-    json5 "^2.1.2"
-    lodash "^4.17.19"
-    resolve "^1.3.2"
-    semver "^5.4.1"
-    source-map "^0.5.0"
-
-"@babel/generator@^7.11.5", "@babel/generator@^7.11.6":
-  version "7.11.6"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620"
-  integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==
-  dependencies:
-    "@babel/types" "^7.11.5"
+    "@babel/types" "^7.13.0"
     jsesc "^2.5.1"
     source-map "^0.5.0"
 
-"@babel/generator@^7.12.10", "@babel/generator@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af"
-  integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==
+"@babel/helper-annotate-as-pure@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
+  integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==
   dependencies:
-    "@babel/types" "^7.12.11"
-    jsesc "^2.5.1"
-    source-map "^0.5.0"
+    "@babel/types" "^7.12.13"
 
-"@babel/generator@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de"
-  integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc"
+  integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==
   dependencies:
-    "@babel/types" "^7.12.5"
-    jsesc "^2.5.1"
-    source-map "^0.5.0"
+    "@babel/helper-explode-assignable-expression" "^7.12.13"
+    "@babel/types" "^7.12.13"
 
-"@babel/helper-annotate-as-pure@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3"
-  integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==
+"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.13.13", "@babel/helper-compilation-targets@^7.13.8":
+  version "7.13.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz#2b2972a0926474853f41e4adbc69338f520600e5"
+  integrity sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==
   dependencies:
-    "@babel/types" "^7.10.4"
-
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3"
-  integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==
-  dependencies:
-    "@babel/helper-explode-assignable-expression" "^7.10.4"
-    "@babel/types" "^7.10.4"
-
-"@babel/helper-compilation-targets@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831"
-  integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==
-  dependencies:
-    "@babel/compat-data" "^7.12.5"
-    "@babel/helper-validator-option" "^7.12.1"
+    "@babel/compat-data" "^7.13.12"
+    "@babel/helper-validator-option" "^7.12.17"
     browserslist "^4.14.5"
-    semver "^5.5.0"
+    semver "^6.3.0"
 
-"@babel/helper-create-class-features-plugin@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e"
-  integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==
+"@babel/helper-create-class-features-plugin@^7.13.0":
+  version "7.13.11"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6"
+  integrity sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==
   dependencies:
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/helper-member-expression-to-functions" "^7.12.1"
-    "@babel/helper-optimise-call-expression" "^7.10.4"
-    "@babel/helper-replace-supers" "^7.12.1"
-    "@babel/helper-split-export-declaration" "^7.10.4"
+    "@babel/helper-function-name" "^7.12.13"
+    "@babel/helper-member-expression-to-functions" "^7.13.0"
+    "@babel/helper-optimise-call-expression" "^7.12.13"
+    "@babel/helper-replace-supers" "^7.13.0"
+    "@babel/helper-split-export-declaration" "^7.12.13"
 
-"@babel/helper-create-regexp-features-plugin@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8"
-  integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==
+"@babel/helper-create-regexp-features-plugin@^7.12.13":
+  version "7.12.17"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7"
+  integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.10.4"
-    "@babel/helper-regex" "^7.10.4"
-    regexpu-core "^4.7.0"
-
-"@babel/helper-create-regexp-features-plugin@^7.12.1":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f"
-  integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.10.4"
+    "@babel/helper-annotate-as-pure" "^7.12.13"
     regexpu-core "^4.7.1"
 
-"@babel/helper-define-map@^7.10.4":
-  version "7.10.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30"
-  integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==
+"@babel/helper-define-polyfill-provider@^0.1.5":
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e"
+  integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==
   dependencies:
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/types" "^7.10.5"
-    lodash "^4.17.19"
+    "@babel/helper-compilation-targets" "^7.13.0"
+    "@babel/helper-module-imports" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/traverse" "^7.13.0"
+    debug "^4.1.1"
+    lodash.debounce "^4.0.8"
+    resolve "^1.14.2"
+    semver "^6.1.2"
 
-"@babel/helper-explode-assignable-expression@^7.10.4":
-  version "7.11.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b"
-  integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==
+"@babel/helper-explode-assignable-expression@^7.12.13":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f"
+  integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==
   dependencies:
-    "@babel/types" "^7.10.4"
+    "@babel/types" "^7.13.0"
 
-"@babel/helper-function-name@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
-  integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==
+"@babel/helper-function-name@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a"
+  integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==
   dependencies:
-    "@babel/helper-get-function-arity" "^7.10.4"
-    "@babel/template" "^7.10.4"
-    "@babel/types" "^7.10.4"
+    "@babel/helper-get-function-arity" "^7.12.13"
+    "@babel/template" "^7.12.13"
+    "@babel/types" "^7.12.13"
 
-"@babel/helper-function-name@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42"
-  integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==
+"@babel/helper-get-function-arity@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
+  integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
   dependencies:
-    "@babel/helper-get-function-arity" "^7.12.10"
-    "@babel/template" "^7.12.7"
-    "@babel/types" "^7.12.11"
+    "@babel/types" "^7.12.13"
 
-"@babel/helper-get-function-arity@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
-  integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==
+"@babel/helper-hoist-variables@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8"
+  integrity sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==
   dependencies:
-    "@babel/types" "^7.10.4"
+    "@babel/traverse" "^7.13.0"
+    "@babel/types" "^7.13.0"
 
-"@babel/helper-get-function-arity@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf"
-  integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==
+"@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72"
+  integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==
   dependencies:
-    "@babel/types" "^7.12.10"
+    "@babel/types" "^7.13.12"
 
-"@babel/helper-hoist-variables@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e"
-  integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==
+"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977"
+  integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==
   dependencies:
-    "@babel/types" "^7.10.4"
+    "@babel/types" "^7.13.12"
 
-"@babel/helper-member-expression-to-functions@^7.10.4":
-  version "7.11.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df"
-  integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==
+"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14":
+  version "7.13.14"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef"
+  integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==
   dependencies:
-    "@babel/types" "^7.11.0"
+    "@babel/helper-module-imports" "^7.13.12"
+    "@babel/helper-replace-supers" "^7.13.12"
+    "@babel/helper-simple-access" "^7.13.12"
+    "@babel/helper-split-export-declaration" "^7.12.13"
+    "@babel/helper-validator-identifier" "^7.12.11"
+    "@babel/template" "^7.12.13"
+    "@babel/traverse" "^7.13.13"
+    "@babel/types" "^7.13.14"
 
-"@babel/helper-member-expression-to-functions@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c"
-  integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==
+"@babel/helper-optimise-call-expression@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
+  integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==
   dependencies:
-    "@babel/types" "^7.12.1"
+    "@babel/types" "^7.12.13"
 
-"@babel/helper-module-imports@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620"
-  integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
+  integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
+
+"@babel/helper-remap-async-to-generator@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209"
+  integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==
   dependencies:
-    "@babel/types" "^7.10.4"
+    "@babel/helper-annotate-as-pure" "^7.12.13"
+    "@babel/helper-wrap-function" "^7.13.0"
+    "@babel/types" "^7.13.0"
 
-"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb"
-  integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==
+"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804"
+  integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==
   dependencies:
-    "@babel/types" "^7.12.5"
+    "@babel/helper-member-expression-to-functions" "^7.13.12"
+    "@babel/helper-optimise-call-expression" "^7.12.13"
+    "@babel/traverse" "^7.13.0"
+    "@babel/types" "^7.13.12"
 
-"@babel/helper-module-transforms@^7.11.0":
-  version "7.11.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359"
-  integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==
+"@babel/helper-simple-access@^7.12.13", "@babel/helper-simple-access@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
+  integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==
   dependencies:
-    "@babel/helper-module-imports" "^7.10.4"
-    "@babel/helper-replace-supers" "^7.10.4"
-    "@babel/helper-simple-access" "^7.10.4"
-    "@babel/helper-split-export-declaration" "^7.11.0"
-    "@babel/template" "^7.10.4"
-    "@babel/types" "^7.11.0"
-    lodash "^4.17.19"
-
-"@babel/helper-module-transforms@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c"
-  integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==
-  dependencies:
-    "@babel/helper-module-imports" "^7.12.1"
-    "@babel/helper-replace-supers" "^7.12.1"
-    "@babel/helper-simple-access" "^7.12.1"
-    "@babel/helper-split-export-declaration" "^7.11.0"
-    "@babel/helper-validator-identifier" "^7.10.4"
-    "@babel/template" "^7.10.4"
-    "@babel/traverse" "^7.12.1"
-    "@babel/types" "^7.12.1"
-    lodash "^4.17.19"
-
-"@babel/helper-optimise-call-expression@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673"
-  integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==
-  dependencies:
-    "@babel/types" "^7.10.4"
-
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
-  integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==
-
-"@babel/helper-regex@^7.10.4":
-  version "7.10.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0"
-  integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==
-  dependencies:
-    lodash "^4.17.19"
-
-"@babel/helper-remap-async-to-generator@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd"
-  integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.10.4"
-    "@babel/helper-wrap-function" "^7.10.4"
-    "@babel/types" "^7.12.1"
-
-"@babel/helper-replace-supers@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf"
-  integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==
-  dependencies:
-    "@babel/helper-member-expression-to-functions" "^7.10.4"
-    "@babel/helper-optimise-call-expression" "^7.10.4"
-    "@babel/traverse" "^7.10.4"
-    "@babel/types" "^7.10.4"
-
-"@babel/helper-replace-supers@^7.12.1":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz#f009a17543bbbbce16b06206ae73b63d3fca68d9"
-  integrity sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==
-  dependencies:
-    "@babel/helper-member-expression-to-functions" "^7.12.1"
-    "@babel/helper-optimise-call-expression" "^7.10.4"
-    "@babel/traverse" "^7.12.5"
-    "@babel/types" "^7.12.5"
-
-"@babel/helper-simple-access@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461"
-  integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==
-  dependencies:
-    "@babel/template" "^7.10.4"
-    "@babel/types" "^7.10.4"
-
-"@babel/helper-simple-access@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136"
-  integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==
-  dependencies:
-    "@babel/types" "^7.12.1"
+    "@babel/types" "^7.13.12"
 
 "@babel/helper-skip-transparent-expression-wrappers@^7.12.1":
   version "7.12.1"
@@ -342,217 +223,189 @@
   dependencies:
     "@babel/types" "^7.12.1"
 
-"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0":
-  version "7.11.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f"
-  integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==
+"@babel/helper-split-export-declaration@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
+  integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
   dependencies:
-    "@babel/types" "^7.11.0"
-
-"@babel/helper-split-export-declaration@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a"
-  integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==
-  dependencies:
-    "@babel/types" "^7.12.11"
-
-"@babel/helper-validator-identifier@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
-  integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
+    "@babel/types" "^7.12.13"
 
 "@babel/helper-validator-identifier@^7.12.11":
   version "7.12.11"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
   integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
 
-"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f"
-  integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==
+"@babel/helper-validator-option@^7.12.17":
+  version "7.12.17"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831"
+  integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==
 
-"@babel/helper-wrap-function@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87"
-  integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==
+"@babel/helper-wrap-function@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4"
+  integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==
   dependencies:
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/template" "^7.10.4"
-    "@babel/traverse" "^7.10.4"
-    "@babel/types" "^7.10.4"
+    "@babel/helper-function-name" "^7.12.13"
+    "@babel/template" "^7.12.13"
+    "@babel/traverse" "^7.13.0"
+    "@babel/types" "^7.13.0"
 
-"@babel/helpers@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044"
-  integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==
+"@babel/helpers@^7.13.10":
+  version "7.13.10"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8"
+  integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==
   dependencies:
-    "@babel/template" "^7.10.4"
-    "@babel/traverse" "^7.10.4"
-    "@babel/types" "^7.10.4"
+    "@babel/template" "^7.12.13"
+    "@babel/traverse" "^7.13.0"
+    "@babel/types" "^7.13.0"
 
-"@babel/helpers@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e"
-  integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==
+"@babel/highlight@^7.12.13":
+  version "7.13.10"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
+  integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
   dependencies:
-    "@babel/template" "^7.10.4"
-    "@babel/traverse" "^7.12.5"
-    "@babel/types" "^7.12.5"
-
-"@babel/highlight@^7.10.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
-  integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
-  dependencies:
-    "@babel/helper-validator-identifier" "^7.10.4"
+    "@babel/helper-validator-identifier" "^7.12.11"
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.7.5":
-  version "7.11.5"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
-  integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
+"@babel/parser@^7.12.13", "@babel/parser@^7.13.13", "@babel/parser@^7.7.5":
+  version "7.13.13"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df"
+  integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==
 
-"@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79"
-  integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==
-
-"@babel/parser@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0"
-  integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==
-
-"@babel/plugin-proposal-async-generator-functions@^7.12.1":
-  version "7.12.12"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566"
-  integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a"
+  integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-remap-async-to-generator" "^7.12.1"
-    "@babel/plugin-syntax-async-generators" "^7.8.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
+    "@babel/plugin-proposal-optional-chaining" "^7.13.12"
 
-"@babel/plugin-proposal-class-properties@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de"
-  integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==
+"@babel/plugin-proposal-async-generator-functions@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1"
+  integrity sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-remap-async-to-generator" "^7.13.0"
+    "@babel/plugin-syntax-async-generators" "^7.8.4"
 
-"@babel/plugin-proposal-dynamic-import@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc"
-  integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==
+"@babel/plugin-proposal-class-properties@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37"
+  integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-dynamic-import" "^7.8.0"
+    "@babel/helper-create-class-features-plugin" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-proposal-export-namespace-from@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4"
-  integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==
+"@babel/plugin-proposal-dynamic-import@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d"
+  integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+
+"@babel/plugin-proposal-export-namespace-from@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d"
+  integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.12.13"
     "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
 
-"@babel/plugin-proposal-json-strings@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c"
-  integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==
+"@babel/plugin-proposal-json-strings@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b"
+  integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-json-strings" "^7.8.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-json-strings" "^7.8.3"
 
-"@babel/plugin-proposal-logical-assignment-operators@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751"
-  integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==
+"@babel/plugin-proposal-logical-assignment-operators@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a"
+  integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
     "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
 
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c"
-  integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3"
+  integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
 
-"@babel/plugin-proposal-numeric-separator@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b"
-  integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==
+"@babel/plugin-proposal-numeric-separator@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db"
+  integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
     "@babel/plugin-syntax-numeric-separator" "^7.10.4"
 
-"@babel/plugin-proposal-object-rest-spread@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069"
-  integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==
+"@babel/plugin-proposal-object-rest-spread@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a"
+  integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-object-rest-spread" "^7.8.0"
-    "@babel/plugin-transform-parameters" "^7.12.1"
+    "@babel/compat-data" "^7.13.8"
+    "@babel/helper-compilation-targets" "^7.13.8"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+    "@babel/plugin-transform-parameters" "^7.13.0"
 
-"@babel/plugin-proposal-optional-catch-binding@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942"
-  integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==
+"@babel/plugin-proposal-optional-catch-binding@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107"
+  integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
 
-"@babel/plugin-proposal-optional-chaining@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c"
-  integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==
+"@babel/plugin-proposal-optional-chaining@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866"
+  integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
-    "@babel/plugin-syntax-optional-chaining" "^7.8.0"
+    "@babel/plugin-syntax-optional-chaining" "^7.8.3"
 
-"@babel/plugin-proposal-private-methods@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389"
-  integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==
+"@babel/plugin-proposal-private-methods@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787"
+  integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-create-class-features-plugin" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072"
-  integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==
+"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba"
+  integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-create-regexp-features-plugin" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d"
-  integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==
-  dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.10.4"
-    "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-async-generators@^7.8.0":
+"@babel/plugin-syntax-async-generators@^7.8.4":
   version "7.8.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
   integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
-"@babel/plugin-syntax-class-properties@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978"
-  integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==
+"@babel/plugin-syntax-class-properties@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
+  integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-syntax-dynamic-import@^7.8.0":
+"@babel/plugin-syntax-dynamic-import@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
   integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
@@ -566,7 +419,7 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-syntax-json-strings@^7.8.0":
+"@babel/plugin-syntax-json-strings@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
   integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
@@ -580,7 +433,7 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.10.4"
 
-"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0":
+"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
   integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==
@@ -594,392 +447,389 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.10.4"
 
-"@babel/plugin-syntax-object-rest-spread@^7.8.0":
+"@babel/plugin-syntax-object-rest-spread@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
   integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
-"@babel/plugin-syntax-optional-catch-binding@^7.8.0":
+"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1"
   integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
-"@babel/plugin-syntax-optional-chaining@^7.8.0":
+"@babel/plugin-syntax-optional-chaining@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a"
   integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
-"@babel/plugin-syntax-top-level-await@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0"
-  integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==
+"@babel/plugin-syntax-top-level-await@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178"
+  integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-syntax-typescript@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5"
-  integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA==
+"@babel/plugin-syntax-typescript@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474"
+  integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-arrow-functions@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3"
-  integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==
+"@babel/plugin-transform-arrow-functions@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae"
+  integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-async-to-generator@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1"
-  integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==
+"@babel/plugin-transform-async-to-generator@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f"
+  integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==
   dependencies:
-    "@babel/helper-module-imports" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-remap-async-to-generator" "^7.12.1"
+    "@babel/helper-module-imports" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-remap-async-to-generator" "^7.13.0"
 
-"@babel/plugin-transform-block-scoped-functions@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9"
-  integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==
+"@babel/plugin-transform-block-scoped-functions@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4"
+  integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-block-scoping@^7.12.11":
-  version "7.12.12"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca"
-  integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==
+"@babel/plugin-transform-block-scoping@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61"
+  integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-classes@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6"
-  integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==
+"@babel/plugin-transform-classes@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b"
+  integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.10.4"
-    "@babel/helper-define-map" "^7.10.4"
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/helper-optimise-call-expression" "^7.10.4"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-replace-supers" "^7.12.1"
-    "@babel/helper-split-export-declaration" "^7.10.4"
+    "@babel/helper-annotate-as-pure" "^7.12.13"
+    "@babel/helper-function-name" "^7.12.13"
+    "@babel/helper-optimise-call-expression" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-replace-supers" "^7.13.0"
+    "@babel/helper-split-export-declaration" "^7.12.13"
     globals "^11.1.0"
 
-"@babel/plugin-transform-computed-properties@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852"
-  integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==
+"@babel/plugin-transform-computed-properties@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed"
+  integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-destructuring@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847"
-  integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==
+"@babel/plugin-transform-destructuring@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963"
+  integrity sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-dotall-regex@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975"
-  integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==
+"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad"
+  integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-create-regexp-features-plugin" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-dotall-regex@^7.4.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee"
-  integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==
+"@babel/plugin-transform-duplicate-keys@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de"
+  integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.10.4"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-duplicate-keys@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228"
-  integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==
+"@babel/plugin-transform-exponentiation-operator@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1"
+  integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-exponentiation-operator@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0"
-  integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==
+"@babel/plugin-transform-for-of@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062"
+  integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==
   dependencies:
-    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-for-of@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa"
-  integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==
+"@babel/plugin-transform-function-name@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051"
+  integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-function-name" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-function-name@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667"
-  integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==
+"@babel/plugin-transform-literals@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9"
+  integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==
   dependencies:
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-literals@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57"
-  integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==
+"@babel/plugin-transform-member-expression-literals@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40"
+  integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-member-expression-literals@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad"
-  integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==
+"@babel/plugin-transform-modules-amd@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3"
+  integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-transform-modules-amd@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9"
-  integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==
-  dependencies:
-    "@babel/helper-module-transforms" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-module-transforms" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
     babel-plugin-dynamic-import-node "^2.3.3"
 
-"@babel/plugin-transform-modules-commonjs@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648"
-  integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==
+"@babel/plugin-transform-modules-commonjs@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b"
+  integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==
   dependencies:
-    "@babel/helper-module-transforms" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-simple-access" "^7.12.1"
+    "@babel/helper-module-transforms" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-simple-access" "^7.12.13"
     babel-plugin-dynamic-import-node "^2.3.3"
 
-"@babel/plugin-transform-modules-systemjs@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086"
-  integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==
+"@babel/plugin-transform-modules-systemjs@^7.13.8":
+  version "7.13.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3"
+  integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==
   dependencies:
-    "@babel/helper-hoist-variables" "^7.10.4"
-    "@babel/helper-module-transforms" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-validator-identifier" "^7.10.4"
+    "@babel/helper-hoist-variables" "^7.13.0"
+    "@babel/helper-module-transforms" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-validator-identifier" "^7.12.11"
     babel-plugin-dynamic-import-node "^2.3.3"
 
-"@babel/plugin-transform-modules-umd@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902"
-  integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==
+"@babel/plugin-transform-modules-umd@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b"
+  integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==
   dependencies:
-    "@babel/helper-module-transforms" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-module-transforms" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753"
-  integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9"
+  integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.12.1"
+    "@babel/helper-create-regexp-features-plugin" "^7.12.13"
 
-"@babel/plugin-transform-new-target@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0"
-  integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==
+"@babel/plugin-transform-new-target@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c"
+  integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-object-super@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e"
-  integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==
+"@babel/plugin-transform-object-super@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7"
+  integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-replace-supers" "^7.12.1"
+    "@babel/helper-plugin-utils" "^7.12.13"
+    "@babel/helper-replace-supers" "^7.12.13"
 
-"@babel/plugin-transform-parameters@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d"
-  integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==
+"@babel/plugin-transform-parameters@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007"
+  integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-property-literals@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd"
-  integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==
+"@babel/plugin-transform-property-literals@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81"
+  integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-regenerator@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753"
-  integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==
+"@babel/plugin-transform-regenerator@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5"
+  integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA==
   dependencies:
     regenerator-transform "^0.14.2"
 
-"@babel/plugin-transform-reserved-words@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8"
-  integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==
+"@babel/plugin-transform-reserved-words@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695"
+  integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-runtime@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz#af0fded4e846c4b37078e8e5d06deac6cd848562"
-  integrity sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==
+"@babel/plugin-transform-runtime@^7.13.10":
+  version "7.13.10"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz#a1e40d22e2bf570c591c9c7e5ab42d6bf1e419e1"
+  integrity sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA==
   dependencies:
-    "@babel/helper-module-imports" "^7.12.5"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    semver "^5.5.1"
+    "@babel/helper-module-imports" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    babel-plugin-polyfill-corejs2 "^0.1.4"
+    babel-plugin-polyfill-corejs3 "^0.1.3"
+    babel-plugin-polyfill-regenerator "^0.1.2"
+    semver "^6.3.0"
 
-"@babel/plugin-transform-shorthand-properties@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3"
-  integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==
+"@babel/plugin-transform-shorthand-properties@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad"
+  integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-spread@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e"
-  integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==
+"@babel/plugin-transform-spread@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd"
+  integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
 
-"@babel/plugin-transform-sticky-regex@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad"
-  integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==
+"@babel/plugin-transform-sticky-regex@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f"
+  integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-template-literals@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843"
-  integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==
+"@babel/plugin-transform-template-literals@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d"
+  integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.13.0"
 
-"@babel/plugin-transform-typeof-symbol@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b"
-  integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==
+"@babel/plugin-transform-typeof-symbol@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f"
+  integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-typescript@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4"
-  integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw==
+"@babel/plugin-transform-typescript@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853"
+  integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/plugin-syntax-typescript" "^7.12.1"
+    "@babel/helper-create-class-features-plugin" "^7.13.0"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/plugin-syntax-typescript" "^7.12.13"
 
-"@babel/plugin-transform-unicode-escapes@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709"
-  integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==
+"@babel/plugin-transform-unicode-escapes@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74"
+  integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-unicode-regex@^7.12.1":
-  version "7.12.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb"
-  integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==
+"@babel/plugin-transform-unicode-regex@^7.12.13":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac"
+  integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.12.1"
-    "@babel/helper-plugin-utils" "^7.10.4"
+    "@babel/helper-create-regexp-features-plugin" "^7.12.13"
+    "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/preset-env@^7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9"
-  integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==
+"@babel/preset-env@^7.13.12":
+  version "7.13.12"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.12.tgz#6dff470478290582ac282fb77780eadf32480237"
+  integrity sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA==
   dependencies:
-    "@babel/compat-data" "^7.12.7"
-    "@babel/helper-compilation-targets" "^7.12.5"
-    "@babel/helper-module-imports" "^7.12.5"
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-validator-option" "^7.12.11"
-    "@babel/plugin-proposal-async-generator-functions" "^7.12.1"
-    "@babel/plugin-proposal-class-properties" "^7.12.1"
-    "@babel/plugin-proposal-dynamic-import" "^7.12.1"
-    "@babel/plugin-proposal-export-namespace-from" "^7.12.1"
-    "@babel/plugin-proposal-json-strings" "^7.12.1"
-    "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1"
-    "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1"
-    "@babel/plugin-proposal-numeric-separator" "^7.12.7"
-    "@babel/plugin-proposal-object-rest-spread" "^7.12.1"
-    "@babel/plugin-proposal-optional-catch-binding" "^7.12.1"
-    "@babel/plugin-proposal-optional-chaining" "^7.12.7"
-    "@babel/plugin-proposal-private-methods" "^7.12.1"
-    "@babel/plugin-proposal-unicode-property-regex" "^7.12.1"
-    "@babel/plugin-syntax-async-generators" "^7.8.0"
-    "@babel/plugin-syntax-class-properties" "^7.12.1"
-    "@babel/plugin-syntax-dynamic-import" "^7.8.0"
+    "@babel/compat-data" "^7.13.12"
+    "@babel/helper-compilation-targets" "^7.13.10"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-validator-option" "^7.12.17"
+    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12"
+    "@babel/plugin-proposal-async-generator-functions" "^7.13.8"
+    "@babel/plugin-proposal-class-properties" "^7.13.0"
+    "@babel/plugin-proposal-dynamic-import" "^7.13.8"
+    "@babel/plugin-proposal-export-namespace-from" "^7.12.13"
+    "@babel/plugin-proposal-json-strings" "^7.13.8"
+    "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8"
+    "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8"
+    "@babel/plugin-proposal-numeric-separator" "^7.12.13"
+    "@babel/plugin-proposal-object-rest-spread" "^7.13.8"
+    "@babel/plugin-proposal-optional-catch-binding" "^7.13.8"
+    "@babel/plugin-proposal-optional-chaining" "^7.13.12"
+    "@babel/plugin-proposal-private-methods" "^7.13.0"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.12.13"
+    "@babel/plugin-syntax-async-generators" "^7.8.4"
+    "@babel/plugin-syntax-class-properties" "^7.12.13"
+    "@babel/plugin-syntax-dynamic-import" "^7.8.3"
     "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
-    "@babel/plugin-syntax-json-strings" "^7.8.0"
+    "@babel/plugin-syntax-json-strings" "^7.8.3"
     "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
-    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
+    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
     "@babel/plugin-syntax-numeric-separator" "^7.10.4"
-    "@babel/plugin-syntax-object-rest-spread" "^7.8.0"
-    "@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
-    "@babel/plugin-syntax-optional-chaining" "^7.8.0"
-    "@babel/plugin-syntax-top-level-await" "^7.12.1"
-    "@babel/plugin-transform-arrow-functions" "^7.12.1"
-    "@babel/plugin-transform-async-to-generator" "^7.12.1"
-    "@babel/plugin-transform-block-scoped-functions" "^7.12.1"
-    "@babel/plugin-transform-block-scoping" "^7.12.11"
-    "@babel/plugin-transform-classes" "^7.12.1"
-    "@babel/plugin-transform-computed-properties" "^7.12.1"
-    "@babel/plugin-transform-destructuring" "^7.12.1"
-    "@babel/plugin-transform-dotall-regex" "^7.12.1"
-    "@babel/plugin-transform-duplicate-keys" "^7.12.1"
-    "@babel/plugin-transform-exponentiation-operator" "^7.12.1"
-    "@babel/plugin-transform-for-of" "^7.12.1"
-    "@babel/plugin-transform-function-name" "^7.12.1"
-    "@babel/plugin-transform-literals" "^7.12.1"
-    "@babel/plugin-transform-member-expression-literals" "^7.12.1"
-    "@babel/plugin-transform-modules-amd" "^7.12.1"
-    "@babel/plugin-transform-modules-commonjs" "^7.12.1"
-    "@babel/plugin-transform-modules-systemjs" "^7.12.1"
-    "@babel/plugin-transform-modules-umd" "^7.12.1"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1"
-    "@babel/plugin-transform-new-target" "^7.12.1"
-    "@babel/plugin-transform-object-super" "^7.12.1"
-    "@babel/plugin-transform-parameters" "^7.12.1"
-    "@babel/plugin-transform-property-literals" "^7.12.1"
-    "@babel/plugin-transform-regenerator" "^7.12.1"
-    "@babel/plugin-transform-reserved-words" "^7.12.1"
-    "@babel/plugin-transform-shorthand-properties" "^7.12.1"
-    "@babel/plugin-transform-spread" "^7.12.1"
-    "@babel/plugin-transform-sticky-regex" "^7.12.7"
-    "@babel/plugin-transform-template-literals" "^7.12.1"
-    "@babel/plugin-transform-typeof-symbol" "^7.12.10"
-    "@babel/plugin-transform-unicode-escapes" "^7.12.1"
-    "@babel/plugin-transform-unicode-regex" "^7.12.1"
-    "@babel/preset-modules" "^0.1.3"
-    "@babel/types" "^7.12.11"
-    core-js-compat "^3.8.0"
-    semver "^5.5.0"
+    "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+    "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+    "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+    "@babel/plugin-syntax-top-level-await" "^7.12.13"
+    "@babel/plugin-transform-arrow-functions" "^7.13.0"
+    "@babel/plugin-transform-async-to-generator" "^7.13.0"
+    "@babel/plugin-transform-block-scoped-functions" "^7.12.13"
+    "@babel/plugin-transform-block-scoping" "^7.12.13"
+    "@babel/plugin-transform-classes" "^7.13.0"
+    "@babel/plugin-transform-computed-properties" "^7.13.0"
+    "@babel/plugin-transform-destructuring" "^7.13.0"
+    "@babel/plugin-transform-dotall-regex" "^7.12.13"
+    "@babel/plugin-transform-duplicate-keys" "^7.12.13"
+    "@babel/plugin-transform-exponentiation-operator" "^7.12.13"
+    "@babel/plugin-transform-for-of" "^7.13.0"
+    "@babel/plugin-transform-function-name" "^7.12.13"
+    "@babel/plugin-transform-literals" "^7.12.13"
+    "@babel/plugin-transform-member-expression-literals" "^7.12.13"
+    "@babel/plugin-transform-modules-amd" "^7.13.0"
+    "@babel/plugin-transform-modules-commonjs" "^7.13.8"
+    "@babel/plugin-transform-modules-systemjs" "^7.13.8"
+    "@babel/plugin-transform-modules-umd" "^7.13.0"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13"
+    "@babel/plugin-transform-new-target" "^7.12.13"
+    "@babel/plugin-transform-object-super" "^7.12.13"
+    "@babel/plugin-transform-parameters" "^7.13.0"
+    "@babel/plugin-transform-property-literals" "^7.12.13"
+    "@babel/plugin-transform-regenerator" "^7.12.13"
+    "@babel/plugin-transform-reserved-words" "^7.12.13"
+    "@babel/plugin-transform-shorthand-properties" "^7.12.13"
+    "@babel/plugin-transform-spread" "^7.13.0"
+    "@babel/plugin-transform-sticky-regex" "^7.12.13"
+    "@babel/plugin-transform-template-literals" "^7.13.0"
+    "@babel/plugin-transform-typeof-symbol" "^7.12.13"
+    "@babel/plugin-transform-unicode-escapes" "^7.12.13"
+    "@babel/plugin-transform-unicode-regex" "^7.12.13"
+    "@babel/preset-modules" "^0.1.4"
+    "@babel/types" "^7.13.12"
+    babel-plugin-polyfill-corejs2 "^0.1.4"
+    babel-plugin-polyfill-corejs3 "^0.1.3"
+    babel-plugin-polyfill-regenerator "^0.1.2"
+    core-js-compat "^3.9.0"
+    semver "^6.3.0"
 
-"@babel/preset-modules@^0.1.3":
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72"
-  integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==
+"@babel/preset-modules@^0.1.4":
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e"
+  integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
@@ -987,19 +837,19 @@
     "@babel/types" "^7.4.4"
     esutils "^2.0.2"
 
-"@babel/preset-typescript@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3"
-  integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw==
+"@babel/preset-typescript@^7.13.0":
+  version "7.13.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz#ab107e5f050609d806fbb039bec553b33462c60a"
+  integrity sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.10.4"
-    "@babel/helper-validator-option" "^7.12.1"
-    "@babel/plugin-transform-typescript" "^7.12.1"
+    "@babel/helper-plugin-utils" "^7.13.0"
+    "@babel/helper-validator-option" "^7.12.17"
+    "@babel/plugin-transform-typescript" "^7.13.0"
 
-"@babel/register@^7.12.10":
-  version "7.12.10"
-  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.10.tgz#19b87143f17128af4dbe7af54c735663b3999f60"
-  integrity sha512-EvX/BvMMJRAA3jZgILWgbsrHwBQvllC5T8B29McyME8DvkdOxk4ujESfrMvME8IHSDvWXrmMXxPvA/lx2gqPLQ==
+"@babel/register@^7.13.14":
+  version "7.13.14"
+  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.13.14.tgz#bbfa8f4f027c2ebc432e8e69e078b632605f2d9b"
+  integrity sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q==
   dependencies:
     find-cache-dir "^2.0.0"
     lodash "^4.17.19"
@@ -1007,10 +857,10 @@
     pirates "^4.0.0"
     source-map-support "^0.5.16"
 
-"@babel/runtime-corejs3@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz#ffee91da0eb4c6dae080774e94ba606368e414f4"
-  integrity sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ==
+"@babel/runtime-corejs3@^7.13.10":
+  version "7.13.10"
+  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.13.10.tgz#14c3f4c85de22ba88e8e86685d13e8861a82fe86"
+  integrity sha512-x/XYVQ1h684pp1mJwOV4CyvqZXqbc8CMsMGUnAbuc82ZCdv1U63w5RSUzgDSXQHG5Rps/kiksH6g2D5BuaKyXg==
   dependencies:
     core-js-pure "^3.0.0"
     regenerator-runtime "^0.13.4"
@@ -1022,91 +872,33 @@
   dependencies:
     regenerator-runtime "^0.13.4"
 
-"@babel/template@^7.10.4", "@babel/template@^7.7.4":
-  version "7.10.4"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
-  integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==
+"@babel/template@^7.12.13", "@babel/template@^7.7.4":
+  version "7.12.13"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
+  integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
   dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/parser" "^7.10.4"
-    "@babel/types" "^7.10.4"
+    "@babel/code-frame" "^7.12.13"
+    "@babel/parser" "^7.12.13"
+    "@babel/types" "^7.12.13"
 
-"@babel/template@^7.12.7":
-  version "7.12.7"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc"
-  integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==
+"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.7.4":
+  version "7.13.13"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d"
+  integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==
   dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/parser" "^7.12.7"
-    "@babel/types" "^7.12.7"
-
-"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.7.4":
-  version "7.11.5"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
-  integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==
-  dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/generator" "^7.11.5"
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/helper-split-export-declaration" "^7.11.0"
-    "@babel/parser" "^7.11.5"
-    "@babel/types" "^7.11.5"
+    "@babel/code-frame" "^7.12.13"
+    "@babel/generator" "^7.13.9"
+    "@babel/helper-function-name" "^7.12.13"
+    "@babel/helper-split-export-declaration" "^7.12.13"
+    "@babel/parser" "^7.13.13"
+    "@babel/types" "^7.13.13"
     debug "^4.1.0"
     globals "^11.1.0"
-    lodash "^4.17.19"
 
-"@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10":
-  version "7.12.12"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376"
-  integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==
-  dependencies:
-    "@babel/code-frame" "^7.12.11"
-    "@babel/generator" "^7.12.11"
-    "@babel/helper-function-name" "^7.12.11"
-    "@babel/helper-split-export-declaration" "^7.12.11"
-    "@babel/parser" "^7.12.11"
-    "@babel/types" "^7.12.12"
-    debug "^4.1.0"
-    globals "^11.1.0"
-    lodash "^4.17.19"
-
-"@babel/traverse@^7.12.5":
-  version "7.12.5"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.5.tgz#78a0c68c8e8a35e4cacfd31db8bb303d5606f095"
-  integrity sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==
-  dependencies:
-    "@babel/code-frame" "^7.10.4"
-    "@babel/generator" "^7.12.5"
-    "@babel/helper-function-name" "^7.10.4"
-    "@babel/helper-split-export-declaration" "^7.11.0"
-    "@babel/parser" "^7.12.5"
-    "@babel/types" "^7.12.5"
-    debug "^4.1.0"
-    globals "^11.1.0"
-    lodash "^4.17.19"
-
-"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4":
-  version "7.11.5"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
-  integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
-  dependencies:
-    "@babel/helper-validator-identifier" "^7.10.4"
-    lodash "^4.17.19"
-    to-fast-properties "^2.0.0"
-
-"@babel/types@^7.12.1", "@babel/types@^7.12.5":
-  version "7.12.6"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96"
-  integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==
-  dependencies:
-    "@babel/helper-validator-identifier" "^7.10.4"
-    lodash "^4.17.19"
-    to-fast-properties "^2.0.0"
-
-"@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.7":
-  version "7.12.12"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299"
-  integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==
+"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.4.4":
+  version "7.13.14"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d"
+  integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==
   dependencies:
     "@babel/helper-validator-identifier" "^7.12.11"
     lodash "^4.17.19"
@@ -2020,11 +1812,16 @@
     "@types/minimatch" "*"
     "@types/node" "*"
 
-"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
+"@types/json-schema@^7.0.3":
   version "7.0.5"
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
   integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
 
+"@types/json-schema@^7.0.6":
+  version "7.0.7"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
+  integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
+
 "@types/json5@^0.0.29":
   version "0.0.29"
   resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -2065,74 +1862,74 @@
   dependencies:
     "@types/node" "*"
 
-"@typescript-eslint/eslint-plugin@^4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.1.tgz#78d5b18e259b13c2f4ec41dd9105af269a161a75"
-  integrity sha512-Hoxyt99EA9LMmqo/5PuWWPeWeB3mKyvibfJ1Hy5SfiUpjE8Nqp+5QNd9fOkzL66+fqvIWSIE+Ett16LGMzCGnQ==
+"@typescript-eslint/eslint-plugin@^4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92"
+  integrity sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.1.1"
-    "@typescript-eslint/scope-manager" "4.1.1"
+    "@typescript-eslint/experimental-utils" "4.20.0"
+    "@typescript-eslint/scope-manager" "4.20.0"
     debug "^4.1.1"
     functional-red-black-tree "^1.0.1"
+    lodash "^4.17.15"
     regexpp "^3.0.0"
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/experimental-utils@4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz#52ff4e37c93113eb96385a4e6d075abece1ea72d"
-  integrity sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A==
+"@typescript-eslint/experimental-utils@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz#a8ab2d7b61924f99042b7d77372996d5f41dc44b"
+  integrity sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/scope-manager" "4.1.1"
-    "@typescript-eslint/types" "4.1.1"
-    "@typescript-eslint/typescript-estree" "4.1.1"
+    "@typescript-eslint/scope-manager" "4.20.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/typescript-estree" "4.20.0"
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
-"@typescript-eslint/parser@^4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.1.1.tgz#324b4b35e314075adbc92bd8330cf3ef0c88cf3e"
-  integrity sha512-NLIhmicpKGfJbdXyQBz9j48PA6hq6e+SDOoXy7Ak6bq1ebGqbgG+fR1UIDAuay6OjQdot69c/URu2uLlsP8GQQ==
+"@typescript-eslint/parser@^4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.20.0.tgz#8dd403c8b4258b99194972d9799e201b8d083bdd"
+  integrity sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.1.1"
-    "@typescript-eslint/types" "4.1.1"
-    "@typescript-eslint/typescript-estree" "4.1.1"
+    "@typescript-eslint/scope-manager" "4.20.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/typescript-estree" "4.20.0"
     debug "^4.1.1"
 
-"@typescript-eslint/scope-manager@4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.1.1.tgz#bdb8526e82435f32b4ccd9dd4cec01af97b48850"
-  integrity sha512-0W8TTobCvIIQ2FsrYTffyZGAAFUyIbEHq5EYJb1m7Rpd005jrnOvKOo8ywCLhs/Bm17C+KsrUboBvBAARQVvyA==
+"@typescript-eslint/scope-manager@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz#953ecbf3b00845ece7be66246608be9d126d05ca"
+  integrity sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ==
   dependencies:
-    "@typescript-eslint/types" "4.1.1"
-    "@typescript-eslint/visitor-keys" "4.1.1"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/visitor-keys" "4.20.0"
 
-"@typescript-eslint/types@4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.1.tgz#57500c4a86b28cb47094c1a62f1177ea279a09cb"
-  integrity sha512-zrBiqOKYerMTllKcn+BP+i1b7LW/EbMMYytroXMxUTvFPn1smkCu0D7lSAx29fTUO4jnwV0ljSvYQtn2vNrNxA==
+"@typescript-eslint/types@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.20.0.tgz#c6cf5ef3c9b1c8f699a9bbdafb7a1da1ca781225"
+  integrity sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w==
 
-"@typescript-eslint/typescript-estree@4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.1.tgz#2015a84d71303ecdb6f46efd807ac19a51aab490"
-  integrity sha512-2AUg5v0liVBsqbGxBphbJ0QbGqSRVaF5qPoTPWcxop+66vMdU1h4CCvHxTC47+Qb+Pr4l2RhXDd41JNpwcQEKw==
+"@typescript-eslint/typescript-estree@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz#8b3b08f85f18a8da5d88f65cb400f013e88ab7be"
+  integrity sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA==
   dependencies:
-    "@typescript-eslint/types" "4.1.1"
-    "@typescript-eslint/visitor-keys" "4.1.1"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/visitor-keys" "4.20.0"
     debug "^4.1.1"
     globby "^11.0.1"
     is-glob "^4.0.1"
-    lodash "^4.17.15"
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/visitor-keys@4.1.1":
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.1.tgz#bb05664bf4bea28dc120d1da94f3027d42ab0f6f"
-  integrity sha512-/EOOXbA2ferGLG6RmCHEQ0lTTLkOlXYDgblCmQk3tIU7mTPLm4gKhFMeeUSe+bcchTUsKeCk8xcpbop5Zr/8Rw==
+"@typescript-eslint/visitor-keys@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz#1e84db034da13f208325e6bfc995c3b75f7dbd62"
+  integrity sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A==
   dependencies:
-    "@typescript-eslint/types" "4.1.1"
+    "@typescript-eslint/types" "4.20.0"
     eslint-visitor-keys "^2.0.0"
 
 "@webassemblyjs/ast@1.8.5":
@@ -2393,7 +2190,12 @@
   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
   integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
 
-ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.11.0, ajv@^6.12.2, ajv@^6.5.5:
+ajv-keywords@^3.5.2:
+  version "3.5.2"
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
+  integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+
+ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.11.0, ajv@^6.5.5:
   version "6.12.3"
   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
   integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
@@ -2403,6 +2205,16 @@
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
+ajv@^6.12.5:
+  version "6.12.6"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+  integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+  dependencies:
+    fast-deep-equal "^3.1.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
+
 ansi-colors@4.1.1, ansi-colors@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
@@ -2669,11 +2481,6 @@
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
   integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
 
-async-array-reduce@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/async-array-reduce/-/async-array-reduce-0.2.1.tgz#c8be010a2b5cd00dea96c81116034693dfdd82d1"
-  integrity sha1-yL4BCitc0A3qlsgRFgNGk9/dgtE=
-
 async-each@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
@@ -2696,6 +2503,11 @@
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
   integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
 
+at-least-node@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
+  integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
+
 atob-lite@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
@@ -2762,6 +2574,30 @@
     reselect "^4.0.0"
     resolve "^1.13.1"
 
+babel-plugin-polyfill-corejs2@^0.1.4:
+  version "0.1.10"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz#a2c5c245f56c0cac3dbddbf0726a46b24f0f81d1"
+  integrity sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA==
+  dependencies:
+    "@babel/compat-data" "^7.13.0"
+    "@babel/helper-define-polyfill-provider" "^0.1.5"
+    semver "^6.1.1"
+
+babel-plugin-polyfill-corejs3@^0.1.3:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0"
+  integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==
+  dependencies:
+    "@babel/helper-define-polyfill-provider" "^0.1.5"
+    core-js-compat "^3.8.1"
+
+babel-plugin-polyfill-regenerator@^0.1.2:
+  version "0.1.6"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz#0fe06a026fe0faa628ccc8ba3302da0a6ce02f3f"
+  integrity sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg==
+  dependencies:
+    "@babel/helper-define-polyfill-provider" "^0.1.5"
+
 babel-plugin-preserve-comment-header@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-preserve-comment-header/-/babel-plugin-preserve-comment-header-1.0.1.tgz#7181cba65c507914d45eaefc372eb659b3f16996"
@@ -2972,16 +2808,16 @@
   dependencies:
     pako "~1.0.5"
 
-browserslist@^4.14.5, browserslist@^4.16.0:
-  version "4.16.1"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
-  integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
+browserslist@^4.14.5, browserslist@^4.16.3:
+  version "4.16.3"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717"
+  integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==
   dependencies:
-    caniuse-lite "^1.0.30001173"
+    caniuse-lite "^1.0.30001181"
     colorette "^1.2.1"
-    electron-to-chromium "^1.3.634"
+    electron-to-chromium "^1.3.649"
     escalade "^3.1.1"
-    node-releases "^1.1.69"
+    node-releases "^1.1.70"
 
 btoa-lite@^1.0.0:
   version "1.0.0"
@@ -3149,15 +2985,10 @@
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
   integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
 
-camelcase@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e"
-  integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==
-
-caniuse-lite@^1.0.30001173:
-  version "1.0.30001178"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz#3ad813b2b2c7d585b0be0a2440e1e233c6eabdbc"
-  integrity sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ==
+caniuse-lite@^1.0.30001181:
+  version "1.0.30001205"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz#d79bf6a6fb13196b4bb46e5143a22ca0242e0ef8"
+  integrity sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==
 
 caseless@~0.12.0:
   version "0.12.0"
@@ -3414,6 +3245,11 @@
   resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
   integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
 
+colors@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
+  integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
+
 columnify@^1.5.4:
   version "1.5.4"
   resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
@@ -3686,12 +3522,12 @@
   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
   integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
 
-core-js-compat@^3.8.0:
-  version "3.8.2"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.2.tgz#3717f51f6c3d2ebba8cbf27619b57160029d1d4c"
-  integrity sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ==
+core-js-compat@^3.8.1, core-js-compat@^3.9.0:
+  version "3.10.0"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.0.tgz#3600dc72869673c110215ee7a005a8609dea0fe1"
+  integrity sha512-9yVewub2MXNYyGvuLnMHcN1k9RkvB7/ofktpeKTIaASyB88YYqGzUnu0ywMMhJrDHOMiTjSHWGzR+i7Wb9Z1kQ==
   dependencies:
-    browserslist "^4.16.0"
+    browserslist "^4.16.3"
     semver "7.0.0"
 
 core-js-pure@^3.0.0:
@@ -3800,30 +3636,6 @@
     randombytes "^2.0.0"
     randomfill "^1.0.3"
 
-css-loader@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.0.0.tgz#814434d4e1e2d5f430c70e85e78268db7f3cced1"
-  integrity sha512-/7d5slKnmY2S39FNifJ7JQ8MhcMM/rDIjAZ2Sc/Z8lnOWOmc10hijg28ovBtljY364pQaF01O2nj5AIBDnJ9vQ==
-  dependencies:
-    camelcase "^6.0.0"
-    cssesc "^3.0.0"
-    icss-utils "^4.1.1"
-    loader-utils "^2.0.0"
-    normalize-path "^3.0.0"
-    postcss "^7.0.32"
-    postcss-modules-extract-imports "^2.0.0"
-    postcss-modules-local-by-default "^3.0.3"
-    postcss-modules-scope "^2.2.0"
-    postcss-modules-values "^3.0.0"
-    postcss-value-parser "^4.1.0"
-    schema-utils "^2.7.0"
-    semver "^7.3.2"
-
-cssesc@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
-  integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
-
 cssom@^0.4.4:
   version "0.4.4"
   resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
@@ -4218,10 +4030,10 @@
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
   integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
 
-electron-to-chromium@^1.3.634:
-  version "1.3.641"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.641.tgz#03f14efd70a7971eff2efc947b3c1d0f717c82b9"
-  integrity sha512-b0DLhsHSHESC1I+Nx6n4w4Lr61chMd3m/av1rZQhS2IXTzaS5BMM5N+ldWdMIlni9CITMRM09m8He4+YV/92TA==
+electron-to-chromium@^1.3.649:
+  version "1.3.707"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz#71386d0ceca6727835c33ba31f507f6824d18c35"
+  integrity sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA==
 
 elegant-spinner@^1.0.1:
   version "1.0.1"
@@ -4259,6 +4071,7 @@
 emojis-list@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
+  integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
 
 encodeurl@~1.0.2:
   version "1.0.2"
@@ -4684,13 +4497,6 @@
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
-expand-tilde@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449"
-  integrity sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=
-  dependencies:
-    os-homedir "^1.0.1"
-
 expand-tilde@^2.0.0, expand-tilde@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
@@ -4875,11 +4681,12 @@
     flat-cache "^2.0.1"
 
 file-loader@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f"
+  version "6.2.0"
+  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
+  integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==
   dependencies:
     loader-utils "^2.0.0"
-    schema-utils "^2.6.5"
+    schema-utils "^3.0.0"
 
 file-uri-to-path@1.0.0:
   version "1.0.0"
@@ -5091,11 +4898,6 @@
   resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.2.0.tgz#e6aa06f240d6267f913cea422075ef88b63e7897"
   integrity sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==
 
-fs-exists-sync@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
-  integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=
-
 fs-extra@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -5105,6 +4907,16 @@
     jsonfile "^4.0.0"
     universalify "^0.1.0"
 
+fs-extra@^9.1.0:
+  version "9.1.0"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
+  integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
+  dependencies:
+    at-least-node "^1.0.0"
+    graceful-fs "^4.2.0"
+    jsonfile "^6.0.1"
+    universalify "^2.0.0"
+
 fs-minipass@^1.2.5:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
@@ -5179,10 +4991,10 @@
   resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
   integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==
 
-gensync@^1.0.0-beta.1:
-  version "1.0.0-beta.1"
-  resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
-  integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
+gensync@^1.0.0-beta.2:
+  version "1.0.0-beta.2"
+  resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
+  integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
 
 get-caller-file@^1.0.1:
   version "1.0.3"
@@ -5305,7 +5117,7 @@
   dependencies:
     ini "^1.3.2"
 
-glob-parent@^3.0.1, glob-parent@^3.1.0:
+glob-parent@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
   integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=
@@ -5313,14 +5125,7 @@
     is-glob "^3.1.0"
     path-dirname "^1.0.0"
 
-glob-parent@^5.0.0, glob-parent@~5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2"
-  integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==
-  dependencies:
-    is-glob "^4.0.1"
-
-glob-parent@^5.1.0:
+glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
   integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
@@ -5332,7 +5137,7 @@
   resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
   integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
 
-glob@7.1.6, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@7.1.6, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
   version "7.1.6"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
   integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
@@ -5344,10 +5149,10 @@
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-global-jsdom@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/global-jsdom/-/global-jsdom-6.1.0.tgz#a911ec57c51cf72e93a2ce97925a02a6427aed76"
-  integrity sha512-zaNNWr7hpov5SgF21fVtvnliRcRMYSZGc47nSipUOw5Ktft+2njD4hjzN1OXWQzlBFnRU/W+MBN6OvaPMTawKQ==
+global-jsdom@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/global-jsdom/-/global-jsdom-8.0.0.tgz#334501e24e24880c7687518826af0d38da6c2be5"
+  integrity sha512-fvOtNsQ4Ip1zkj7yZUzBhE/5pO8Iz6eb30niikooxjwQsQJS2XL6e8f0QlqfpJFBTfuM3dPK7XHUQmptjWJcuw==
 
 global-modules@2.0.0:
   version "2.0.0"
@@ -5356,14 +5161,6 @@
   dependencies:
     global-prefix "^3.0.0"
 
-global-modules@^0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d"
-  integrity sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=
-  dependencies:
-    global-prefix "^0.1.4"
-    is-windows "^0.2.0"
-
 global-modules@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
@@ -5373,16 +5170,6 @@
     is-windows "^1.0.1"
     resolve-dir "^1.0.0"
 
-global-prefix@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f"
-  integrity sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=
-  dependencies:
-    homedir-polyfill "^1.0.0"
-    ini "^1.3.4"
-    is-windows "^0.2.0"
-    which "^1.2.12"
-
 global-prefix@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
@@ -5467,14 +5254,15 @@
   resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
   integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
 
-handlebars@^4.1.2:
-  version "4.3.4"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.4.tgz#aab065294c27ad16ff4e711240a7288d2753306d"
-  integrity sha512-vvpo6mpK4ScNC1DbGRZ2d5BznS6ht0r1hi20RivsibMc6jNvFAeZQ6qk5VNspo6SOwVOJQbjHyBCpuS7BzA1pw==
+handlebars@^4.1.2, handlebars@^4.7.7:
+  version "4.7.7"
+  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
+  integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
   dependencies:
+    minimist "^1.2.5"
     neo-async "^2.6.0"
-    optimist "^0.6.1"
     source-map "^0.6.1"
+    wordwrap "^1.0.0"
   optionalDependencies:
     uglify-js "^3.1.4"
 
@@ -5508,13 +5296,6 @@
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-has-glob@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-0.1.1.tgz#a261c4c2a6c667e0c77b700a7f297c39ef3aa589"
-  integrity sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=
-  dependencies:
-    is-glob "^2.0.1"
-
 has-symbols@^1.0.0, has-symbols@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
@@ -5601,7 +5382,7 @@
     minimalistic-assert "^1.0.0"
     minimalistic-crypto-utils "^1.0.1"
 
-homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
+homedir-polyfill@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
   integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
@@ -5760,13 +5541,6 @@
   dependencies:
     safer-buffer ">= 2.1.2 < 3"
 
-icss-utils@^4.0.0, icss-utils@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
-  integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==
-  dependencies:
-    postcss "^7.0.14"
-
 ieee754@^1.1.4:
   version "1.1.13"
   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
@@ -5789,12 +5563,7 @@
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
   integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
 
-ignore@^5.1.1:
-  version "5.1.4"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
-  integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
-
-ignore@^5.1.4:
+ignore@^5.1.1, ignore@^5.1.4:
   version "5.1.8"
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
   integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
@@ -5845,11 +5614,6 @@
   resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
   integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
 
-indexes-of@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
-  integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
-
 infer-owner@^1.0.3, infer-owner@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
@@ -5919,7 +5683,7 @@
     default-gateway "^4.2.0"
     ipaddr.js "^1.9.0"
 
-interpret@1.2.0:
+interpret@1.2.0, interpret@^1.0.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
   integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
@@ -6009,6 +5773,13 @@
   dependencies:
     ci-info "^2.0.0"
 
+is-core-module@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
+  integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
+  dependencies:
+    has "^1.0.3"
+
 is-data-descriptor@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -6063,11 +5834,6 @@
   dependencies:
     is-plain-object "^2.0.4"
 
-is-extglob@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
-  integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=
-
 is-extglob@^2.1.0, is-extglob@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@@ -6097,13 +5863,6 @@
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
   integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
 
-is-glob@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
-  integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=
-  dependencies:
-    is-extglob "^1.0.0"
-
 is-glob@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
@@ -6258,16 +6017,6 @@
   resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
   integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
 
-is-valid-glob@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe"
-  integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=
-
-is-windows@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
-  integrity sha1-3hqm1j6indJIc3tp8f+LgALSEIw=
-
 is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -6508,6 +6257,15 @@
   optionalDependencies:
     graceful-fs "^4.1.6"
 
+jsonfile@^6.0.1:
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
+  integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
+  dependencies:
+    universalify "^2.0.0"
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
 jsonparse@^1.2.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@@ -6552,13 +6310,6 @@
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
   integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
 
-lazy-cache@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
-  integrity sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=
-  dependencies:
-    set-getter "^0.1.0"
-
 lcid@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
@@ -6721,7 +6472,7 @@
   resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
   integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
 
-loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3:
+loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
   integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
@@ -6733,6 +6484,7 @@
 loader-utils@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
+  integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
   dependencies:
     big.js "^5.2.2"
     emojis-list "^3.0.0"
@@ -6771,6 +6523,11 @@
   resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
   integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
 
+lodash.debounce@^4.0.8:
+  version "4.0.8"
+  resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
+  integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
+
 lodash.flattendeep@^4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
@@ -6816,10 +6573,10 @@
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.2.1:
-  version "4.17.20"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
-  integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
+lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.2.1:
+  version "4.17.21"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 
 log-symbols@3.0.0, log-symbols@^3.0.0:
   version "3.0.0"
@@ -6864,6 +6621,11 @@
   dependencies:
     yallist "^3.0.2"
 
+lunr@^2.3.9:
+  version "2.3.9"
+  resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
+  integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
+
 macos-release@^2.2.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
@@ -6942,20 +6704,10 @@
   dependencies:
     object-visit "^1.0.0"
 
-matched@^0.4.4:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/matched/-/matched-0.4.4.tgz#56d7b7eb18033f0cf9bc52eb2090fac7dc1e89fa"
-  integrity sha1-Vte36xgDPwz5vFLrIJD6x9weifo=
-  dependencies:
-    arr-union "^3.1.0"
-    async-array-reduce "^0.2.0"
-    extend-shallow "^2.0.1"
-    fs-exists-sync "^0.1.0"
-    glob "^7.0.5"
-    has-glob "^0.1.1"
-    is-valid-glob "^0.3.0"
-    lazy-cache "^2.0.1"
-    resolve-dir "^0.1.0"
+marked@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.1.tgz#5e7ed7009bfa5c95182e4eb696f85e948cefcee3"
+  integrity sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==
 
 md5.js@^1.3.4:
   version "1.3.5"
@@ -7029,12 +6781,7 @@
   resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
   integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
 
-merge2@^1.2.3:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
-  integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
-
-merge2@^1.3.0:
+merge2@^1.2.3, merge2@^1.3.0:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
   integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
@@ -7121,7 +6868,7 @@
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
   integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
 
-minimatch@3.0.4, minimatch@^3.0.4:
+minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
   integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -7136,7 +6883,7 @@
     arrify "^1.0.1"
     is-plain-obj "^1.1.0"
 
-minimist@0.0.8, minimist@~0.0.1:
+minimist@0.0.8:
   version "0.0.8"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
   integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
@@ -7199,16 +6946,6 @@
   dependencies:
     minimist "0.0.8"
 
-mocha-loader@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/mocha-loader/-/mocha-loader-5.1.1.tgz#7348d33f25116fa1b9684679acbf062667b3b23c"
-  integrity sha512-WK3cgPf3N6ZZRuk7vUm4tt2BsuUMsjnbjpabNr32BMgEQyxcMxTD7jgbQdwIVZ99/YhHOhJmm5FRlEXu+/nLgA==
-  dependencies:
-    css-loader "^4.0.0"
-    loader-utils "^2.0.0"
-    schema-utils "^2.7.0"
-    style-loader "^1.2.1"
-
 mocha@^8.0.1:
   version "8.0.1"
   resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.0.1.tgz#fe01f0530362df271aa8f99510447bc38b88d8ed"
@@ -7272,15 +7009,6 @@
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
   integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
 
-multi-entry-loader@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/multi-entry-loader/-/multi-entry-loader-1.1.2.tgz#238085c85845726e50528955d19b04568fefcdb9"
-  integrity sha1-I4CFyFhFcm5QUolV0ZsEVo/vzbk=
-  dependencies:
-    glob-parent "^3.0.1"
-    loader-utils "^1.1.0"
-    matched "^0.4.4"
-
 multicast-dns-service-types@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
@@ -7437,10 +7165,10 @@
   dependencies:
     process-on-spawn "^1.0.0"
 
-node-releases@^1.1.69:
-  version "1.1.69"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6"
-  integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==
+node-releases@^1.1.70:
+  version "1.1.71"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
+  integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==
 
 "nopt@2 || 3":
   version "3.0.6"
@@ -7716,6 +7444,13 @@
   dependencies:
     mimic-fn "^2.1.0"
 
+onigasm@^2.2.5:
+  version "2.2.5"
+  resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892"
+  integrity sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==
+  dependencies:
+    lru-cache "^5.1.1"
+
 opencollective-postinstall@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89"
@@ -7728,13 +7463,10 @@
   dependencies:
     is-wsl "^1.1.0"
 
-optimist@^0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
-  integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
-  dependencies:
-    minimist "~0.0.1"
-    wordwrap "~0.0.2"
+optimal-select@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/optimal-select/-/optimal-select-4.0.1.tgz#47de7da7a39bb0949fd9af54c6f03571548f04c9"
+  integrity sha1-R959p6ObsJSf2a9UxvA1cVSPBMk=
 
 optionator@^0.8.1:
   version "0.8.3"
@@ -7772,7 +7504,7 @@
   resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
   integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
 
-os-homedir@^1.0.0, os-homedir@^1.0.1:
+os-homedir@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
   integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
@@ -8234,62 +7966,6 @@
   resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
   integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
 
-postcss-modules-extract-imports@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e"
-  integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==
-  dependencies:
-    postcss "^7.0.5"
-
-postcss-modules-local-by-default@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0"
-  integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==
-  dependencies:
-    icss-utils "^4.1.1"
-    postcss "^7.0.32"
-    postcss-selector-parser "^6.0.2"
-    postcss-value-parser "^4.1.0"
-
-postcss-modules-scope@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee"
-  integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==
-  dependencies:
-    postcss "^7.0.6"
-    postcss-selector-parser "^6.0.0"
-
-postcss-modules-values@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10"
-  integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==
-  dependencies:
-    icss-utils "^4.0.0"
-    postcss "^7.0.6"
-
-postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c"
-  integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==
-  dependencies:
-    cssesc "^3.0.0"
-    indexes-of "^1.0.1"
-    uniq "^1.0.1"
-
-postcss-value-parser@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
-  integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
-
-postcss@^7.0.14, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
-  version "7.0.32"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
-  integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
-  dependencies:
-    chalk "^2.4.2"
-    source-map "^0.6.1"
-    supports-color "^6.1.0"
-
 prelude-ls@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -8334,7 +8010,7 @@
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
   integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
 
-progress@^2.0.0:
+progress@^2.0.0, progress@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
   integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
@@ -8667,6 +8343,13 @@
   dependencies:
     picomatch "^2.2.1"
 
+rechoir@^0.6.2:
+  version "0.6.2"
+  resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+  integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
+  dependencies:
+    resolve "^1.1.6"
+
 redent@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
@@ -8728,18 +8411,6 @@
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
   integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
 
-regexpu-core@^4.7.0:
-  version "4.7.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938"
-  integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==
-  dependencies:
-    regenerate "^1.4.0"
-    regenerate-unicode-properties "^8.2.0"
-    regjsgen "^0.5.1"
-    regjsparser "^0.6.4"
-    unicode-match-property-ecmascript "^1.0.4"
-    unicode-match-property-value-ecmascript "^1.2.0"
-
 regexpu-core@^4.7.1:
   version "4.7.1"
   resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6"
@@ -8867,14 +8538,6 @@
   dependencies:
     resolve-from "^3.0.0"
 
-resolve-dir@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
-  integrity sha1-shklmlYC+sXFxJatiUpujMQwJh4=
-  dependencies:
-    expand-tilde "^1.2.2"
-    global-modules "^0.2.3"
-
 resolve-dir@^1.0.0, resolve-dir@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
@@ -8903,11 +8566,12 @@
   resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
   integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
 
-resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.15.0, resolve@^1.17.0, resolve@^1.3.2:
-  version "1.17.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
-  integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
+resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.0, resolve@^1.17.0:
+  version "1.20.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
+  integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
   dependencies:
+    is-core-module "^2.2.0"
     path-parse "^1.0.6"
 
 restore-cursor@^2.0.0:
@@ -9024,14 +8688,14 @@
     ajv-errors "^1.0.0"
     ajv-keywords "^3.1.0"
 
-schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
-  version "2.7.0"
-  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
-  integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
+schema-utils@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef"
+  integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==
   dependencies:
-    "@types/json-schema" "^7.0.4"
-    ajv "^6.12.2"
-    ajv-keywords "^3.4.1"
+    "@types/json-schema" "^7.0.6"
+    ajv "^6.12.5"
+    ajv-keywords "^3.5.2"
 
 select-hose@^2.0.0:
   version "2.0.0"
@@ -9065,7 +8729,7 @@
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
   integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
 
-semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0:
+semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
   version "6.3.0"
   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
   integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -9137,13 +8801,6 @@
   resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
   integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
 
-set-getter@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
-  integrity sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=
-  dependencies:
-    to-object-path "^0.3.0"
-
 set-value@^2.0.0, set-value@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@@ -9208,6 +8865,23 @@
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
   integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 
+shelljs@^0.8.4:
+  version "0.8.4"
+  resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
+  integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
+  dependencies:
+    glob "^7.0.0"
+    interpret "^1.0.0"
+    rechoir "^0.6.2"
+
+shiki@^0.9.3:
+  version "0.9.3"
+  resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.3.tgz#7bf7bcf3ed50ca525ec89cc09254abce4264d5ca"
+  integrity sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==
+  dependencies:
+    onigasm "^2.2.5"
+    vscode-textmate "^5.2.0"
+
 signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@@ -9686,14 +9360,6 @@
     minimist "^1.2.0"
     through "^2.3.4"
 
-style-loader@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a"
-  integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==
-  dependencies:
-    loader-utils "^2.0.0"
-    schema-utils "^2.6.6"
-
 supports-color@6.1.0, supports-color@^6.1.0:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
@@ -10057,10 +9723,32 @@
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@^3.9.7:
-  version "3.9.7"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
-  integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
+typedoc-default-themes@^0.12.9:
+  version "0.12.10"
+  resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843"
+  integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==
+
+typedoc@^0.20.5:
+  version "0.20.35"
+  resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.35.tgz#c36996098cbeb2ef63d9d7991262a071b98336a3"
+  integrity sha512-7sNca19LXg2hgyGHq3b33tQ1YFApmd8aBDEzWQ2ry4VDkw/NdFWkysGiGRY1QckDCB0gVH8+MlXA4K71IB3azg==
+  dependencies:
+    colors "^1.4.0"
+    fs-extra "^9.1.0"
+    handlebars "^4.7.7"
+    lodash "^4.17.21"
+    lunr "^2.3.9"
+    marked "^2.0.1"
+    minimatch "^3.0.0"
+    progress "^2.0.3"
+    shelljs "^0.8.4"
+    shiki "^0.9.3"
+    typedoc-default-themes "^0.12.9"
+
+typescript@^4.2.3:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
+  integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
 
 uglify-js@^3.1.4:
   version "3.6.0"
@@ -10113,11 +9801,6 @@
     is-extendable "^0.1.1"
     set-value "^2.0.1"
 
-uniq@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
-  integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
-
 unique-filename@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
@@ -10144,6 +9827,11 @@
   resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
   integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
 
+universalify@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
+  integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
+
 unpipe@1.0.0, unpipe@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -10270,6 +9958,11 @@
   resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
   integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
 
+vscode-textmate@^5.2.0:
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.4.0.tgz#4b25ffc1f14ac3a90faf9a388c67a01d24257cd7"
+  integrity sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w==
+
 w3c-hr-time@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
@@ -10492,7 +10185,7 @@
   resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
   integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
 
-which@1, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.1:
+which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
   integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -10525,10 +10218,10 @@
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
-wordwrap@~0.0.2:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
-  integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
+wordwrap@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+  integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
 
 worker-farm@^1.7.0:
   version "1.7.0"