Merge branch 'master' into feat-extension-type
diff --git a/.eslintrc-common.yaml b/.eslintrc-common.yaml
index 081c0bf..4ae0d21 100644
--- a/.eslintrc-common.yaml
+++ b/.eslintrc-common.yaml
@@ -163,7 +163,7 @@
         - 2
         - "never"
     space-unary-ops: 2
-    spaced-comment: 0
+    spaced-comment: "error"
 
     max-nested-callbacks:
         - 1
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 2c293e7..bcdea0e 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -26,5 +26,6 @@
           stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. If you wish not to mark it as stale, please leave a comment in this PR. We are sorry for this but 2 years is a long time and the code base has been changed a lot. Thanks for your contribution anyway.'
           close-pr-message: 'This PR has been automatically closed because it has not had recent activity. Sorry for that and we are looking forward to your next contribution.'
           exempt-issue-labels: 'FAQ,priority: high'
+          exempt-all-milestones: true
           operations-per-run: 500
           ascending: true
diff --git a/package-lock.json b/package-lock.json
index 004f091..bdc0335 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "2.3.0",
-        "zrender": "5.3.2"
+        "zrender": "npm:zrender-nightly@^5.3.3-dev.20220820"
       },
       "devDependencies": {
         "@babel/code-frame": "7.10.4",
@@ -19,7 +19,7 @@
         "@definitelytyped/typescript-versions": "0.0.64",
         "@definitelytyped/utils": "0.0.64",
         "@lang/rollup-plugin-dts": "2.0.2",
-        "@microsoft/api-extractor": "7.7.2",
+        "@microsoft/api-extractor": "7.31.2",
         "@rollup/plugin-commonjs": "^17.0.0",
         "@rollup/plugin-node-resolve": "^11.0.0",
         "@rollup/plugin-replace": "^2.3.4",
@@ -38,7 +38,7 @@
         "husky": "^4.2.5",
         "jest": "^26.6.1",
         "jest-canvas-mock": "^2.2.0",
-        "jshint": "2.10.2",
+        "jshint": "2.13.5",
         "magic-string": "^0.25.7",
         "open": "6.4.0",
         "pixelmatch": "5.0.2",
@@ -49,7 +49,7 @@
         "semver": "6.3.0",
         "serve-handler": "6.1.1",
         "slugify": "1.3.4",
-        "socket.io": "2.2.0",
+        "socket.io": "2.5.0",
         "terser": "^5.3.8",
         "ts-jest": "^26.4.3",
         "typescript": "4.4.3"
@@ -681,12 +681,6 @@
         "tar-stream": "^2.1.4"
       }
     },
-    "node_modules/@definitelytyped/utils/node_modules/@types/node": {
-      "version": "12.19.12",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz",
-      "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==",
-      "dev": true
-    },
     "node_modules/@definitelytyped/utils/node_modules/fs-extra": {
       "version": "8.1.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -1532,42 +1526,52 @@
       }
     },
     "node_modules/@microsoft/api-extractor": {
-      "version": "7.7.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.7.2.tgz",
-      "integrity": "sha512-W75kcjWlONyB9kQKYAfSMiG3v2JMGlgUihny8PucZqdRatcYADeQiEcX5qE5sWdNRHD/J+5INiwlooZDd82sDQ==",
+      "version": "7.31.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.31.2.tgz",
+      "integrity": "sha512-ZODCU9ckTS9brXiZpUW2iDrnAg7jLxeLBM1AkPpSZFcbG/8HGLvfKOKrd71VIJHjc52x2lB8xj7ZWksnP7AOBA==",
       "dev": true,
       "dependencies": {
-        "@microsoft/api-extractor-model": "7.7.2",
-        "@microsoft/node-core-library": "3.18.2",
-        "@microsoft/ts-command-line": "4.3.7",
-        "@microsoft/tsdoc": "0.12.14",
+        "@microsoft/api-extractor-model": "7.24.2",
+        "@microsoft/tsdoc": "0.14.1",
+        "@microsoft/tsdoc-config": "~0.16.1",
+        "@rushstack/node-core-library": "3.52.0",
+        "@rushstack/rig-package": "0.3.15",
+        "@rushstack/ts-command-line": "4.12.3",
         "colors": "~1.2.1",
         "lodash": "~4.17.15",
-        "resolve": "1.8.1",
+        "resolve": "~1.17.0",
+        "semver": "~7.3.0",
         "source-map": "~0.6.1",
-        "typescript": "~3.7.2"
+        "typescript": "~4.7.4"
       },
       "bin": {
         "api-extractor": "bin/api-extractor"
       }
     },
     "node_modules/@microsoft/api-extractor-model": {
-      "version": "7.7.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.7.2.tgz",
-      "integrity": "sha512-USwWUPV3YLS8ZOS11vFh3nzEWXC2d8OZJ6CGp0nRnCXtbqmKqAq4Jg9J5gs1PCemo7JQEbzbHGGwycC0DbRJqw==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.24.2.tgz",
+      "integrity": "sha512-uUvjqTCY7hYERWGks+joTioN1QYHIucCDy7I/JqLxFxLbFXE5dpc1X7L+FG4PN/s8QYL24DKt0fqJkgcrFKLTw==",
       "dev": true,
       "dependencies": {
-        "@microsoft/node-core-library": "3.18.2",
-        "@microsoft/tsdoc": "0.12.14"
+        "@microsoft/tsdoc": "0.14.1",
+        "@microsoft/tsdoc-config": "~0.16.1",
+        "@rushstack/node-core-library": "3.52.0"
       }
     },
-    "node_modules/@microsoft/api-extractor/node_modules/resolve": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
-      "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+    "node_modules/@microsoft/api-extractor/node_modules/semver": {
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dev": true,
       "dependencies": {
-        "path-parse": "^1.0.5"
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/@microsoft/api-extractor/node_modules/source-map": {
@@ -1580,9 +1584,9 @@
       }
     },
     "node_modules/@microsoft/api-extractor/node_modules/typescript": {
-      "version": "3.7.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
-      "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
+      "version": "4.7.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+      "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -1592,61 +1596,43 @@
         "node": ">=4.2.0"
       }
     },
-    "node_modules/@microsoft/node-core-library": {
-      "version": "3.18.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/node-core-library/-/node-core-library-3.18.2.tgz",
-      "integrity": "sha512-IRoRmLwNvrR0rTNavYlfNObz9pr4Epo8Hd//0SNptt7adOySd735ur7YBO7SzafeijHsD3/dC4PXLLwhIsMU7Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "8.10.54",
-        "colors": "~1.2.1",
-        "fs-extra": "~7.0.1",
-        "jju": "~1.4.0",
-        "semver": "~5.3.0",
-        "timsort": "~0.3.0",
-        "z-schema": "~3.18.3"
-      }
-    },
-    "node_modules/@microsoft/node-core-library/node_modules/fs-extra": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
-      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/@microsoft/node-core-library/node_modules/semver": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
-      "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/@microsoft/ts-command-line": {
-      "version": "4.3.7",
-      "resolved": "https://registry.npmjs.org/@microsoft/ts-command-line/-/ts-command-line-4.3.7.tgz",
-      "integrity": "sha512-dl7j5E4Ly4vin0dFRNyDEmslpqLTeFkSvWi1Ux2OhTXbORpaRm2qivTQzUgbPSh8Mtc1LSZGekqEMNl0e0OMNw==",
-      "dev": true,
-      "dependencies": {
-        "@types/argparse": "1.0.33",
-        "argparse": "~1.0.9",
-        "colors": "~1.2.1"
-      }
-    },
     "node_modules/@microsoft/tsdoc": {
-      "version": "0.12.14",
-      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.14.tgz",
-      "integrity": "sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q==",
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz",
+      "integrity": "sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw==",
       "dev": true
     },
+    "node_modules/@microsoft/tsdoc-config": {
+      "version": "0.16.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
+      "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
+      "dev": true,
+      "dependencies": {
+        "@microsoft/tsdoc": "0.14.2",
+        "ajv": "~6.12.6",
+        "jju": "~1.4.0",
+        "resolve": "~1.19.0"
+      }
+    },
+    "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
+      "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
+      "dev": true
+    },
+    "node_modules/@microsoft/tsdoc-config/node_modules/resolve": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.1.0",
+        "path-parse": "^1.0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@@ -1749,15 +1735,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/@rollup/plugin-node-resolve/node_modules/is-core-module": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-      "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
-      "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      }
-    },
     "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": {
       "version": "1.19.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
@@ -1804,6 +1781,94 @@
       "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
       "dev": true
     },
+    "node_modules/@rushstack/node-core-library": {
+      "version": "3.52.0",
+      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.52.0.tgz",
+      "integrity": "sha512-Z+MAP//G3rEGZd3JxJcBGcPYJlh8pvPoLMTLa5Sy6FTE6hRPzN+5J8DT7BbTmlqZaL6SZpXF30heRUbnYOvujw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "12.20.24",
+        "colors": "~1.2.1",
+        "fs-extra": "~7.0.1",
+        "import-lazy": "~4.0.0",
+        "jju": "~1.4.0",
+        "resolve": "~1.17.0",
+        "semver": "~7.3.0",
+        "z-schema": "~5.0.2"
+      }
+    },
+    "node_modules/@rushstack/node-core-library/node_modules/fs-extra": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/@rushstack/node-core-library/node_modules/import-lazy": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+      "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@rushstack/node-core-library/node_modules/semver": {
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@rushstack/rig-package": {
+      "version": "0.3.15",
+      "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.15.tgz",
+      "integrity": "sha512-jxVfvO5OnkRlYRhcVDZWvwiI2l4pv37HDJRtyg5HbD8Z/I8Xj32RICgrxS5xMeGGytobrg5S6OfPOHskg7Nw+A==",
+      "dev": true,
+      "dependencies": {
+        "resolve": "~1.17.0",
+        "strip-json-comments": "~3.1.1"
+      }
+    },
+    "node_modules/@rushstack/rig-package/node_modules/strip-json-comments": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@rushstack/ts-command-line": {
+      "version": "4.12.3",
+      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.12.3.tgz",
+      "integrity": "sha512-Pdij22RotMXzI+HWHyYCvw0RMZhiP5a6Za/96XamZ1+mxmpSm4ujf8TROKxGAHySmR5A8iNVSlzhNMnUlFQE6g==",
+      "dev": true,
+      "dependencies": {
+        "@types/argparse": "1.0.38",
+        "argparse": "~1.0.9",
+        "colors": "~1.2.1",
+        "string-argv": "~0.3.1"
+      }
+    },
     "node_modules/@sindresorhus/is": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@@ -1831,10 +1896,19 @@
         "@sinonjs/commons": "^1.7.0"
       }
     },
+    "node_modules/@tootallnate/once": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/@types/argparse": {
-      "version": "1.0.33",
-      "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.33.tgz",
-      "integrity": "sha512-VQgHxyPMTj3hIlq9SY1mctqx+Jj8kpQfoLvDlVSDNOyuYs8JYfkuY3OW/4+dO657yPmNhHpePRx0/Tje5ImNVQ==",
+      "version": "1.0.38",
+      "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
+      "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
       "dev": true
     },
     "node_modules/@types/babel__core": {
@@ -1934,9 +2008,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "8.10.54",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz",
-      "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==",
+      "version": "12.20.24",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz",
+      "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==",
       "dev": true
     },
     "node_modules/@types/normalize-package-data": {
@@ -2392,13 +2466,13 @@
       "dev": true
     },
     "node_modules/accepts": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
-      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
       "dev": true,
       "dependencies": {
-        "mime-types": "~2.1.24",
-        "negotiator": "0.6.2"
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
       },
       "engines": {
         "node": ">= 0.6"
@@ -2447,9 +2521,21 @@
     "node_modules/after": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
-      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+      "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==",
       "dev": true
     },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2646,12 +2732,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/async-limiter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
-      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
-      "dev": true
-    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -2894,7 +2974,7 @@
     "node_modules/backo2": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
-      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+      "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
       "dev": true
     },
     "node_modules/balanced-match": {
@@ -2972,9 +3052,9 @@
       }
     },
     "node_modules/base64-arraybuffer": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
-      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+      "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
       "dev": true,
       "engines": {
         "node": ">= 0.6.0"
@@ -2987,12 +3067,12 @@
       "dev": true
     },
     "node_modules/base64id": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
-      "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
       "dev": true,
       "engines": {
-        "node": ">= 0.4.0"
+        "node": "^4.5.0 || >= 5.9"
       }
     },
     "node_modules/bcrypt-pbkdf": {
@@ -3004,18 +3084,6 @@
         "tweetnacl": "^0.14.3"
       }
     },
-    "node_modules/better-assert": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
-      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
-      "dev": true,
-      "dependencies": {
-        "callsite": "1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
     "node_modules/bin-build": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz",
@@ -3614,15 +3682,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/callsite": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
-      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -4000,7 +4059,7 @@
     "node_modules/component-bind": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
-      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+      "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==",
       "dev": true
     },
     "node_modules/component-emitter": {
@@ -4012,7 +4071,7 @@
     "node_modules/component-inherit": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
-      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+      "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==",
       "dev": true
     },
     "node_modules/concat-map": {
@@ -4081,9 +4140,9 @@
       }
     },
     "node_modules/cookie": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
-      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
@@ -4804,12 +4863,6 @@
         "node": ">=6 <7 || >=8"
       }
     },
-    "node_modules/dtslint/node_modules/@types/node": {
-      "version": "12.19.12",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz",
-      "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==",
-      "dev": true
-    },
     "node_modules/dtslint/node_modules/fs-extra": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
@@ -4880,44 +4933,41 @@
       }
     },
     "node_modules/engine.io": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz",
-      "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.0.tgz",
+      "integrity": "sha512-Kc8fo5bbg8F4a2f3HPHTEpGyq/IRIQpyeHu3H1ThR14XDD7VrLcsGBo16HUpahgp8YkHJDaU5gNxJZbuGcuueg==",
       "dev": true,
       "dependencies": {
         "accepts": "~1.3.4",
-        "base64id": "1.0.0",
-        "cookie": "0.3.1",
-        "debug": "~3.1.0",
-        "engine.io-parser": "~2.1.0",
-        "ws": "~6.1.0"
+        "base64id": "2.0.0",
+        "cookie": "~0.4.1",
+        "debug": "~4.1.0",
+        "engine.io-parser": "~2.2.0",
+        "ws": "~7.4.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
       }
     },
     "node_modules/engine.io-client": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.3.tgz",
-      "integrity": "sha512-PXIgpzb1brtBzh8Q6vCjzCMeu4nfEPmaDm+L3Qb2sVHwLkxC1qRiBMSjOB0NJNjZ0hbPNUKQa+s8J2XxLOIEeQ==",
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.2.tgz",
+      "integrity": "sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA==",
       "dev": true,
       "dependencies": {
-        "component-emitter": "1.2.1",
+        "component-emitter": "~1.3.0",
         "component-inherit": "0.0.3",
         "debug": "~3.1.0",
-        "engine.io-parser": "~2.1.1",
+        "engine.io-parser": "~2.2.0",
         "has-cors": "1.1.0",
         "indexof": "0.0.1",
-        "parseqs": "0.0.5",
-        "parseuri": "0.0.5",
-        "ws": "~6.1.0",
-        "xmlhttprequest-ssl": "~1.6.3",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "ws": "~7.4.2",
+        "xmlhttprequest-ssl": "~1.6.2",
         "yeast": "0.1.2"
       }
     },
-    "node_modules/engine.io-client/node_modules/component-emitter": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
-      "dev": true
-    },
     "node_modules/engine.io-client/node_modules/debug": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -4930,53 +4980,72 @@
     "node_modules/engine.io-client/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "dev": true
     },
     "node_modules/engine.io-client/node_modules/ws": {
-      "version": "6.1.4",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
-      "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+      "version": "7.4.6",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
       "dev": true,
-      "dependencies": {
-        "async-limiter": "~1.0.0"
+      "engines": {
+        "node": ">=8.3.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
       }
     },
     "node_modules/engine.io-parser": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
-      "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
+      "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
       "dev": true,
       "dependencies": {
         "after": "0.8.2",
         "arraybuffer.slice": "~0.0.7",
-        "base64-arraybuffer": "0.1.5",
+        "base64-arraybuffer": "0.1.4",
         "blob": "0.0.5",
         "has-binary2": "~1.0.2"
       }
     },
     "node_modules/engine.io/node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
       "dev": true,
       "dependencies": {
-        "ms": "2.0.0"
+        "ms": "^2.1.1"
       }
     },
-    "node_modules/engine.io/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
     "node_modules/engine.io/node_modules/ws": {
-      "version": "6.1.4",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
-      "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+      "version": "7.4.6",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
       "dev": true,
-      "dependencies": {
-        "async-limiter": "~1.0.0"
+      "engines": {
+        "node": ">=8.3.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
       }
     },
     "node_modules/enquirer": {
@@ -5026,13 +5095,13 @@
       }
     },
     "node_modules/escodegen": {
-      "version": "1.14.3",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
-      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+      "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
       "dev": true,
       "dependencies": {
         "esprima": "^4.0.1",
-        "estraverse": "^4.2.0",
+        "estraverse": "^5.2.0",
         "esutils": "^2.0.2",
         "optionator": "^0.8.1"
       },
@@ -5041,12 +5110,21 @@
         "esgenerate": "bin/esgenerate.js"
       },
       "engines": {
-        "node": ">=4.0"
+        "node": ">=6.0"
       },
       "optionalDependencies": {
         "source-map": "~0.6.1"
       }
     },
+    "node_modules/escodegen/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/escodegen/node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -6404,13 +6482,13 @@
     "node_modules/has-binary2/node_modules/isarray": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-      "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+      "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
       "dev": true
     },
     "node_modules/has-cors": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
-      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+      "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==",
       "dev": true
     },
     "node_modules/has-flag": {
@@ -6580,6 +6658,20 @@
       "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
       "dev": true
     },
+    "node_modules/http-proxy-agent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+      "dev": true,
+      "dependencies": {
+        "@tootallnate/once": "1",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/http-signature": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -6595,6 +6687,19 @@
         "npm": ">=1.3.7"
       }
     },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "dev": true,
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/human-signals": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@@ -6875,7 +6980,7 @@
     "node_modules/indexof": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==",
       "dev": true
     },
     "node_modules/inflight": {
@@ -6913,15 +7018,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/ip-regex": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
-      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -6971,12 +7067,15 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz",
-      "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
       "dev": true,
       "dependencies": {
         "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/is-data-descriptor": {
@@ -7140,9 +7239,9 @@
       }
     },
     "node_modules/is-potential-custom-element-name": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
-      "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
       "dev": true
     },
     "node_modules/is-reference": {
@@ -7910,75 +8009,6 @@
         "node": ">= 10.14.2"
       }
     },
-    "node_modules/jest-environment-jsdom/node_modules/jsdom": {
-      "version": "16.4.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz",
-      "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==",
-      "dev": true,
-      "dependencies": {
-        "abab": "^2.0.3",
-        "acorn": "^7.1.1",
-        "acorn-globals": "^6.0.0",
-        "cssom": "^0.4.4",
-        "cssstyle": "^2.2.0",
-        "data-urls": "^2.0.0",
-        "decimal.js": "^10.2.0",
-        "domexception": "^2.0.1",
-        "escodegen": "^1.14.1",
-        "html-encoding-sniffer": "^2.0.1",
-        "is-potential-custom-element-name": "^1.0.0",
-        "nwsapi": "^2.2.0",
-        "parse5": "5.1.1",
-        "request": "^2.88.2",
-        "request-promise-native": "^1.0.8",
-        "saxes": "^5.0.0",
-        "symbol-tree": "^3.2.4",
-        "tough-cookie": "^3.0.1",
-        "w3c-hr-time": "^1.0.2",
-        "w3c-xmlserializer": "^2.0.0",
-        "webidl-conversions": "^6.1.0",
-        "whatwg-encoding": "^1.0.5",
-        "whatwg-mimetype": "^2.3.0",
-        "whatwg-url": "^8.0.0",
-        "ws": "^7.2.3",
-        "xml-name-validator": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "canvas": "^2.5.0"
-      },
-      "peerDependenciesMeta": {
-        "canvas": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/jest-environment-jsdom/node_modules/saxes": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
-      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
-      "dev": true,
-      "dependencies": {
-        "xmlchars": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
-      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
-      "dev": true,
-      "dependencies": {
-        "xml-name-validator": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/jest-environment-node": {
       "version": "26.6.1",
       "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.1.tgz",
@@ -9182,7 +9212,7 @@
     "node_modules/jju": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
-      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
+      "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
       "dev": true
     },
     "node_modules/js-tokens": {
@@ -9210,6 +9240,78 @@
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "dev": true
     },
+    "node_modules/jsdom": {
+      "version": "16.7.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+      "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
+      "dev": true,
+      "dependencies": {
+        "abab": "^2.0.5",
+        "acorn": "^8.2.4",
+        "acorn-globals": "^6.0.0",
+        "cssom": "^0.4.4",
+        "cssstyle": "^2.3.0",
+        "data-urls": "^2.0.0",
+        "decimal.js": "^10.2.1",
+        "domexception": "^2.0.1",
+        "escodegen": "^2.0.0",
+        "form-data": "^3.0.0",
+        "html-encoding-sniffer": "^2.0.1",
+        "http-proxy-agent": "^4.0.1",
+        "https-proxy-agent": "^5.0.0",
+        "is-potential-custom-element-name": "^1.0.1",
+        "nwsapi": "^2.2.0",
+        "parse5": "6.0.1",
+        "saxes": "^5.0.1",
+        "symbol-tree": "^3.2.4",
+        "tough-cookie": "^4.0.0",
+        "w3c-hr-time": "^1.0.2",
+        "w3c-xmlserializer": "^2.0.0",
+        "webidl-conversions": "^6.1.0",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.5.0",
+        "ws": "^7.4.6",
+        "xml-name-validator": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "canvas": "^2.5.0"
+      },
+      "peerDependenciesMeta": {
+        "canvas": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/jsdom/node_modules/acorn": {
+      "version": "8.7.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/jsdom/node_modules/form-data": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -9223,18 +9325,17 @@
       }
     },
     "node_modules/jshint": {
-      "version": "2.10.2",
-      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.2.tgz",
-      "integrity": "sha512-e7KZgCSXMJxznE/4WULzybCMNXNAd/bf5TSrvVEq78Q/K8ZwFpmBqQeDtNiHc3l49nV4E/+YeHU/JZjSUIrLAA==",
+      "version": "2.13.5",
+      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.5.tgz",
+      "integrity": "sha512-dB2n1w3OaQ35PLcBGIWXlszjbPZwsgZoxsg6G8PtNf2cFMC1l0fObkYLUuXqTTdi6tKw4sAjfUseTdmDMHQRcg==",
       "dev": true,
       "dependencies": {
         "cli": "~1.0.0",
         "console-browserify": "1.1.x",
         "exit": "0.1.x",
         "htmlparser2": "3.8.x",
-        "lodash": "~4.17.11",
+        "lodash": "~4.17.21",
         "minimatch": "~3.0.2",
-        "shelljs": "0.3.x",
         "strip-json-comments": "1.0.x"
       },
       "bin": {
@@ -9385,7 +9486,7 @@
     "node_modules/levn": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
       "dev": true,
       "dependencies": {
         "prelude-ls": "~1.1.2",
@@ -9422,13 +9523,13 @@
     "node_modules/lodash.get": {
       "version": "4.4.2",
       "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
       "dev": true
     },
     "node_modules/lodash.isequal": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
       "dev": true
     },
     "node_modules/lodash.memoize": {
@@ -9437,12 +9538,6 @@
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
       "dev": true
     },
-    "node_modules/lodash.sortby": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
-      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
-      "dev": true
-    },
     "node_modules/lowercase-keys": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
@@ -9556,21 +9651,21 @@
       }
     },
     "node_modules/mime-db": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
-      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
     },
     "node_modules/mime-types": {
-      "version": "2.1.27",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
-      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
       "dev": true,
       "dependencies": {
-        "mime-db": "1.44.0"
+        "mime-db": "1.52.0"
       },
       "engines": {
         "node": ">= 0.6"
@@ -9681,9 +9776,9 @@
       "dev": true
     },
     "node_modules/negotiator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
-      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
@@ -9965,12 +10060,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/object-component": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
-      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
-      "dev": true
-    },
     "node_modules/object-copy": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
@@ -10262,28 +10351,22 @@
       }
     },
     "node_modules/parse5": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
-      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
       "dev": true
     },
     "node_modules/parseqs": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
-      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
-      "dev": true,
-      "dependencies": {
-        "better-assert": "~1.0.0"
-      }
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
+      "dev": true
     },
     "node_modules/parseuri": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
-      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
-      "dev": true,
-      "dependencies": {
-        "better-assert": "~1.0.0"
-      }
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
+      "dev": true
     },
     "node_modules/parsimmon": {
       "version": "1.16.0",
@@ -10471,7 +10554,7 @@
     "node_modules/prelude-ls": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
       "dev": true,
       "engines": {
         "node": ">= 0.8.0"
@@ -10783,52 +10866,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/request-promise-core": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
-      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.19"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      },
-      "peerDependencies": {
-        "request": "^2.34"
-      }
-    },
-    "node_modules/request-promise-native": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
-      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
-      "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
-      "dev": true,
-      "dependencies": {
-        "request-promise-core": "1.1.4",
-        "stealthy-require": "^1.1.1",
-        "tough-cookie": "^2.3.3"
-      },
-      "engines": {
-        "node": ">=0.12.0"
-      },
-      "peerDependencies": {
-        "request": "^2.34"
-      }
-    },
-    "node_modules/request-promise-native/node_modules/tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/request/node_modules/tough-cookie": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -11221,6 +11258,18 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/saxes": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+      "dev": true,
+      "dependencies": {
+        "xmlchars": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/seedrandom": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.3.tgz",
@@ -11385,18 +11434,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/shelljs": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
-      "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
-      "dev": true,
-      "bin": {
-        "shjs": "bin/shjs"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
     "node_modules/shellwords": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
@@ -11643,17 +11680,17 @@
       "dev": true
     },
     "node_modules/socket.io": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz",
-      "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.0.tgz",
+      "integrity": "sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==",
       "dev": true,
       "dependencies": {
         "debug": "~4.1.0",
-        "engine.io": "~3.3.1",
+        "engine.io": "~3.6.0",
         "has-binary2": "~1.0.2",
         "socket.io-adapter": "~1.1.0",
-        "socket.io-client": "2.2.0",
-        "socket.io-parser": "~3.3.0"
+        "socket.io-client": "2.5.0",
+        "socket.io-parser": "~3.4.0"
       }
     },
     "node_modules/socket.io-adapter": {
@@ -11663,33 +11700,24 @@
       "dev": true
     },
     "node_modules/socket.io-client": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz",
-      "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
+      "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
       "dev": true,
       "dependencies": {
         "backo2": "1.0.2",
-        "base64-arraybuffer": "0.1.5",
         "component-bind": "1.0.0",
-        "component-emitter": "1.2.1",
+        "component-emitter": "~1.3.0",
         "debug": "~3.1.0",
-        "engine.io-client": "~3.3.1",
+        "engine.io-client": "~3.5.0",
         "has-binary2": "~1.0.2",
-        "has-cors": "1.1.0",
         "indexof": "0.0.1",
-        "object-component": "0.0.3",
-        "parseqs": "0.0.5",
-        "parseuri": "0.0.5",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
         "socket.io-parser": "~3.3.0",
         "to-array": "0.1.4"
       }
     },
-    "node_modules/socket.io-client/node_modules/component-emitter": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
-      "dev": true
-    },
     "node_modules/socket.io-client/node_modules/debug": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -11699,13 +11727,19 @@
         "ms": "2.0.0"
       }
     },
+    "node_modules/socket.io-client/node_modules/isarray": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+      "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
+      "dev": true
+    },
     "node_modules/socket.io-client/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "dev": true
     },
-    "node_modules/socket.io-parser": {
+    "node_modules/socket.io-client/node_modules/socket.io-parser": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
       "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
@@ -11716,25 +11750,37 @@
         "isarray": "2.0.1"
       }
     },
-    "node_modules/socket.io-parser/node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+    "node_modules/socket.io-parser": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
+      "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
       "dev": true,
       "dependencies": {
-        "ms": "2.0.0"
+        "component-emitter": "1.2.1",
+        "debug": "~4.1.0",
+        "isarray": "2.0.1"
+      }
+    },
+    "node_modules/socket.io-parser/node_modules/component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==",
+      "dev": true
+    },
+    "node_modules/socket.io-parser/node_modules/debug": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
       }
     },
     "node_modules/socket.io-parser/node_modules/isarray": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-      "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
-      "dev": true
-    },
-    "node_modules/socket.io-parser/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
       "dev": true
     },
     "node_modules/socket.io/node_modules/debug": {
@@ -11956,15 +12002,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/stealthy-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -11983,6 +12020,15 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "node_modules/string-argv": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6.19"
+      }
+    },
     "node_modules/string-length": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz",
@@ -12432,12 +12478,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/timsort": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
-      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
-      "dev": true
-    },
     "node_modules/tmpl": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@@ -12447,7 +12487,7 @@
     "node_modules/to-array": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
-      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+      "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==",
       "dev": true
     },
     "node_modules/to-buffer": {
@@ -12517,23 +12557,23 @@
       }
     },
     "node_modules/tough-cookie": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
-      "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+      "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
       "dev": true,
       "dependencies": {
-        "ip-regex": "^2.1.0",
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
+        "psl": "^1.1.33",
+        "punycode": "^2.1.1",
+        "universalify": "^0.1.2"
       },
       "engines": {
         "node": ">=6"
       }
     },
     "node_modules/tr46": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
-      "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
       "dev": true,
       "dependencies": {
         "punycode": "^2.1.1"
@@ -12758,7 +12798,7 @@
     "node_modules/type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
       "dev": true,
       "dependencies": {
         "prelude-ls": "~1.1.2"
@@ -13006,9 +13046,9 @@
       }
     },
     "node_modules/validator": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
-      "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==",
+      "version": "13.7.0",
+      "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
+      "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
       "dev": true,
       "engines": {
         "node": ">= 0.10"
@@ -13037,6 +13077,18 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "node_modules/w3c-xmlserializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+      "dev": true,
+      "dependencies": {
+        "xml-name-validator": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/walker": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
@@ -13071,13 +13123,13 @@
       "dev": true
     },
     "node_modules/whatwg-url": {
-      "version": "8.4.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz",
-      "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==",
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+      "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
       "dev": true,
       "dependencies": {
-        "lodash.sortby": "^4.7.0",
-        "tr46": "^2.0.2",
+        "lodash": "^4.7.0",
+        "tr46": "^2.1.0",
         "webidl-conversions": "^6.1.0"
       },
       "engines": {
@@ -13391,7 +13443,7 @@
     "node_modules/yeast": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
-      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+      "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==",
       "dev": true
     },
     "node_modules/yocto-queue": {
@@ -13407,26 +13459,37 @@
       }
     },
     "node_modules/z-schema": {
-      "version": "3.18.4",
-      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
-      "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.4.tgz",
+      "integrity": "sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==",
       "dev": true,
       "dependencies": {
-        "lodash.get": "^4.0.0",
-        "lodash.isequal": "^4.0.0",
-        "validator": "^8.0.0"
+        "lodash.get": "^4.4.2",
+        "lodash.isequal": "^4.5.0",
+        "validator": "^13.7.0"
       },
       "bin": {
         "z-schema": "bin/z-schema"
       },
+      "engines": {
+        "node": ">=8.0.0"
+      },
       "optionalDependencies": {
-        "commander": "^2.7.1"
+        "commander": "^2.20.3"
       }
     },
+    "node_modules/z-schema/node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true,
+      "optional": true
+    },
     "node_modules/zrender": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
-      "integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==",
+      "name": "zrender-nightly",
+      "version": "5.3.3-dev.20220820",
+      "resolved": "https://registry.npmjs.org/zrender-nightly/-/zrender-nightly-5.3.3-dev.20220820.tgz",
+      "integrity": "sha512-/4hBgw+X1EAZ+wE/4VYfOJEkOD+FWJ+GUEMYVNUoo8FWpU97avPhcTVMupP2w6qjuDY8178ivDs8PMBL7igdxQ==",
       "dependencies": {
         "tslib": "2.3.0"
       }
@@ -14015,12 +14078,6 @@
         "tar-stream": "^2.1.4"
       },
       "dependencies": {
-        "@types/node": {
-          "version": "12.19.12",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz",
-          "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==",
-          "dev": true
-        },
         "fs-extra": {
           "version": "8.1.0",
           "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -14702,29 +14759,32 @@
       }
     },
     "@microsoft/api-extractor": {
-      "version": "7.7.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.7.2.tgz",
-      "integrity": "sha512-W75kcjWlONyB9kQKYAfSMiG3v2JMGlgUihny8PucZqdRatcYADeQiEcX5qE5sWdNRHD/J+5INiwlooZDd82sDQ==",
+      "version": "7.31.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.31.2.tgz",
+      "integrity": "sha512-ZODCU9ckTS9brXiZpUW2iDrnAg7jLxeLBM1AkPpSZFcbG/8HGLvfKOKrd71VIJHjc52x2lB8xj7ZWksnP7AOBA==",
       "dev": true,
       "requires": {
-        "@microsoft/api-extractor-model": "7.7.2",
-        "@microsoft/node-core-library": "3.18.2",
-        "@microsoft/ts-command-line": "4.3.7",
-        "@microsoft/tsdoc": "0.12.14",
+        "@microsoft/api-extractor-model": "7.24.2",
+        "@microsoft/tsdoc": "0.14.1",
+        "@microsoft/tsdoc-config": "~0.16.1",
+        "@rushstack/node-core-library": "3.52.0",
+        "@rushstack/rig-package": "0.3.15",
+        "@rushstack/ts-command-line": "4.12.3",
         "colors": "~1.2.1",
         "lodash": "~4.17.15",
-        "resolve": "1.8.1",
+        "resolve": "~1.17.0",
+        "semver": "~7.3.0",
         "source-map": "~0.6.1",
-        "typescript": "~3.7.2"
+        "typescript": "~4.7.4"
       },
       "dependencies": {
-        "resolve": {
-          "version": "1.8.1",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
-          "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+        "semver": {
+          "version": "7.3.7",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.5"
+            "lru-cache": "^6.0.0"
           }
         },
         "source-map": {
@@ -14734,74 +14794,60 @@
           "dev": true
         },
         "typescript": {
-          "version": "3.7.5",
-          "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
-          "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
+          "version": "4.7.4",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+          "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
           "dev": true
         }
       }
     },
     "@microsoft/api-extractor-model": {
-      "version": "7.7.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.7.2.tgz",
-      "integrity": "sha512-USwWUPV3YLS8ZOS11vFh3nzEWXC2d8OZJ6CGp0nRnCXtbqmKqAq4Jg9J5gs1PCemo7JQEbzbHGGwycC0DbRJqw==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.24.2.tgz",
+      "integrity": "sha512-uUvjqTCY7hYERWGks+joTioN1QYHIucCDy7I/JqLxFxLbFXE5dpc1X7L+FG4PN/s8QYL24DKt0fqJkgcrFKLTw==",
       "dev": true,
       "requires": {
-        "@microsoft/node-core-library": "3.18.2",
-        "@microsoft/tsdoc": "0.12.14"
-      }
-    },
-    "@microsoft/node-core-library": {
-      "version": "3.18.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/node-core-library/-/node-core-library-3.18.2.tgz",
-      "integrity": "sha512-IRoRmLwNvrR0rTNavYlfNObz9pr4Epo8Hd//0SNptt7adOySd735ur7YBO7SzafeijHsD3/dC4PXLLwhIsMU7Q==",
-      "dev": true,
-      "requires": {
-        "@types/node": "8.10.54",
-        "colors": "~1.2.1",
-        "fs-extra": "~7.0.1",
-        "jju": "~1.4.0",
-        "semver": "~5.3.0",
-        "timsort": "~0.3.0",
-        "z-schema": "~3.18.3"
-      },
-      "dependencies": {
-        "fs-extra": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
-          "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "^4.1.2",
-            "jsonfile": "^4.0.0",
-            "universalify": "^0.1.0"
-          }
-        },
-        "semver": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
-          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
-          "dev": true
-        }
-      }
-    },
-    "@microsoft/ts-command-line": {
-      "version": "4.3.7",
-      "resolved": "https://registry.npmjs.org/@microsoft/ts-command-line/-/ts-command-line-4.3.7.tgz",
-      "integrity": "sha512-dl7j5E4Ly4vin0dFRNyDEmslpqLTeFkSvWi1Ux2OhTXbORpaRm2qivTQzUgbPSh8Mtc1LSZGekqEMNl0e0OMNw==",
-      "dev": true,
-      "requires": {
-        "@types/argparse": "1.0.33",
-        "argparse": "~1.0.9",
-        "colors": "~1.2.1"
+        "@microsoft/tsdoc": "0.14.1",
+        "@microsoft/tsdoc-config": "~0.16.1",
+        "@rushstack/node-core-library": "3.52.0"
       }
     },
     "@microsoft/tsdoc": {
-      "version": "0.12.14",
-      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.14.tgz",
-      "integrity": "sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q==",
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz",
+      "integrity": "sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw==",
       "dev": true
     },
+    "@microsoft/tsdoc-config": {
+      "version": "0.16.2",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
+      "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
+      "dev": true,
+      "requires": {
+        "@microsoft/tsdoc": "0.14.2",
+        "ajv": "~6.12.6",
+        "jju": "~1.4.0",
+        "resolve": "~1.19.0"
+      },
+      "dependencies": {
+        "@microsoft/tsdoc": {
+          "version": "0.14.2",
+          "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
+          "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
+          "dev": true
+        },
+        "resolve": {
+          "version": "1.19.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+          "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+          "dev": true,
+          "requires": {
+            "is-core-module": "^2.1.0",
+            "path-parse": "^1.0.6"
+          }
+        }
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@@ -14879,15 +14925,6 @@
           "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
           "dev": true
         },
-        "is-core-module": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-          "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
-          "dev": true,
-          "requires": {
-            "has": "^1.0.3"
-          }
-        },
         "resolve": {
           "version": "1.19.0",
           "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
@@ -14929,6 +14966,80 @@
         }
       }
     },
+    "@rushstack/node-core-library": {
+      "version": "3.52.0",
+      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.52.0.tgz",
+      "integrity": "sha512-Z+MAP//G3rEGZd3JxJcBGcPYJlh8pvPoLMTLa5Sy6FTE6hRPzN+5J8DT7BbTmlqZaL6SZpXF30heRUbnYOvujw==",
+      "dev": true,
+      "requires": {
+        "@types/node": "12.20.24",
+        "colors": "~1.2.1",
+        "fs-extra": "~7.0.1",
+        "import-lazy": "~4.0.0",
+        "jju": "~1.4.0",
+        "resolve": "~1.17.0",
+        "semver": "~7.3.0",
+        "z-schema": "~5.0.2"
+      },
+      "dependencies": {
+        "fs-extra": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+          "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "jsonfile": "^4.0.0",
+            "universalify": "^0.1.0"
+          }
+        },
+        "import-lazy": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+          "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+          "dev": true
+        },
+        "semver": {
+          "version": "7.3.7",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        }
+      }
+    },
+    "@rushstack/rig-package": {
+      "version": "0.3.15",
+      "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.15.tgz",
+      "integrity": "sha512-jxVfvO5OnkRlYRhcVDZWvwiI2l4pv37HDJRtyg5HbD8Z/I8Xj32RICgrxS5xMeGGytobrg5S6OfPOHskg7Nw+A==",
+      "dev": true,
+      "requires": {
+        "resolve": "~1.17.0",
+        "strip-json-comments": "~3.1.1"
+      },
+      "dependencies": {
+        "strip-json-comments": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+          "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+          "dev": true
+        }
+      }
+    },
+    "@rushstack/ts-command-line": {
+      "version": "4.12.3",
+      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.12.3.tgz",
+      "integrity": "sha512-Pdij22RotMXzI+HWHyYCvw0RMZhiP5a6Za/96XamZ1+mxmpSm4ujf8TROKxGAHySmR5A8iNVSlzhNMnUlFQE6g==",
+      "dev": true,
+      "requires": {
+        "@types/argparse": "1.0.38",
+        "argparse": "~1.0.9",
+        "colors": "~1.2.1",
+        "string-argv": "~0.3.1"
+      }
+    },
     "@sindresorhus/is": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@@ -14953,10 +15064,16 @@
         "@sinonjs/commons": "^1.7.0"
       }
     },
+    "@tootallnate/once": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+      "dev": true
+    },
     "@types/argparse": {
-      "version": "1.0.33",
-      "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.33.tgz",
-      "integrity": "sha512-VQgHxyPMTj3hIlq9SY1mctqx+Jj8kpQfoLvDlVSDNOyuYs8JYfkuY3OW/4+dO657yPmNhHpePRx0/Tje5ImNVQ==",
+      "version": "1.0.38",
+      "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
+      "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
       "dev": true
     },
     "@types/babel__core": {
@@ -15056,9 +15173,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "8.10.54",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz",
-      "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==",
+      "version": "12.20.24",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz",
+      "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==",
       "dev": true
     },
     "@types/normalize-package-data": {
@@ -15390,13 +15507,13 @@
       "dev": true
     },
     "accepts": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
-      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
       "dev": true,
       "requires": {
-        "mime-types": "~2.1.24",
-        "negotiator": "0.6.2"
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
       }
     },
     "acorn": {
@@ -15431,9 +15548,18 @@
     "after": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
-      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+      "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==",
       "dev": true
     },
+    "agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dev": true,
+      "requires": {
+        "debug": "4"
+      }
+    },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -15590,12 +15716,6 @@
       "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
       "dev": true
     },
-    "async-limiter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
-      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
-      "dev": true
-    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -15788,7 +15908,7 @@
     "backo2": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
-      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+      "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
       "dev": true
     },
     "balanced-match": {
@@ -15853,9 +15973,9 @@
       }
     },
     "base64-arraybuffer": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
-      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+      "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
       "dev": true
     },
     "base64-js": {
@@ -15865,9 +15985,9 @@
       "dev": true
     },
     "base64id": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
-      "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
       "dev": true
     },
     "bcrypt-pbkdf": {
@@ -15879,15 +15999,6 @@
         "tweetnacl": "^0.14.3"
       }
     },
-    "better-assert": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
-      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
-      "dev": true,
-      "requires": {
-        "callsite": "1.0.0"
-      }
-    },
     "bin-build": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz",
@@ -16396,12 +16507,6 @@
         }
       }
     },
-    "callsite": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
-      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
-      "dev": true
-    },
     "callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -16716,7 +16821,7 @@
     "component-bind": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
-      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+      "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==",
       "dev": true
     },
     "component-emitter": {
@@ -16728,7 +16833,7 @@
     "component-inherit": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
-      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+      "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==",
       "dev": true
     },
     "concat-map": {
@@ -16791,9 +16896,9 @@
       }
     },
     "cookie": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
-      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
       "dev": true
     },
     "copy-descriptor": {
@@ -17380,12 +17485,6 @@
             }
           }
         },
-        "@types/node": {
-          "version": "12.19.12",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz",
-          "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==",
-          "dev": true
-        },
         "fs-extra": {
           "version": "6.0.1",
           "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
@@ -17452,70 +17551,56 @@
       }
     },
     "engine.io": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz",
-      "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.0.tgz",
+      "integrity": "sha512-Kc8fo5bbg8F4a2f3HPHTEpGyq/IRIQpyeHu3H1ThR14XDD7VrLcsGBo16HUpahgp8YkHJDaU5gNxJZbuGcuueg==",
       "dev": true,
       "requires": {
         "accepts": "~1.3.4",
-        "base64id": "1.0.0",
-        "cookie": "0.3.1",
-        "debug": "~3.1.0",
-        "engine.io-parser": "~2.1.0",
-        "ws": "~6.1.0"
+        "base64id": "2.0.0",
+        "cookie": "~0.4.1",
+        "debug": "~4.1.0",
+        "engine.io-parser": "~2.2.0",
+        "ws": "~7.4.2"
       },
       "dependencies": {
         "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
           "dev": true,
           "requires": {
-            "ms": "2.0.0"
+            "ms": "^2.1.1"
           }
         },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
         "ws": {
-          "version": "6.1.4",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
-          "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+          "version": "7.4.6",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+          "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
           "dev": true,
-          "requires": {
-            "async-limiter": "~1.0.0"
-          }
+          "requires": {}
         }
       }
     },
     "engine.io-client": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.3.tgz",
-      "integrity": "sha512-PXIgpzb1brtBzh8Q6vCjzCMeu4nfEPmaDm+L3Qb2sVHwLkxC1qRiBMSjOB0NJNjZ0hbPNUKQa+s8J2XxLOIEeQ==",
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.2.tgz",
+      "integrity": "sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA==",
       "dev": true,
       "requires": {
-        "component-emitter": "1.2.1",
+        "component-emitter": "~1.3.0",
         "component-inherit": "0.0.3",
         "debug": "~3.1.0",
-        "engine.io-parser": "~2.1.1",
+        "engine.io-parser": "~2.2.0",
         "has-cors": "1.1.0",
         "indexof": "0.0.1",
-        "parseqs": "0.0.5",
-        "parseuri": "0.0.5",
-        "ws": "~6.1.0",
-        "xmlhttprequest-ssl": "~1.6.3",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "ws": "~7.4.2",
+        "xmlhttprequest-ssl": "~1.6.2",
         "yeast": "0.1.2"
       },
       "dependencies": {
-        "component-emitter": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
-          "dev": true
-        },
         "debug": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -17528,29 +17613,27 @@
         "ms": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
           "dev": true
         },
         "ws": {
-          "version": "6.1.4",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
-          "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+          "version": "7.4.6",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+          "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
           "dev": true,
-          "requires": {
-            "async-limiter": "~1.0.0"
-          }
+          "requires": {}
         }
       }
     },
     "engine.io-parser": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
-      "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
+      "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
       "dev": true,
       "requires": {
         "after": "0.8.2",
         "arraybuffer.slice": "~0.0.7",
-        "base64-arraybuffer": "0.1.5",
+        "base64-arraybuffer": "0.1.4",
         "blob": "0.0.5",
         "has-binary2": "~1.0.2"
       }
@@ -17592,18 +17675,24 @@
       "dev": true
     },
     "escodegen": {
-      "version": "1.14.3",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
-      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+      "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
       "dev": true,
       "requires": {
         "esprima": "^4.0.1",
-        "estraverse": "^4.2.0",
+        "estraverse": "^5.2.0",
         "esutils": "^2.0.2",
         "optionator": "^0.8.1",
         "source-map": "~0.6.1"
       },
       "dependencies": {
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
+        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -18692,7 +18781,7 @@
         "isarray": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
           "dev": true
         }
       }
@@ -18700,7 +18789,7 @@
     "has-cors": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
-      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+      "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==",
       "dev": true
     },
     "has-flag": {
@@ -18849,6 +18938,17 @@
       "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
       "dev": true
     },
+    "http-proxy-agent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+      "dev": true,
+      "requires": {
+        "@tootallnate/once": "1",
+        "agent-base": "6",
+        "debug": "4"
+      }
+    },
     "http-signature": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -18860,6 +18960,16 @@
         "sshpk": "^1.7.0"
       }
     },
+    "https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "dev": true,
+      "requires": {
+        "agent-base": "6",
+        "debug": "4"
+      }
+    },
     "human-signals": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@@ -19052,7 +19162,7 @@
     "indexof": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==",
       "dev": true
     },
     "inflight": {
@@ -19087,12 +19197,6 @@
         "p-is-promise": "^1.1.0"
       }
     },
-    "ip-regex": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
-      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
-      "dev": true
-    },
     "is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -19135,9 +19239,9 @@
       }
     },
     "is-core-module": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz",
-      "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
       "dev": true,
       "requires": {
         "has": "^1.0.3"
@@ -19266,9 +19370,9 @@
       }
     },
     "is-potential-custom-element-name": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
-      "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
       "dev": true
     },
     "is-reference": {
@@ -19952,60 +20056,6 @@
         "jest-mock": "^26.6.1",
         "jest-util": "^26.6.1",
         "jsdom": "^16.4.0"
-      },
-      "dependencies": {
-        "jsdom": {
-          "version": "16.4.0",
-          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz",
-          "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==",
-          "dev": true,
-          "requires": {
-            "abab": "^2.0.3",
-            "acorn": "^7.1.1",
-            "acorn-globals": "^6.0.0",
-            "cssom": "^0.4.4",
-            "cssstyle": "^2.2.0",
-            "data-urls": "^2.0.0",
-            "decimal.js": "^10.2.0",
-            "domexception": "^2.0.1",
-            "escodegen": "^1.14.1",
-            "html-encoding-sniffer": "^2.0.1",
-            "is-potential-custom-element-name": "^1.0.0",
-            "nwsapi": "^2.2.0",
-            "parse5": "5.1.1",
-            "request": "^2.88.2",
-            "request-promise-native": "^1.0.8",
-            "saxes": "^5.0.0",
-            "symbol-tree": "^3.2.4",
-            "tough-cookie": "^3.0.1",
-            "w3c-hr-time": "^1.0.2",
-            "w3c-xmlserializer": "^2.0.0",
-            "webidl-conversions": "^6.1.0",
-            "whatwg-encoding": "^1.0.5",
-            "whatwg-mimetype": "^2.3.0",
-            "whatwg-url": "^8.0.0",
-            "ws": "^7.2.3",
-            "xml-name-validator": "^3.0.0"
-          }
-        },
-        "saxes": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
-          "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
-          "dev": true,
-          "requires": {
-            "xmlchars": "^2.2.0"
-          }
-        },
-        "w3c-xmlserializer": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
-          "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
-          "dev": true,
-          "requires": {
-            "xml-name-validator": "^3.0.0"
-          }
-        }
       }
     },
     "jest-environment-node": {
@@ -20896,7 +20946,7 @@
     "jju": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
-      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
+      "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
       "dev": true
     },
     "js-tokens": {
@@ -20921,6 +20971,60 @@
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "dev": true
     },
+    "jsdom": {
+      "version": "16.7.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+      "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.5",
+        "acorn": "^8.2.4",
+        "acorn-globals": "^6.0.0",
+        "cssom": "^0.4.4",
+        "cssstyle": "^2.3.0",
+        "data-urls": "^2.0.0",
+        "decimal.js": "^10.2.1",
+        "domexception": "^2.0.1",
+        "escodegen": "^2.0.0",
+        "form-data": "^3.0.0",
+        "html-encoding-sniffer": "^2.0.1",
+        "http-proxy-agent": "^4.0.1",
+        "https-proxy-agent": "^5.0.0",
+        "is-potential-custom-element-name": "^1.0.1",
+        "nwsapi": "^2.2.0",
+        "parse5": "6.0.1",
+        "saxes": "^5.0.1",
+        "symbol-tree": "^3.2.4",
+        "tough-cookie": "^4.0.0",
+        "w3c-hr-time": "^1.0.2",
+        "w3c-xmlserializer": "^2.0.0",
+        "webidl-conversions": "^6.1.0",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^8.5.0",
+        "ws": "^7.4.6",
+        "xml-name-validator": "^3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "8.7.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+          "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+          "dev": true
+        },
+        "form-data": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+          "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+          "dev": true,
+          "requires": {
+            "asynckit": "^0.4.0",
+            "combined-stream": "^1.0.8",
+            "mime-types": "^2.1.12"
+          }
+        }
+      }
+    },
     "jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -20928,18 +21032,17 @@
       "dev": true
     },
     "jshint": {
-      "version": "2.10.2",
-      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.2.tgz",
-      "integrity": "sha512-e7KZgCSXMJxznE/4WULzybCMNXNAd/bf5TSrvVEq78Q/K8ZwFpmBqQeDtNiHc3l49nV4E/+YeHU/JZjSUIrLAA==",
+      "version": "2.13.5",
+      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.5.tgz",
+      "integrity": "sha512-dB2n1w3OaQ35PLcBGIWXlszjbPZwsgZoxsg6G8PtNf2cFMC1l0fObkYLUuXqTTdi6tKw4sAjfUseTdmDMHQRcg==",
       "dev": true,
       "requires": {
         "cli": "~1.0.0",
         "console-browserify": "1.1.x",
         "exit": "0.1.x",
         "htmlparser2": "3.8.x",
-        "lodash": "~4.17.11",
+        "lodash": "~4.17.21",
         "minimatch": "~3.0.2",
-        "shelljs": "0.3.x",
         "strip-json-comments": "1.0.x"
       },
       "dependencies": {
@@ -21062,7 +21165,7 @@
     "levn": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
       "dev": true,
       "requires": {
         "prelude-ls": "~1.1.2",
@@ -21093,13 +21196,13 @@
     "lodash.get": {
       "version": "4.4.2",
       "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
       "dev": true
     },
     "lodash.isequal": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
       "dev": true
     },
     "lodash.memoize": {
@@ -21108,12 +21211,6 @@
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
       "dev": true
     },
-    "lodash.sortby": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
-      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
-      "dev": true
-    },
     "lowercase-keys": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
@@ -21208,18 +21305,18 @@
       }
     },
     "mime-db": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
-      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
       "dev": true
     },
     "mime-types": {
-      "version": "2.1.27",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
-      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
       "dev": true,
       "requires": {
-        "mime-db": "1.44.0"
+        "mime-db": "1.52.0"
       }
     },
     "minimatch": {
@@ -21316,9 +21413,9 @@
       "dev": true
     },
     "negotiator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
-      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
       "dev": true
     },
     "nice-try": {
@@ -21550,12 +21647,6 @@
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
       "dev": true
     },
-    "object-component": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
-      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
-      "dev": true
-    },
     "object-copy": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
@@ -21777,28 +21868,22 @@
       }
     },
     "parse5": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
-      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
       "dev": true
     },
     "parseqs": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
-      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
-      "dev": true,
-      "requires": {
-        "better-assert": "~1.0.0"
-      }
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
+      "dev": true
     },
     "parseuri": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
-      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
-      "dev": true,
-      "requires": {
-        "better-assert": "~1.0.0"
-      }
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
+      "dev": true
     },
     "parsimmon": {
       "version": "1.16.0",
@@ -21944,7 +22029,7 @@
     "prelude-ls": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
       "dev": true
     },
     "prepend-http": {
@@ -22217,38 +22302,6 @@
         }
       }
     },
-    "request-promise-core": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
-      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
-      "dev": true,
-      "requires": {
-        "lodash": "^4.17.19"
-      }
-    },
-    "request-promise-native": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
-      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
-      "dev": true,
-      "requires": {
-        "request-promise-core": "1.1.4",
-        "stealthy-require": "^1.1.1",
-        "tough-cookie": "^2.3.3"
-      },
-      "dependencies": {
-        "tough-cookie": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-          "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-          "dev": true,
-          "requires": {
-            "psl": "^1.1.28",
-            "punycode": "^2.1.1"
-          }
-        }
-      }
-    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -22552,6 +22605,15 @@
         }
       }
     },
+    "saxes": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+      "dev": true,
+      "requires": {
+        "xmlchars": "^2.2.0"
+      }
+    },
     "seedrandom": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.3.tgz",
@@ -22688,12 +22750,6 @@
       "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
       "dev": true
     },
-    "shelljs": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
-      "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
-      "dev": true
-    },
     "shellwords": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
@@ -22897,17 +22953,17 @@
       }
     },
     "socket.io": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz",
-      "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.0.tgz",
+      "integrity": "sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==",
       "dev": true,
       "requires": {
         "debug": "~4.1.0",
-        "engine.io": "~3.3.1",
+        "engine.io": "~3.6.0",
         "has-binary2": "~1.0.2",
         "socket.io-adapter": "~1.1.0",
-        "socket.io-client": "2.2.0",
-        "socket.io-parser": "~3.3.0"
+        "socket.io-client": "2.5.0",
+        "socket.io-parser": "~3.4.0"
       },
       "dependencies": {
         "debug": {
@@ -22928,59 +22984,22 @@
       "dev": true
     },
     "socket.io-client": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz",
-      "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
+      "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
       "dev": true,
       "requires": {
         "backo2": "1.0.2",
-        "base64-arraybuffer": "0.1.5",
         "component-bind": "1.0.0",
-        "component-emitter": "1.2.1",
-        "debug": "~3.1.0",
-        "engine.io-client": "~3.3.1",
-        "has-binary2": "~1.0.2",
-        "has-cors": "1.1.0",
-        "indexof": "0.0.1",
-        "object-component": "0.0.3",
-        "parseqs": "0.0.5",
-        "parseuri": "0.0.5",
-        "socket.io-parser": "~3.3.0",
-        "to-array": "0.1.4"
-      },
-      "dependencies": {
-        "component-emitter": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
-          "dev": true
-        },
-        "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "socket.io-parser": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
-      "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
-      "dev": true,
-      "requires": {
         "component-emitter": "~1.3.0",
         "debug": "~3.1.0",
-        "isarray": "2.0.1"
+        "engine.io-client": "~3.5.0",
+        "has-binary2": "~1.0.2",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "socket.io-parser": "~3.3.0",
+        "to-array": "0.1.4"
       },
       "dependencies": {
         "debug": {
@@ -22995,13 +23014,58 @@
         "isarray": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
           "dev": true
         },
         "ms": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+          "dev": true
+        },
+        "socket.io-parser": {
+          "version": "3.3.2",
+          "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
+          "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
+          "dev": true,
+          "requires": {
+            "component-emitter": "~1.3.0",
+            "debug": "~3.1.0",
+            "isarray": "2.0.1"
+          }
+        }
+      }
+    },
+    "socket.io-parser": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
+      "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "debug": "~4.1.0",
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "component-emitter": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+          "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==",
+          "dev": true
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
           "dev": true
         }
       }
@@ -23184,12 +23248,6 @@
         }
       }
     },
-    "stealthy-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
-      "dev": true
-    },
     "strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -23205,6 +23263,12 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "string-argv": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+      "dev": true
+    },
     "string-length": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz",
@@ -23566,12 +23630,6 @@
       "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
       "dev": true
     },
-    "timsort": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
-      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
-      "dev": true
-    },
     "tmpl": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@@ -23581,7 +23639,7 @@
     "to-array": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
-      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+      "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==",
       "dev": true
     },
     "to-buffer": {
@@ -23638,20 +23696,20 @@
       }
     },
     "tough-cookie": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
-      "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+      "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
       "dev": true,
       "requires": {
-        "ip-regex": "^2.1.0",
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
+        "psl": "^1.1.33",
+        "punycode": "^2.1.1",
+        "universalify": "^0.1.2"
       }
     },
     "tr46": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
-      "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
       "dev": true,
       "requires": {
         "punycode": "^2.1.1"
@@ -23821,7 +23879,7 @@
     "type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
       "dev": true,
       "requires": {
         "prelude-ls": "~1.1.2"
@@ -24022,9 +24080,9 @@
       }
     },
     "validator": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
-      "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==",
+      "version": "13.7.0",
+      "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
+      "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
       "dev": true
     },
     "verror": {
@@ -24047,6 +24105,15 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "w3c-xmlserializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+      "dev": true,
+      "requires": {
+        "xml-name-validator": "^3.0.0"
+      }
+    },
     "walker": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
@@ -24078,13 +24145,13 @@
       "dev": true
     },
     "whatwg-url": {
-      "version": "8.4.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz",
-      "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==",
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+      "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
       "dev": true,
       "requires": {
-        "lodash.sortby": "^4.7.0",
-        "tr46": "^2.0.2",
+        "lodash": "^4.7.0",
+        "tr46": "^2.1.0",
         "webidl-conversions": "^6.1.0"
       }
     },
@@ -24331,7 +24398,7 @@
     "yeast": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
-      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+      "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==",
       "dev": true
     },
     "yocto-queue": {
@@ -24341,21 +24408,30 @@
       "dev": true
     },
     "z-schema": {
-      "version": "3.18.4",
-      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
-      "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.4.tgz",
+      "integrity": "sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==",
       "dev": true,
       "requires": {
-        "commander": "^2.7.1",
-        "lodash.get": "^4.0.0",
-        "lodash.isequal": "^4.0.0",
-        "validator": "^8.0.0"
+        "commander": "^2.20.3",
+        "lodash.get": "^4.4.2",
+        "lodash.isequal": "^4.5.0",
+        "validator": "^13.7.0"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.20.3",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+          "dev": true,
+          "optional": true
+        }
       }
     },
     "zrender": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
-      "integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==",
+      "version": "npm:zrender-nightly@5.3.3-dev.20220820",
+      "resolved": "https://registry.npmjs.org/zrender-nightly/-/zrender-nightly-5.3.3-dev.20220820.tgz",
+      "integrity": "sha512-/4hBgw+X1EAZ+wE/4VYfOJEkOD+FWJ+GUEMYVNUoo8FWpU97avPhcTVMupP2w6qjuDY8178ivDs8PMBL7igdxQ==",
       "requires": {
         "tslib": "2.3.0"
       }
diff --git a/package.json b/package.json
index 5acf86a..44c325f 100644
--- a/package.json
+++ b/package.json
@@ -64,7 +64,7 @@
   },
   "dependencies": {
     "tslib": "2.3.0",
-    "zrender": "5.3.2"
+    "zrender": "npm:zrender-nightly@^5.3.3-dev.20220820"
   },
   "devDependencies": {
     "@babel/code-frame": "7.10.4",
@@ -73,7 +73,7 @@
     "@definitelytyped/typescript-versions": "0.0.64",
     "@definitelytyped/utils": "0.0.64",
     "@lang/rollup-plugin-dts": "2.0.2",
-    "@microsoft/api-extractor": "7.7.2",
+    "@microsoft/api-extractor": "7.31.2",
     "@rollup/plugin-commonjs": "^17.0.0",
     "@rollup/plugin-node-resolve": "^11.0.0",
     "@rollup/plugin-replace": "^2.3.4",
@@ -92,7 +92,7 @@
     "husky": "^4.2.5",
     "jest": "^26.6.1",
     "jest-canvas-mock": "^2.2.0",
-    "jshint": "2.10.2",
+    "jshint": "2.13.5",
     "magic-string": "^0.25.7",
     "open": "6.4.0",
     "pixelmatch": "5.0.2",
@@ -103,7 +103,7 @@
     "semver": "6.3.0",
     "serve-handler": "6.1.1",
     "slugify": "1.3.4",
-    "socket.io": "2.2.0",
+    "socket.io": "2.5.0",
     "terser": "^5.3.8",
     "ts-jest": "^26.4.3",
     "typescript": "4.4.3"
diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts
index a5c99d0..3cbad98 100644
--- a/src/chart/bar/BarView.ts
+++ b/src/chart/bar/BarView.ts
@@ -1146,6 +1146,7 @@
     const el = new LargePath({
         shape: {points: data.getLayout('largePoints')},
         incremental: !!incremental,
+        ignoreCoarsePointer: true,
         z2: 1
     });
     el.baseDimIdx = baseDimIdx;
diff --git a/src/chart/bar/BaseBarSeries.ts b/src/chart/bar/BaseBarSeries.ts
index 8dad96d..e21d968 100644
--- a/src/chart/bar/BaseBarSeries.ts
+++ b/src/chart/bar/BaseBarSeries.ts
@@ -29,6 +29,9 @@
 import GlobalModel from '../../model/Global';
 import Cartesian2D from '../../coord/cartesian/Cartesian2D';
 import SeriesData from '../../data/SeriesData';
+import {dimPermutations} from '../../component/marker/MarkAreaView';
+import { each } from 'zrender/src/core/util';
+import type Axis2D from '../../coord/cartesian/Axis2D';
 
 
 export interface BaseBarSeriesOption<StateOption, ExtraStateOption = DefaultStatesMixin>
@@ -82,16 +85,34 @@
         return createSeriesData(null, this, {useEncodeDefaulter: true});
     }
 
-    getMarkerPosition(value: ScaleDataValue[]) {
+    getMarkerPosition(value: ScaleDataValue[], dims?: typeof dimPermutations[number], startingAtTick: boolean = false) {
         const coordSys = this.coordinateSystem;
         if (coordSys && coordSys.clampData) {
             // PENDING if clamp ?
             const pt = coordSys.dataToPoint(coordSys.clampData(value));
-            const data = this.getData();
-            const offset = data.getLayout('offset');
-            const size = data.getLayout('size');
-            const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
-            pt[offsetIndex] += offset + size / 2;
+            if (startingAtTick) {
+                each(coordSys.getAxes(), function (axis: Axis2D, idx: number) {
+                    //If axis type is category, use tick coords instead
+                    if (axis.type === 'category') {
+                        const tickCoords = axis.getTicksCoords();
+                        let tickIdx = coordSys.clampData(value)[idx];
+                        //The index of rightmost tick of markArea is 1 larger than x1/y1 index
+                        if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
+                            tickIdx += 1;
+                        }
+                        (tickIdx > tickCoords.length - 1) && (tickIdx = tickCoords.length - 1);
+                        (tickIdx < 0) && (tickIdx = 0);
+                        tickCoords[tickIdx] && (pt[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
+                    }
+                });
+            }
+            else {
+                const data = this.getData();
+                const offset = data.getLayout('offset');
+                const size = data.getLayout('size');
+                const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
+                pt[offsetIndex] += offset + size / 2;
+            }
             return pt;
         }
         return [NaN, NaN];
diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts
index 3fa95f3..ed4f666 100644
--- a/src/chart/candlestick/CandlestickView.ts
+++ b/src/chart/candlestick/CandlestickView.ts
@@ -358,12 +358,14 @@
 
     const elP = new LargeBoxPath({
         shape: {points: largePoints},
-        __sign: 1
+        __sign: 1,
+        ignoreCoarsePointer: true
     });
     group.add(elP);
     const elN = new LargeBoxPath({
         shape: {points: largePoints},
-        __sign: -1
+        __sign: -1,
+        ignoreCoarsePointer: true
     });
     group.add(elN);
 
@@ -397,4 +399,3 @@
 
 
 export default CandlestickView;
-
diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts
index 37d0086..bd5b966 100644
--- a/src/chart/graph/GraphView.ts
+++ b/src/chart/graph/GraphView.ts
@@ -37,6 +37,9 @@
 import Line from '../helper/Line';
 import { getECData } from '../../util/innerStore';
 
+import { simpleLayoutEdge } from './simpleLayoutHelper';
+import { circularLayout, rotateNodeLabel } from './circularLayoutHelper';
+
 function isViewCoordSys(coordSys: CoordinateSystem): coordSys is View {
     return coordSys.type === 'view';
 }
@@ -122,6 +125,8 @@
             this._startForceLayoutIteration(forceLayout, layoutAnimation);
         }
 
+        const layout = seriesModel.get('layout');
+
         data.graph.eachNode((node) => {
             const idx = node.dataIndex;
             const el = node.getGraphicEl() as Symbol;
@@ -135,14 +140,31 @@
             el.off('drag').off('dragend');
             const draggable = itemModel.get('draggable');
             if (draggable) {
-                el.on('drag', () => {
-                    if (forceLayout) {
-                        forceLayout.warmUp();
-                        !this._layouting
-                            && this._startForceLayoutIteration(forceLayout, layoutAnimation);
-                        forceLayout.setFixed(idx);
-                        // Write position back to layout
-                        data.setItemLayout(idx, [el.x, el.y]);
+                el.on('drag', (e) => {
+                    switch (layout) {
+                        case 'force':
+                            forceLayout.warmUp();
+                            !this._layouting
+                                && this._startForceLayoutIteration(forceLayout, layoutAnimation);
+                            forceLayout.setFixed(idx);
+                            // Write position back to layout
+                            data.setItemLayout(idx, [el.x, el.y]);
+                            break;
+                        case 'circular':
+                            data.setItemLayout(idx, [el.x, el.y]);
+                            // mark node fixed
+                            node.setLayout({ fixed: true }, true);
+                            // recalculate circular layout
+                            circularLayout(seriesModel, 'symbolSize', node, [e.offsetX, e.offsetY]);
+                            this.updateLayout(seriesModel);
+                            break;
+                        case 'none':
+                        default:
+                            data.setItemLayout(idx, [el.x, el.y]);
+                            // update edge
+                            simpleLayoutEdge(seriesModel.getGraph(), seriesModel);
+                            this.updateLayout(seriesModel);
+                            break;
                     }
                 }).on('dragend', () => {
                     if (forceLayout) {
@@ -179,37 +201,8 @@
             && seriesModel.get(['circular', 'rotateLabel']);
         const cx = data.getLayout('cx');
         const cy = data.getLayout('cy');
-        data.eachItemGraphicEl(function (el: Symbol, idx) {
-            const itemModel = data.getItemModel<GraphNodeItemOption>(idx);
-            let labelRotate = itemModel.get(['label', 'rotate']) || 0;
-            const symbolPath = el.getSymbolPath();
-            if (circularRotateLabel) {
-                const pos = data.getItemLayout(idx);
-                let rad = Math.atan2(pos[1] - cy, pos[0] - cx);
-                if (rad < 0) {
-                    rad = Math.PI * 2 + rad;
-                }
-                const isLeft = pos[0] < cx;
-                if (isLeft) {
-                    rad = rad - Math.PI;
-                }
-                const textPosition = isLeft ? 'left' as const : 'right' as const;
-
-                symbolPath.setTextConfig({
-                    rotation: -rad,
-                    position: textPosition,
-                    origin: 'center'
-                });
-                const emphasisState = symbolPath.ensureState('emphasis');
-                zrUtil.extend(emphasisState.textConfig || (emphasisState.textConfig = {}), {
-                    position: textPosition
-                });
-            }
-            else {
-                symbolPath.setTextConfig({
-                    rotation: labelRotate *= Math.PI / 180
-                });
-            }
+        data.graph.eachNode((node) => {
+            rotateNodeLabel(node, circularRotateLabel, cx, cy);
         });
 
         this._firstRender = false;
diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts
index 91265be..af01fb0 100644
--- a/src/chart/graph/circularLayoutHelper.ts
+++ b/src/chart/graph/circularLayoutHelper.ts
@@ -20,8 +20,9 @@
 
 import * as vec2 from 'zrender/src/core/vector';
 import {getSymbolSize, getNodeGlobalScale} from './graphHelper';
-import GraphSeriesModel, { GraphEdgeItemOption } from './GraphSeries';
-import Graph from '../../data/Graph';
+import GraphSeriesModel, { GraphEdgeItemOption, GraphNodeItemOption } from './GraphSeries';
+import Graph, { GraphNode } from '../../data/Graph';
+import Symbol from '../helper/Symbol';
 import SeriesData from '../../data/SeriesData';
 import * as zrUtil from 'zrender/src/core/util';
 import {getCurvenessForEdge} from '../helper/multipleGraphEdgeHelper';
@@ -51,7 +52,9 @@
  */
 export function circularLayout(
     seriesModel: GraphSeriesModel,
-    basedOn: 'value' | 'symbolSize'
+    basedOn: 'value' | 'symbolSize',
+    draggingNode?: GraphNode,
+    pointer?: [number, number]
 ) {
     const coordSys = seriesModel.coordinateSystem;
     if (coordSys && coordSys.type !== 'view') {
@@ -77,6 +80,17 @@
         return;
     }
 
+    if (draggingNode) {
+        const [tempX, tempY] = coordSys.pointToData(pointer) as [number, number];
+        const v = [tempX - cx, tempY - cy];
+        vec2.normalize(v, v);
+        vec2.scale(v, v, r);
+        draggingNode.setLayout([cx + v[0], cy + v[1]], true);
+
+        const circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']);
+        rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy);
+    }
+
     _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count);
 
     graph.eachEdge(function (edge, index) {
@@ -163,7 +177,11 @@
             const radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex];
 
             angle += radianHalf;
-            node.setLayout([
+            // init circular layout for
+            // 1. layout undefined node
+            // 2. not fixed node
+            (!node.getLayout() || !node.getLayout().fixed)
+            && node.setLayout([
                 r * Math.cos(angle) + cx,
                 r * Math.sin(angle) + cy
             ]);
@@ -171,3 +189,46 @@
         });
     }
 };
+
+export function rotateNodeLabel(
+    node: GraphNode,
+    circularRotateLabel: boolean,
+    cx: number,
+    cy: number
+) {
+    const el = node.getGraphicEl() as Symbol;
+    // need to check if el exists. '-' value may not create node element.
+    if (!el) {
+        return;
+    }
+    const nodeModel = node.getModel<GraphNodeItemOption>();
+    let labelRotate = nodeModel.get(['label', 'rotate']) || 0;
+    const symbolPath = el.getSymbolPath();
+    if (circularRotateLabel) {
+        const pos = node.getLayout();
+        let rad = Math.atan2(pos[1] - cy, pos[0] - cx);
+        if (rad < 0) {
+            rad = Math.PI * 2 + rad;
+        }
+        const isLeft = pos[0] < cx;
+        if (isLeft) {
+            rad = rad - Math.PI;
+        }
+        const textPosition = isLeft ? 'left' as const : 'right' as const;
+
+        symbolPath.setTextConfig({
+            rotation: -rad,
+            position: textPosition,
+            origin: 'center'
+        });
+        const emphasisState = symbolPath.ensureState('emphasis');
+        zrUtil.extend(emphasisState.textConfig || (emphasisState.textConfig = {}), {
+            position: textPosition
+        });
+    }
+    else {
+        symbolPath.setTextConfig({
+            rotation: labelRotate *= Math.PI / 180
+        });
+    }
+}
diff --git a/src/chart/helper/EffectLine.ts b/src/chart/helper/EffectLine.ts
index 412b272..f368d83 100644
--- a/src/chart/helper/EffectLine.ts
+++ b/src/chart/helper/EffectLine.ts
@@ -47,6 +47,8 @@
 
     private _loop: boolean;
 
+    private _roundTrip: boolean;
+
     private _symbolScale: number[];
 
     constructor(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
@@ -121,6 +123,7 @@
 
         let period = effectModel.get('period') * 1000;
         const loop = effectModel.get('loop');
+        const roundTrip = effectModel.get('roundTrip');
         const constantSpeed = effectModel.get('constantSpeed');
         const delayExpr = zrUtil.retrieve(effectModel.get('delay'), function (idx) {
             return idx / lineData.count() * period / 3;
@@ -135,7 +138,7 @@
             period = this._getLineLength(symbol) / constantSpeed * 1000;
         }
 
-        if (period !== this._period || loop !== this._loop) {
+        if (period !== this._period || loop !== this._loop || roundTrip !== this._roundTrip) {
             symbol.stopAnimation();
             let delayNum: number;
             if (zrUtil.isFunction(delayExpr)) {
@@ -149,21 +152,23 @@
             }
 
             this._animateSymbol(
-                symbol, period, delayNum, loop
+                symbol, period, delayNum, loop, roundTrip
             );
         }
 
         this._period = period;
         this._loop = loop;
+        this._roundTrip = roundTrip;
     }
 
-    private _animateSymbol(symbol: ECSymbolOnEffectLine, period: number, delayNum: number, loop: boolean) {
+    private _animateSymbol(
+        symbol: ECSymbolOnEffectLine, period: number, delayNum: number, loop: boolean, roundTrip: boolean) {
         if (period > 0) {
             symbol.__t = 0;
             const self = this;
             const animator = symbol.animate('', loop)
-                .when(period, {
-                    __t: 1
+                .when(roundTrip ? period * 2 : period, {
+                    __t: roundTrip ? 2 : 1
                 })
                 .delay(delayNum)
                 .during(function () {
@@ -202,7 +207,7 @@
         const p1 = symbol.__p1;
         const p2 = symbol.__p2;
         const cp1 = symbol.__cp1;
-        const t = symbol.__t;
+        const t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t;
         const pos = [symbol.x, symbol.y];
         const lastPos = pos.slice();
         const quadraticAt = curveUtil.quadraticAt;
@@ -211,8 +216,11 @@
         pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t);
 
         // Tangent
-        const tx = quadraticDerivativeAt(p1[0], cp1[0], p2[0], t);
-        const ty = quadraticDerivativeAt(p1[1], cp1[1], p2[1], t);
+        const tx = symbol.__t < 1 ? quadraticDerivativeAt(p1[0], cp1[0], p2[0], t)
+                 : quadraticDerivativeAt(p2[0], cp1[0], p1[0], 1 - t);
+         const ty = symbol.__t < 1 ? quadraticDerivativeAt(p1[1], cp1[1], p2[1], t)
+                 : quadraticDerivativeAt(p2[1], cp1[1], p1[1], 1 - t);
+
 
         symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;
         // enable continuity trail for 'line', 'rect', 'roundRect' symbolType
@@ -247,4 +255,4 @@
         this._updateEffectAnimation(lineData, effectModel, idx);
     }
 }
-export default EffectLine;
\ No newline at end of file
+export default EffectLine;
diff --git a/src/chart/helper/EffectPolyline.ts b/src/chart/helper/EffectPolyline.ts
index a250cb5..389dbe4 100644
--- a/src/chart/helper/EffectPolyline.ts
+++ b/src/chart/helper/EffectPolyline.ts
@@ -67,7 +67,7 @@
 
     // Override
     protected _updateSymbolPosition(symbol: ECSymbolOnEffectLine) {
-        const t = symbol.__t;
+        const t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t;
         const points = this._points;
         const offsets = this._offsets;
         const len = points.length;
@@ -107,8 +107,8 @@
         symbol.x = p0[0] * (1 - p) + p * p1[0];
         symbol.y = p0[1] * (1 - p) + p * p1[1];
 
-        const tx = p1[0] - p0[0];
-        const ty = p1[1] - p0[1];
+        const tx = symbol.__t < 1 ? p1[0] - p0[0] : p0[0] - p1[0];
+        const ty = symbol.__t < 1 ? p1[1] - p0[1] : p0[1] - p1[1];
         symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;
 
         this._lastFrame = frame;
@@ -119,4 +119,4 @@
 
 }
 
-export default EffectPolyline;
\ No newline at end of file
+export default EffectPolyline;
diff --git a/src/chart/helper/LargeLineDraw.ts b/src/chart/helper/LargeLineDraw.ts
index 62f5b6d..88afd6b 100644
--- a/src/chart/helper/LargeLineDraw.ts
+++ b/src/chart/helper/LargeLineDraw.ts
@@ -293,7 +293,8 @@
 
     private _create() {
         const lineEl = new LargeLinesPath({
-            cursor: 'default'
+            cursor: 'default',
+            ignoreCoarsePointer: true
         });
         this._newAdded.push(lineEl);
         this.group.add(lineEl);
diff --git a/src/chart/helper/LargeSymbolDraw.ts b/src/chart/helper/LargeSymbolDraw.ts
index 22614b2..2aafb9d 100644
--- a/src/chart/helper/LargeSymbolDraw.ts
+++ b/src/chart/helper/LargeSymbolDraw.ts
@@ -315,6 +315,7 @@
         const symbolEl = new LargeSymbolPath({
             cursor: 'default'
         });
+        symbolEl.ignoreCoarsePointer = true;
         this.group.add(symbolEl);
         this._newAdded.push(symbolEl);
         return symbolEl;
diff --git a/src/chart/helper/LineDraw.ts b/src/chart/helper/LineDraw.ts
index d965953..94c417f 100644
--- a/src/chart/helper/LineDraw.ts
+++ b/src/chart/helper/LineDraw.ts
@@ -73,6 +73,7 @@
         symbol?: string
         symbolSize?: number | number[]
         loop?: boolean
+        roundTrip?: boolean
         /**
          * Length of trail, 0 - 1
          */
diff --git a/src/chart/sunburst/sunburstAction.ts b/src/chart/sunburst/sunburstAction.ts
index d45fdde..ade76a3 100644
--- a/src/chart/sunburst/sunburstAction.ts
+++ b/src/chart/sunburst/sunburstAction.ts
@@ -87,7 +87,7 @@
             }
 
             if (__DEV__) {
-                deprecateReplaceLog('highlight', 'sunburstHighlight');
+                deprecateReplaceLog('sunburstHighlight', 'highlight');
             }
 
             // Fast forward action
@@ -103,7 +103,7 @@
             payload = extend({}, payload);
 
             if (__DEV__) {
-                deprecateReplaceLog('downplay', 'sunburstUnhighlight');
+                deprecateReplaceLog('sunburstUnhighlight', 'downplay');
             }
 
             api.dispatchAction(extend(payload, {
@@ -112,4 +112,4 @@
         }
     );
 
-}
\ No newline at end of file
+}
diff --git a/src/component/axis/AxisBuilder.ts b/src/component/axis/AxisBuilder.ts
index b0e31e0..d01d20d 100644
--- a/src/component/axis/AxisBuilder.ts
+++ b/src/component/axis/AxisBuilder.ts
@@ -269,8 +269,6 @@
         );
 
         const line = new graphic.Line({
-            // Id for animation
-            subPixelOptimize: true,
             shape: {
                 x1: pt1[0],
                 y1: pt1[1],
@@ -282,6 +280,7 @@
             silent: true,
             z2: 1
         });
+        graphic.subPixelOptimizeLine(line.shape, line.style.lineWidth);
         line.anid = 'line';
         group.add(line);
 
@@ -343,7 +342,6 @@
     },
 
     axisTickLabel(opt, axisModel, group, transformGroup) {
-
         const ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt);
         const labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
 
@@ -630,7 +628,6 @@
         }
         // Tick line, Not use group transform to have better line draw
         const tickEl = new graphic.Line({
-            subPixelOptimize: true,
             shape: {
                 x1: pt1[0],
                 y1: pt1[1],
@@ -642,6 +639,7 @@
             autoBatch: true,
             silent: true
         });
+        graphic.subPixelOptimizeLine(tickEl.shape, tickEl.style.lineWidth);
         tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
         tickEls.push(tickEl);
     }
diff --git a/src/component/axis/CartesianAxisView.ts b/src/component/axis/CartesianAxisView.ts
index e040398..3cc48e3 100644
--- a/src/component/axis/CartesianAxisView.ts
+++ b/src/component/axis/CartesianAxisView.ts
@@ -157,9 +157,8 @@
 
             const colorIndex = (lineCount++) % lineColors.length;
             const tickValue = ticksCoords[i].tickValue;
-            axisGroup.add(new graphic.Line({
+            const line = new graphic.Line({
                 anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
-                subPixelOptimize: true,
                 autoBatch: true,
                 shape: {
                     x1: p1[0],
@@ -171,7 +170,9 @@
                     stroke: lineColors[colorIndex]
                 }, lineStyle),
                 silent: true
-            }));
+            });
+            graphic.subPixelOptimizeLine(line.shape, lineStyle.lineWidth);
+            axisGroup.add(line);
         }
     },
 
@@ -193,7 +194,6 @@
 
         const lineStyle = lineStyleModel.getLineStyle();
 
-
         for (let i = 0; i < minorTicksCoords.length; i++) {
             for (let k = 0; k < minorTicksCoords[i].length; k++) {
                 const tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);
@@ -211,9 +211,8 @@
                     p2[1] = tickCoord;
                 }
 
-                axisGroup.add(new graphic.Line({
+                const line = new graphic.Line({
                     anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
-                    subPixelOptimize: true,
                     autoBatch: true,
                     shape: {
                         x1: p1[0],
@@ -223,7 +222,9 @@
                     },
                     style: lineStyle,
                     silent: true
-                }));
+                });
+                graphic.subPixelOptimizeLine(line.shape, lineStyle.lineWidth);
+                axisGroup.add(line);
             }
         }
     },
diff --git a/src/component/axis/SingleAxisView.ts b/src/component/axis/SingleAxisView.ts
index 06cf5e3..600b55a 100644
--- a/src/component/axis/SingleAxisView.ts
+++ b/src/component/axis/SingleAxisView.ts
@@ -93,8 +93,8 @@
         const splitLineModel = axisModel.getModel('splitLine');
         const lineStyleModel = splitLineModel.getModel('lineStyle');
         let lineColors = lineStyleModel.get('color');
-
         lineColors = lineColors instanceof Array ? lineColors : [lineColors];
+        const lineWidth = lineStyleModel.get('width');
 
         const gridRect = axisModel.coordinateSystem.getRect();
         const isHorizontal = axis.isHorizontal();
@@ -123,10 +123,8 @@
                 p2[0] = gridRect.x + gridRect.width;
                 p2[1] = tickCoord;
             }
-            const colorIndex = (lineCount++) % lineColors.length;
-            splitLines[colorIndex] = splitLines[colorIndex] || [];
-            splitLines[colorIndex].push(new graphic.Line({
-                subPixelOptimize: true,
+
+            const line = new graphic.Line({
                 shape: {
                     x1: p1[0],
                     y1: p1[1],
@@ -134,7 +132,12 @@
                     y2: p2[1]
                 },
                 silent: true
-            }));
+            });
+            graphic.subPixelOptimizeLine(line.shape, lineWidth);
+
+            const colorIndex = (lineCount++) % lineColors.length;
+            splitLines[colorIndex] = splitLines[colorIndex] || [];
+            splitLines[colorIndex].push(line);
         }
 
         const lineStyle = lineStyleModel.getLineStyle(['color']);
diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts
index edff610..874865e 100644
--- a/src/component/helper/RoamController.ts
+++ b/src/component/helper/RoamController.ts
@@ -173,12 +173,19 @@
     }
 
     private _mousedownHandler(e: ZRElementEvent) {
-        if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)
-            || (e.target && e.target.draggable)
-        ) {
+        if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
             return;
         }
 
+        let el = e.target;
+        while (el) {
+            if (el.draggable) {
+                return;
+            }
+            // check if host is draggable
+            el = el.__hostTarget || el.parent;
+        }
+
         const x = e.offsetX;
         const y = e.offsetY;
 
diff --git a/src/component/legend/LegendModel.ts b/src/component/legend/LegendModel.ts
index b121c94..9c97f80 100644
--- a/src/component/legend/LegendModel.ts
+++ b/src/component/legend/LegendModel.ts
@@ -354,6 +354,7 @@
         // which is convinient for user preparing option.
         const rawData = this.get('data') || potentialData;
 
+        const legendNameMap = zrUtil.createHashMap();
         const legendData = zrUtil.map(rawData, function (dataItem) {
             // Can be string or number
             if (zrUtil.isString(dataItem) || zrUtil.isNumber(dataItem)) {
@@ -361,6 +362,11 @@
                     name: dataItem as string
                 };
             }
+            if (legendNameMap.get(dataItem.name)) {
+                // remove legend name duplicate
+                return null;
+            }
+            legendNameMap.set(dataItem.name, true);
             return new Model(dataItem, this, this.ecModel);
         }, this);
 
@@ -368,7 +374,7 @@
          * @type {Array.<module:echarts/model/Model>}
          * @private
          */
-        this._data = legendData;
+        this._data = zrUtil.filter(legendData, item => !!item);
     }
 
     getData() {
diff --git a/src/component/marker/MarkAreaView.ts b/src/component/marker/MarkAreaView.ts
index 785d107..801a74b 100644
--- a/src/component/marker/MarkAreaView.ts
+++ b/src/component/marker/MarkAreaView.ts
@@ -164,9 +164,28 @@
     else {
         // Chart like bar may have there own marker positioning logic
         if (seriesModel.getMarkerPosition) {
-            // Use the getMarkerPosition
+            //Consider the case that user input the right-bottom point first
+            //Pick the larger x and y as 'x1' and 'y1'
+            const pointValue0 = data.getValues(['x0', 'y0'], idx);
+            const pointValue1 = data.getValues(['x1', 'y1'], idx);
+            const clampPointValue0 = coordSys.clampData(pointValue0);
+            const clampPointValue1 = coordSys.clampData(pointValue1);
+            const pointValue = [];
+            if (dims[0] === 'x0') {
+                pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue1[0] : pointValue0[0];
+            }
+            else {
+                pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue0[0] : pointValue1[0];
+            }
+            if (dims[1] === 'y0') {
+                pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue1[1] : pointValue0[1];
+            }
+            else {
+                pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue0[1] : pointValue1[1];
+            }
+            // Use the getMarkerPoisition
             point = seriesModel.getMarkerPosition(
-                data.getValues(dims, idx)
+                pointValue, dims, true
             );
         }
         else {
@@ -202,7 +221,7 @@
     return point;
 }
 
-const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const;
+export const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const;
 
 class MarkAreaView extends MarkerView {
 
diff --git a/src/component/timeline/SliderTimelineView.ts b/src/component/timeline/SliderTimelineView.ts
index 32eb7d6..f993e57 100644
--- a/src/component/timeline/SliderTimelineView.ts
+++ b/src/component/timeline/SliderTimelineView.ts
@@ -420,7 +420,7 @@
 
         this._tickSymbols = [];
 
-        // The value is dataIndex, see the costomized scale.
+        // The value is dataIndex, see the customized scale.
         each(ticks, (tick: ScaleTick) => {
             const tickCoord = axis.dataToCoord(tick.value);
             const itemModel = data.getItemModel<TimelineDataItemOption>(tick.value);
@@ -470,7 +470,7 @@
         this._tickLabels = [];
 
         each(labels, (labelItem) => {
-            // The tickValue is dataIndex, see the costomized scale.
+            // The tickValue is dataIndex, see the customized scale.
             const dataIndex = labelItem.tickValue;
 
             const itemModel = data.getItemModel<TimelineDataItemOption>(dataIndex);
@@ -626,8 +626,11 @@
         this._currentPointer.x = toCoord;
         this._currentPointer.markRedraw();
 
-        this._progressLine.shape.x2 = toCoord;
-        this._progressLine.dirty();
+        const progressLine = this._progressLine;
+        if (progressLine) {
+            progressLine.shape.x2 = toCoord;
+            progressLine.dirty();
+        }
 
         const targetDataIndex = this._findNearestTick(toCoord);
         const timelineModel = this.model;
diff --git a/src/coord/CoordinateSystem.ts b/src/coord/CoordinateSystem.ts
index 0ebe41e..b27f66a 100644
--- a/src/coord/CoordinateSystem.ts
+++ b/src/coord/CoordinateSystem.ts
@@ -137,6 +137,8 @@
     // @param point Point in global pixel coordinate system.
     containPoint(point: number[]): boolean;
 
+    getAxes?: () => Axis[];
+
     getAxis?: (dim?: DimensionName) => Axis;
 
     getBaseAxis?: () => Axis;
diff --git a/src/coord/axisHelper.ts b/src/coord/axisHelper.ts
index c487d52..3c5d685 100644
--- a/src/coord/axisHelper.ts
+++ b/src/coord/axisHelper.ts
@@ -77,7 +77,7 @@
     // (4) Consider other chart types using `barGrid`?
     // See #6728, #4862, `test/bar-overflow-time-plot.html`
     const ecModel = model.ecModel;
-    if (ecModel && (scaleType === 'time' /*|| scaleType === 'interval' */)) {
+    if (ecModel && (scaleType === 'time' /* || scaleType === 'interval' */)) {
         const barSeriesModels = prepareLayoutBarSeries('bar', ecModel);
         let isBaseAxisAndHasBarSeries = false;
 
diff --git a/src/core/echarts.ts b/src/core/echarts.ts
index 500dbe9..538c819 100644
--- a/src/core/echarts.ts
+++ b/src/core/echarts.ts
@@ -34,7 +34,8 @@
     isDom,
     isArray,
     noop,
-    isString
+    isString,
+    retrieve2
 } from 'zrender/src/core/util';
 import env from 'zrender/src/core/env';
 import timsort from 'zrender/src/core/timsort';
@@ -324,6 +325,8 @@
     renderer?: RendererType,
     devicePixelRatio?: number,
     useDirtyRect?: boolean,
+    useCoarsePointer?: boolean,
+    pointerSize?: number,
     ssr?: boolean,
     width?: number,
     height?: number
@@ -409,6 +412,7 @@
         this._dom = dom;
 
         let defaultRenderer = 'canvas';
+        let defaultCoarsePointer: 'auto' | boolean = 'auto';
         let defaultUseDirtyRect = false;
         if (__DEV__) {
             const root = (
@@ -418,6 +422,8 @@
 
             defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
 
+            defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer);
+
             const devUseDirtyRect = root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__;
             defaultUseDirtyRect = devUseDirtyRect == null
                 ? defaultUseDirtyRect
@@ -430,7 +436,9 @@
             width: opts.width,
             height: opts.height,
             ssr: opts.ssr,
-            useDirtyRect: opts.useDirtyRect == null ? defaultUseDirtyRect : opts.useDirtyRect
+            useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect),
+            useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer),
+            pointerSize: opts.pointerSize
         });
         this._ssr = opts.ssr;
 
diff --git a/src/core/task.ts b/src/core/task.ts
index 08d7e23..4d55846 100644
--- a/src/core/task.ts
+++ b/src/core/task.ts
@@ -384,7 +384,7 @@
 
 
 
-///////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
 // For stream debug (Should be commented out after used!)
 // @usage: printTask(this, 'begin');
 // @usage: printTask(this, null, {someExtraProp});
diff --git a/src/export/api.ts b/src/export/api.ts
index 4534c66..6d78c5f 100644
--- a/src/export/api.ts
+++ b/src/export/api.ts
@@ -41,7 +41,7 @@
 
 export {setPlatformAPI} from 'zrender/src/core/platform';
 
-//////////////// Helper Methods /////////////////////
+// --------------------- Helper Methods ---------------------
 export {default as parseGeoJSON} from '../coord/geo/parseGeoJson';
 export {default as parseGeoJson} from '../coord/geo/parseGeoJson';
 
@@ -55,7 +55,7 @@
 
 export {default as env} from 'zrender/src/core/env';
 
-//////////////// Export for Extension Usage ////////////////
+// --------------------- Export for Exension Usage ---------------------
 // export {SeriesData};
 export {SeriesData as List};    // TODO: Compatible with exists echarts-gl code
 export {default as Model} from '../model/Model';
@@ -72,7 +72,7 @@
 export {brushSingle as innerDrawElementOnCanvas} from 'zrender/src/canvas/graphic';
 
 
-//////////////// Deprecated Extension Methods ////////////////
+// --------------------- Deprecated Extension Methods ---------------------
 
 // Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class.
 // Then use `registerComponentModel` in `install` parameter when `use` this extension. For example:
diff --git a/src/export/core.ts b/src/export/core.ts
index d17b784..9c3107e 100644
--- a/src/export/core.ts
+++ b/src/export/core.ts
@@ -34,6 +34,7 @@
 export {LinearGradientObject} from 'zrender/src/graphic/LinearGradient';
 export {RadialGradientObject} from 'zrender/src/graphic/RadialGradient';
 export {PatternObject, ImagePatternObject, SVGPatternObject} from 'zrender/src/graphic/Pattern';
+export {ElementEvent} from 'zrender/src/Element';
 
 // ComposeOption
 import type { ComponentOption, ECBasicOption as EChartsCoreOption } from '../util/types';
diff --git a/src/layout/barPolar.ts b/src/layout/barPolar.ts
index bc63fcb..48d8b4f 100644
--- a/src/layout/barPolar.ts
+++ b/src/layout/barPolar.ts
@@ -100,7 +100,7 @@
 
         const valueDim = data.mapDimension(valueAxis.dim);
         const baseDim = data.mapDimension(baseAxis.dim);
-        const stacked = isDimensionStacked(data, valueDim /*, baseDim*/);
+        const stacked = isDimensionStacked(data, valueDim /* , baseDim */);
         const clampLayout = baseAxis.dim !== 'radius'
             || !seriesModel.get('roundCap', true);
 
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 4c9b141..f4e9923 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -57,6 +57,7 @@
 import {ECSymbol} from '../util/symbol';
 import {Group} from '../util/graphic';
 import {LegendIconParams} from '../component/legend/LegendModel';
+import {dimPermutations} from '../component/marker/MarkAreaView';
 
 const inner = modelUtil.makeInner<{
     data: SeriesData
@@ -99,7 +100,10 @@
     /**
      * Get position for marker
      */
-    getMarkerPosition(value: ScaleDataValue[]): number[];
+    getMarkerPosition(
+        value: ScaleDataValue[],
+        dims?: typeof dimPermutations[number],
+        startingAtTick?:boolean): number[];
 
     /**
      * Get legend icon symbol according to each series type
diff --git a/src/util/format.ts b/src/util/format.ts
index ce85f6c..8aa0068 100644
--- a/src/util/format.ts
+++ b/src/util/format.ts
@@ -18,6 +18,7 @@
 */
 
 import * as zrUtil from 'zrender/src/core/util';
+import { encodeHTML } from 'zrender/src/core/dom';
 import { parseDate, isNumeric, numericToNumber } from './number';
 import { TooltipRenderMode, ColorString, ZRColor, DimensionType } from './types';
 import { Dictionary } from 'zrender/src/core/types';
@@ -51,24 +52,7 @@
 
 export const normalizeCssArray = zrUtil.normalizeCssArray;
 
-
-const replaceReg = /([&<>"'])/g;
-const replaceMap: Dictionary<string> = {
-    '&': '&amp;',
-    '<': '&lt;',
-    '>': '&gt;',
-    '"': '&quot;',
-    '\'': '&#39;'
-};
-
-export function encodeHTML(source: string): string {
-    return source == null
-        ? ''
-        : (source + '').replace(replaceReg, function (str, c) {
-            return replaceMap[c];
-        });
-}
-
+export { encodeHTML };
 
 /**
  * Make value user readable for tooltip and label.
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index a2e2d7c..0c09c04 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -268,16 +268,14 @@
 /**
  * Sub pixel optimize line for canvas
  */
-export function subPixelOptimizeLine(param: {
+export function subPixelOptimizeLine(
     shape: {
         x1: number, y1: number, x2: number, y2: number
     },
-    style: {
-        lineWidth: number
-    }
-}) {
-    subPixelOptimizeUtil.subPixelOptimizeLine(param.shape, param.shape, param.style);
-    return param;
+    lineWidth: number
+) {
+    subPixelOptimizeUtil.subPixelOptimizeLine(shape, shape, {lineWidth});
+    return shape;
 }
 
 /**
diff --git a/src/util/log.ts b/src/util/log.ts
index 7d8ca56..8bcc7cc 100644
--- a/src/util/log.ts
+++ b/src/util/log.ts
@@ -68,7 +68,7 @@
 /**
  * If in __DEV__ environment, get console printable message for users hint.
  * Parameters are separated by ' '.
- * @usuage
+ * @usage
  * makePrintable('This is an error on', someVar, someObj);
  *
  * @param hintInfo anything about the current execution context to hint users.
diff --git a/src/util/states.ts b/src/util/states.ts
index f3886cd..7f6e255 100644
--- a/src/util/states.ts
+++ b/src/util/states.ts
@@ -365,7 +365,8 @@
     }
     return state;
 }
-/**FI
+
+/**
  * Set hover style (namely "emphasis style") of element.
  * @param el Should not be `zrender/graphic/Group`.
  * @param focus 'self' | 'selfInSeries' | 'series'
diff --git a/src/util/types.ts b/src/util/types.ts
index 3e9eb31..36e970d 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -758,7 +758,8 @@
     type?: 'box',
     ignoreSize?: boolean | boolean[]
 };
-/******************* Mixins for Common Option Properties   ********************** */
+
+// ------------------ Mixins for Common Option Properties ------------------
 export type PaletteOptionMixin = ColorPaletteOptionMixin;
 
 export interface ColorPaletteOptionMixin {
diff --git a/test/bar-markArea.html b/test/bar-markArea.html
new file mode 100644
index 0000000..81de2f5
--- /dev/null
+++ b/test/bar-markArea.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+        <div id="main1"></div>
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                xAxis: {
+                type: 'category',
+                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+                },
+                yAxis: {
+                type: 'value'
+                },
+                series: [
+                {
+                    data: [120, 200, 150, 80, 70, 110, 130],
+                    type: 'bar',
+                    markArea: {
+                    data: [
+                        [
+                        {
+                            name: 'Invert input',
+                            xAxis: 'Thu'
+                        },
+                        {
+                            xAxis: 'Mon'
+                        }
+                        ]
+                    ]
+                    }
+                },
+                {
+                    data: [120, 200, 150, 80, 70, 110, 130],
+                    type: 'bar',
+                    markArea: {
+                    data: [
+                        [
+                        {
+                            name: 'Single Emphasis',
+                            xAxis: 'Sun'
+                        },
+                        {
+                            xAxis: 'Sun'
+                        }
+                        ]
+                    ]
+                    }
+                }
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    `MarkArea should be covering the 'Mon' to 'Thu' area and 'Sun' area`,
+                    `rather than area between bars inside. (See issue#12341)`
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+<script>
+    require([
+        'echarts',
+        // 'map/js/china',
+        // './data/nutrients.json'
+    ], function (echarts) {
+        var option;
+
+        option = {
+            xAxis: {
+            type: 'category',
+            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+            },
+            yAxis: {
+            type: 'category',
+            data: ['Sleep', 'Exercise', 'Gardening', 'Gaming', 'Work']
+            },
+            series: [
+            {
+                data: ['Work', 'Exercise', 'Work', 'Gardening', 'Gaming' ],
+                type: 'bar',
+                markArea: {
+                    data: [
+                        [
+                        {
+                            name: 'Dual Axes specified Emphasis',
+                            xAxis: 'Fri',
+                            yAxis: 'Work'
+                        },
+                        {
+                            xAxis: 'Mon',
+                            yAxis: 'Gardening'
+                        }
+                        ]
+                    ]
+                }
+            },
+            {
+                data: ['Gardening', 'Work', 'Exercise', 'Exercise', 'Gardening'],
+                type: 'bar',
+                markArea: {
+                    data: [
+                        [
+                        {
+                            name: 'Coord specified Emphasis',
+                            coord:['Mon', 'Exercise']
+                        },
+                        {
+                            coord:['Tue', 'Gardening']
+                        }
+                        ]
+                    ]
+                }
+            }
+            ]
+        };
+
+        var chart = testHelper.create(echarts, 'main1', {
+            title: [
+                `MarkArea should be covering the 'Mon' to 'Fri' area and 'Exercise' to 'Gaming' area`,
+                `rather than area between bars inside. (Dual category axes for bar chart is rare)`
+            ],
+            option: option
+            // height: 300,
+            // buttons: [{text: 'btn-txt', onclick: function () {}}],
+            // recordCanvas: true,
+        });
+    });
+    </script>
+
+
+    </body>
+</html>
+
diff --git a/test/bar-race.html b/test/bar-race.html
index 766ae13..332e4f4 100644
--- a/test/bar-race.html
+++ b/test/bar-race.html
@@ -75,6 +75,11 @@
                         formatter: function (n) {
                             return Math.round(n);
                         }
+                    },
+                    splitLine: {
+                        lineStyle: {
+                            color: 'red'
+                        }
                     }
                 },
                 dataset: {
diff --git a/test/coarse-pointer.html b/test/coarse-pointer.html
new file mode 100644
index 0000000..959d8ba
--- /dev/null
+++ b/test/coarse-pointer.html
@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+        <h3>__ECHARTS__DEFAULT__COARSE_POINTER: <span id="debug"></span></h3>
+
+        <div id="main0"></div>
+        <div id="main1"></div>
+        <div id="main2"></div>
+
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var debug = document.getElementById('debug');
+            debug.innerText = window.__ECHARTS__DEFAULT__COARSE_POINTER;
+
+            var option;
+
+            option = {
+                xAxis: {},
+                yAxis: {},
+                series: {
+                    type: 'scatter',
+                    data: [[11, 22], [33, 44]],
+                    symbol: 'pin',
+                    symbolSize: 100,
+                    emphasis: {
+                        itemStyle: {
+                            color: 'red'
+                        }
+                    }
+                },
+                tooltip: {
+                    show: true
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    'By default, pointer size feature is turned **off** for non-mobile devices.',
+                    'So in this tese case, tooltip should **not show** if mouse position is near by but not on the data point.'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                xAxis: {},
+                yAxis: {},
+                series: {
+                    type: 'scatter',
+                    data: [[11, 22], [33, 44]],
+                    symbol: 'pin',
+                    symbolSize: 100,
+                    emphasis: {
+                        itemStyle: {
+                            color: 'red'
+                        }
+                    }
+                },
+                tooltip: {
+                    show: true
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main1', {
+                title: [
+                    'If pointer size feature is turned **on** for non-mobile devices,',
+                    'like in this tese case, tooltip should **show** if mouse position is near by but not on the data point.'
+                ],
+                option: option,
+                useCoarsePointer: true
+            });
+        });
+        </script>
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                xAxis: {},
+                yAxis: {},
+                series: {
+                    type: 'scatter',
+                    data: [[11, 22], [33, 44]],
+                    symbol: 'pin',
+                    symbolSize: 100,
+                    emphasis: {
+                        itemStyle: {
+                            color: 'red'
+                        }
+                    }
+                },
+                tooltip: {
+                    show: true
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main2', {
+                title: [
+                    'In this case, the pointer size is set to be 200 so it should have a larger responsive area.'
+                ],
+                option: option,
+                useCoarsePointer: true,
+                pointerSize: 200
+            });
+        });
+        </script>
+
+
+    </body>
+</html>
diff --git a/test/graph-draggable.html b/test/graph-draggable.html
new file mode 100644
index 0000000..d681e98
--- /dev/null
+++ b/test/graph-draggable.html
@@ -0,0 +1,441 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+
+
+        <div id="main1"></div>
+
+
+        <div id="main2"></div>
+
+
+
+
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                tooltip: {},
+                series : [
+                    {
+                        type: 'graph',
+                        symbolSize: 25,
+                        roam: true,
+                        label: {
+                            normal: {
+                                show: true,
+                                formatter(p) {
+                                    return p.name.slice(-1)
+                                }
+                            }
+                        },
+                        edgeSymbol: ['circle', 'arrow'],
+                        edgeSymbolSize: [4, 10],
+                        edgeLabel: {
+                            normal: {
+                                textStyle: {
+                                    color: 'green',
+                                    fontSize: 30
+                                }
+                            },
+                            emphasis: {
+                                textStyle: {
+                                    color: '#987654'
+                                }
+                            }
+                        },
+                        data: [{
+                            name: '节点1',
+                            x: 300,
+                            y: 300,
+                            value: '🍌🎂🎉',
+                            draggable: true,
+                        }, {
+                            name: '节点2',
+                            value: 233,
+                            x: 800,
+                            y: 300
+                        }, {
+                            name: '节点3',
+                            x: 550,
+                            y: 100
+                        }, {
+                            name: '节点4',
+                            x: 550,
+                            y: 500
+                        }],
+                        lineStyle: {
+                            normal: {
+                                width: 3,
+                                color: '#184029',
+                                curveness: 0
+                            }
+                        },
+                        links: [{
+                            source: 0,
+                            target: 1,
+                            symbolSize: [5, 20],
+                            label: {
+                                normal: {
+                                    show: true
+                                    // position: 'end'
+                                }
+                            },
+                            lineStyle: {
+                                width: 5,
+                                opacity: 1,
+                                curveness: 0.2
+                            },
+                            emphasis: {
+                                lineStyle: {
+                                    color: 'blue',
+                                    width: 20,
+                                    opacity: 0.1
+                                },
+                                label: {
+                                    fontSize: 40,
+                                    color: 'red'
+                                }
+                            }
+                        }, {
+                            source: '节点2',
+                            target: '节点1',
+                            label: {
+                                normal: {
+                                    show: true
+                                }
+                            },
+                            lineStyle: {
+                                normal: {
+                                    curveness: 0.2
+                                }
+                            }
+                        }, {
+                            source: '节点1',
+                            target: '节点3',
+                            emphasis: {
+                                label: {
+                                    show: true
+                                }
+                            }
+                        }, {
+                            source: '节点2',
+                            target: '节点3'
+                        }, {
+                            source: '节点2',
+                            target: '节点4'
+                        }, {
+                            source: '节点1',
+                            target: '节点4'
+                        }]
+                    }
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    'graph draggable test case for **layout: none**',
+                    '**node 1** should be draggable'
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+
+
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                tooltip: {},
+                legend: {},
+                series: [{
+                    type: 'graph',
+                    name: 'Gene',
+                    layout: 'circular',
+                    circular: {
+                        rotateLabel: true
+                    },
+                    roam: true,
+                    focusNodeAdjacency: true,
+                    label: {
+                        show: true
+                    },
+                    lineStyle: {
+                        color: 'source',
+                        curveness: 0.3
+                    },
+                    emphasis: {
+                        label: {
+                            color: 'blue'
+                        },
+                        lineStyle: {
+                            width: 10
+                        }
+                    },
+                    data: [
+                        {
+                            itemStyle: null,
+                            name: 'DRD2',
+                            value: 40,
+                            symbolSize: 40,
+                            draggable: true,
+                            itemStyle: {
+                                color: '#91cc75'
+                            }
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'ADORA2A',
+                            value: 0,
+                            symbolSize: 20,
+                            draggable: true,
+                            itemStyle: {
+                                color: '#91cc75'
+                            }
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'ARRB2',
+                            value: 30,
+                            symbolSize: 20,
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'CALM1',
+                            value: 20,
+                            symbolSize: 40
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'CALM2',
+                            value: 0,
+                            symbolSize: 20
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'FLNA',
+                            value: 0,
+                            symbolSize: 20
+                        },
+                        {
+                            itemStyle: null,
+                            name: 'NSF',
+                            value: 0,
+                            symbolSize: 20
+                        }
+                    ],
+                    links: [
+                        {
+                            source: 'DRD2',
+                            target: 'ADORA2A'
+                        },
+                        {
+                            source: 'DRD2',
+                            target: 'ARRB2'
+                        },
+                        {
+                            source: 'DRD2',
+                            target: 'CALM1'
+                        },
+                        {
+                            source: 'DRD2',
+                            target: 'CALM2'
+                        },
+                        {
+                            source: 'DRD2',
+                            target: 'FLNA'
+                        },
+                        {
+                            source: 'DRD2',
+                            target: 'NSF'
+                        },
+                        {
+                            source: 'CALM1',
+                            target: 'ADORA2A'
+                        },
+                        {
+                            source: 'CALM1',
+                            target: 'ARRB2'
+                        },
+                        {
+                            source: 'CALM1',
+                            target: 'CALM2'
+                        },
+                        {
+                            source: 'CALM1',
+                            target: 'FLNA'
+                        },
+                        {
+                            source: 'CALM1',
+                            target: 'NSF'
+                        },
+                    ]
+                }]
+            };
+
+            var chart = testHelper.create(echarts, 'main1', {
+                title: [
+                    'graph draggable test case for **layout: circular**',
+                    '**green node** should be draggable'
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+
+
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            var option;
+
+            option = {
+                tooltip: {},
+                series: [{
+                    draggable: true,
+                    type: 'graph',
+                    layout: 'force',
+                    roam: true,
+                    symbolSize: 25,
+                    emphasis: {
+                        label: {
+                            show: false,
+                        }
+                    },
+                    force: {
+                        edgeLength: 100,
+                        repulsion: 300,
+                    },
+                    data: [
+                        {
+                            name: 'node 1',
+                            value: 10,
+                        },
+                        {
+                            name: 'node 2',
+                            value: 10,
+                        },
+                        {
+                            name: 'node 3',
+                            value: 10,
+                        },
+                        {
+                            name: 'node 4',
+                            value: 10,
+                        },
+                        {
+                            name: 'node 5',
+                            value: 10,
+                        },
+                        {
+                            name: 'node 6',
+                            value: 10,
+                        },
+                    ],
+                    links: [
+                        {
+                            source: 0,
+                            target: 1
+                        },
+                        {
+                            source: 0,
+                            target: 2
+                        },
+                        {
+                            source: 0,
+                            target: 3
+                        },
+                        {
+                            source: 0,
+                            target: 4
+                        },
+                        {
+                            source: 0,
+                            target: 5
+                        },
+                    ]
+                }]
+            };
+
+            var chart = testHelper.create(echarts, 'main2', {
+                title: [
+                    'graph draggable test case for **layout: force**',
+                    '**all node** should be draggable'
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+
+    </body>
+</html>
+
diff --git a/test/lib/caseFrame.js b/test/lib/caseFrame.js
index fb2a170..bd3e193 100644
--- a/test/lib/caseFrame.js
+++ b/test/lib/caseFrame.js
@@ -207,6 +207,17 @@
             var matchResult = (pageURL || '').match(/[?&]__RENDERER__=(canvas|svg)(&|$)/);
             return matchResult && matchResult[1] || 'canvas';
         },
+        // true, false, 'auto'
+        useCoarsePointer: function (pageURL) {
+            var matchResult = (pageURL || '').match(/[?&]__USE_COARSE_POINTER__=(true|false|auto)(&|$)/);
+            return matchResult && matchResult[1]
+                ? matchResult[1] === 'true'
+                    ? true
+                    : matchResult[1] === 'false'
+                        ? false
+                        : 'auto'
+                : 'auto';
+        },
         // true, false
         useDirtyRect: function (pageURL) {
             var matchResult = (pageURL || '').match(/[?&]__USE_DIRTY_RECT__=(true|false)(&|$)/);
diff --git a/test/lib/config.js b/test/lib/config.js
index 1c99b35..bc36037 100644
--- a/test/lib/config.js
+++ b/test/lib/config.js
@@ -30,6 +30,21 @@
     if (params.__RENDERER__) {
         window.__ECHARTS__DEFAULT__RENDERER__ = params.__RENDERER__;
     }
+    if (params.__COARSE__POINTER__) {
+        switch (params.__COARSE__POINTER__) {
+            case 'true':
+                window.__ECHARTS__COARSE__POINTER__ = true;
+                break;
+
+            case 'false':
+                window.__ECHARTS__COARSE__POINTER__ = false;
+                break;
+
+            default:
+                window.__ECHARTS__COARSE__POINTER__ = 'auto';
+                break;
+        }
+    }
     if (params.__USE_DIRTY_RECT__) {
         window.__ECHARTS__DEFAULT__USE_DIRTY_RECT__ = params.__USE_DIRTY_RECT__ === 'true';
     }
diff --git a/test/lib/testHelper.js b/test/lib/testHelper.js
index 93fb9bb..6df2c44 100644
--- a/test/lib/testHelper.js
+++ b/test/lib/testHelper.js
@@ -262,6 +262,8 @@
      * @param {boolean|number} opt If number, means height
      * @param {boolean} opt.lazyUpdate
      * @param {boolean} opt.notMerge
+     * @param {boolean} opt.useCoarsePointer
+     * @param {boolean} opt.pointerSize
      * @param {number} opt.width
      * @param {number} opt.height
      * @param {boolean} opt.draggable
@@ -284,7 +286,10 @@
                 dom.style.height = opt.height + 'px';
             }
 
-            var chart = echarts.init(dom);
+            var chart = echarts.init(dom, null, {
+                useCoarsePointer: opt.useCoarsePointer,
+                pointerSize: opt.pointerSize
+            });
 
             if (opt.draggable) {
                 if (!window.draggable) {
diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json
index 1726696..c08e7ae 100644
--- a/test/runTest/actions/__meta__.json
+++ b/test/runTest/actions/__meta__.json
@@ -50,6 +50,7 @@
   "candlestick-large2": 1,
   "candlestickConnect": 4,
   "clip": 12,
+  "coarse-pointer": 3,
   "color-mix-aqi": 2,
   "connect": 1,
   "connect-dynamic": 2,
@@ -174,6 +175,7 @@
   "symbol": 1,
   "symbol2": 1,
   "themeRiver": 1,
+  "timeline-case": 1,
   "timeScale": 1,
   "timeScale2": 1,
   "toolbox-textStyle": 1,
diff --git a/test/runTest/actions/coarse-pointer.json b/test/runTest/actions/coarse-pointer.json
new file mode 100644
index 0000000..4b7d7ed
--- /dev/null
+++ b/test/runTest/actions/coarse-pointer.json
@@ -0,0 +1 @@
+[{"name":"Action 1","ops":[{"type":"mousemove","time":427,"x":507,"y":250},{"type":"mousemove","time":627,"x":469,"y":258},{"type":"mousemove","time":830,"x":403,"y":272},{"type":"mousemove","time":1042,"x":365,"y":279},{"type":"mousemove","time":1242,"x":345,"y":306},{"type":"mousemove","time":1446,"x":338,"y":330},{"type":"mousemove","time":1626,"x":337,"y":330},{"type":"mousemove","time":1827,"x":304,"y":339},{"type":"mousemove","time":2027,"x":303,"y":338},{"type":"mousemove","time":2231,"x":298,"y":331},{"type":"mousemove","time":2447,"x":298,"y":330},{"type":"mousedown","time":2686,"x":298,"y":330},{"type":"mouseup","time":2831,"x":298,"y":330},{"time":2832,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4028,"x":298,"y":333},{"type":"mousemove","time":4230,"x":330,"y":386},{"type":"mousemove","time":4446,"x":339,"y":395},{"type":"mousemove","time":4692,"x":339,"y":395},{"type":"mousemove","time":4892,"x":344,"y":402}],"scrollY":0,"scrollX":0,"timestamp":1657770168133},{"name":"Action 2","ops":[{"type":"mousemove","time":777,"x":394,"y":369},{"type":"mousemove","time":977,"x":351,"y":337},{"type":"mousemove","time":1178,"x":322,"y":311},{"type":"mousemove","time":1378,"x":312,"y":297},{"type":"mousemove","time":1578,"x":305,"y":292},{"type":"mousemove","time":1779,"x":304,"y":291},{"type":"mousedown","time":2165,"x":304,"y":291},{"type":"mouseup","time":2308,"x":304,"y":291},{"time":2309,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":3131,"x":304,"y":292},{"type":"mousemove","time":3333,"x":335,"y":337},{"type":"mousemove","time":3545,"x":354,"y":365},{"type":"mousemove","time":3749,"x":357,"y":369}],"scrollY":512,"scrollX":0,"timestamp":1657770178748},{"name":"Action 3","ops":[{"type":"mousemove","time":351,"x":589,"y":312},{"type":"mousemove","time":551,"x":481,"y":373},{"type":"mousemove","time":755,"x":446,"y":397},{"type":"mousemove","time":967,"x":417,"y":416},{"type":"mousemove","time":1168,"x":410,"y":420},{"type":"mousemove","time":1401,"x":409,"y":420},{"type":"mousemove","time":1408,"x":408,"y":420},{"type":"mousemove","time":1608,"x":375,"y":433},{"type":"mousemove","time":1818,"x":353,"y":433},{"type":"mousemove","time":2018,"x":352,"y":433},{"type":"mousemove","time":2618,"x":352,"y":433},{"type":"mousemove","time":2823,"x":406,"y":439},{"type":"mousemove","time":3035,"x":467,"y":431},{"type":"mousemove","time":3237,"x":467,"y":431}],"scrollY":870.5,"scrollX":0,"timestamp":1657770187725}]
\ No newline at end of file
diff --git a/test/runTest/actions/timeline-case.json b/test/runTest/actions/timeline-case.json
new file mode 100644
index 0000000..9b9518d
--- /dev/null
+++ b/test/runTest/actions/timeline-case.json
@@ -0,0 +1 @@
+[{"name":"Action 1","ops":[{"type":"mousemove","time":456,"x":236,"y":511},{"type":"mousemove","time":659,"x":232,"y":484},{"type":"mousemove","time":876,"x":235,"y":465},{"type":"mousedown","time":1031,"x":236,"y":463},{"type":"mousemove","time":1088,"x":238,"y":462},{"type":"mousemove","time":1288,"x":333,"y":463},{"type":"mousemove","time":1494,"x":464,"y":457},{"type":"mousemove","time":1711,"x":464,"y":457},{"type":"mousemove","time":1955,"x":465,"y":457},{"type":"mousemove","time":2155,"x":581,"y":446},{"type":"mousemove","time":2355,"x":596,"y":446},{"type":"mousemove","time":2561,"x":600,"y":446},{"type":"mouseup","time":2731,"x":600,"y":446},{"time":2732,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":2744,"x":600,"y":446},{"type":"mousemove","time":2960,"x":598,"y":453},{"type":"mousemove","time":3122,"x":597,"y":454},{"type":"mousedown","time":3315,"x":598,"y":457},{"type":"mousemove","time":3328,"x":598,"y":457},{"type":"mousemove","time":3388,"x":597,"y":457},{"type":"mousemove","time":3588,"x":462,"y":469},{"type":"mousemove","time":3788,"x":414,"y":463},{"type":"mouseup","time":4033,"x":414,"y":463},{"time":4034,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4053,"x":414,"y":463},{"type":"mousemove","time":4255,"x":417,"y":466},{"type":"mousedown","time":4419,"x":418,"y":467},{"type":"mousemove","time":4461,"x":418,"y":467},{"type":"mousemove","time":4472,"x":416,"y":468},{"type":"mousemove","time":4680,"x":272,"y":472},{"type":"mousemove","time":4894,"x":232,"y":468},{"type":"mouseup","time":4979,"x":232,"y":468},{"time":4980,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":5196,"x":232,"y":468},{"type":"mousemove","time":5238,"x":231,"y":468},{"type":"mousedown","time":5363,"x":232,"y":464},{"type":"mousemove","time":5438,"x":242,"y":464},{"type":"mousemove","time":5638,"x":390,"y":481},{"type":"mousemove","time":5846,"x":420,"y":484},{"type":"mouseup","time":5851,"x":420,"y":484},{"time":5852,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":6054,"x":418,"y":513},{"type":"mousemove","time":6255,"x":408,"y":531},{"type":"mousemove","time":6588,"x":406,"y":532},{"type":"mousemove","time":6794,"x":405,"y":532},{"type":"mousemove","time":7044,"x":397,"y":532},{"type":"mousemove","time":7171,"x":396,"y":533},{"type":"mousemove","time":7377,"x":382,"y":535},{"type":"mousemove","time":8588,"x":380,"y":534}],"scrollY":0,"scrollX":0,"timestamp":1663128694475}]
\ No newline at end of file
diff --git a/test/runTest/cli.js b/test/runTest/cli.js
index 582fa99..7b7755f 100644
--- a/test/runTest/cli.js
+++ b/test/runTest/cli.js
@@ -41,6 +41,7 @@
     .option('--expected <expected>', 'Expected version')
     .option('--actual <actual>', 'Actual version')
     .option('--renderer <renderer>', 'svg/canvas renderer')
+    .option('--use-coarse-pointer <useCoarsePointer>', '"auto" (by default) or "true" or "false"')
     .option('--threads <threads>', 'How many threads to run concurrently')
     .option('--no-save', 'Don\'t save result')
     .option('--dir <dir>', 'Out dir');
@@ -51,6 +52,7 @@
 program.actual = program.actual || 'local';
 program.threads = +program.threads || 1;
 program.renderer = (program.renderer || 'canvas').toLowerCase();
+program.useCoarsePointer = (program.useCoarsePointer || 'auto').toLowerCase();
 program.dir = program.dir || (__dirname + '/tmp');
 
 if (!program.tests) {
@@ -265,7 +267,7 @@
             width: 800,
             height: 600
         });
-        await page.goto(`${origin}/test/${fileUrl}?__RENDERER__=${program.renderer}`, {
+        await page.goto(`${origin}/test/${fileUrl}?__RENDERER__=${program.renderer}&__COARSE__POINTER__=${program.useCoarsePointer}`, {
             waitUntil: 'networkidle2',
             timeout: 10000
         });
@@ -384,6 +386,7 @@
         testOpt.actualVersion = actualVersion;
         testOpt.expectedVersion = expectedVersion;
         testOpt.useSVG = program.renderer === 'svg';
+        testOpt.useCoarsePointer = program.useCoarsePointer;
         testOpt.lastRun = Date.now();
     }
     else {
@@ -407,7 +410,7 @@
     });
 
     async function eachTask(testOpt) {
-        console.log(`Running test: ${testOpt.name}, renderer: ${program.renderer}`);
+        console.log(`Running test: ${testOpt.name}, renderer: ${program.renderer}, useCoarsePointer: ${program.useCoarsePointer}`);
         try {
             await runTest(browser, testOpt, runtimeCode, program.expected, program.actual);
         }
diff --git a/test/runTest/client/client.css b/test/runTest/client/client.css
index dcb6956..1cce880 100644
--- a/test/runTest/client/client.css
+++ b/test/runTest/client/client.css
@@ -71,7 +71,6 @@
 }
 
 .nav-toolbar, .test-run-controls {
-    padding: 10px 10px;
     background: #fff;
     position: fixed;
     width: 330px;
@@ -84,17 +83,14 @@
     z-index: 1;
     position: sticky;
     width: 100%;
-    padding: 5px 40px;
     top: 0px;
-
     background: #896bda;
     box-shadow: 0 0 20px rgb(0 0 0 / 20%);
     border-bottom: none;
 }
 
-.test-run-controls>* {
-    display: inline-block;
-    vertical-align: middle;
+.test-run-row {
+    padding: 5px 20px;
 }
 
 .nav-toolbar .el-button {
@@ -106,6 +102,8 @@
     margin: 0 5px;
     color: #fff;
     font-size: 12px;
+    display: inline-block;
+    vertical-align: middle;
 }
 .run-config-item>* {
     display: inline-block;
diff --git a/test/runTest/client/client.js b/test/runTest/client/client.js
index f110fbd..0c34e0f 100644
--- a/test/runTest/client/client.js
+++ b/test/runTest/client/client.js
@@ -137,6 +137,7 @@
             expectedVersion: null,
 
             renderer: 'canvas',
+            useCoarsePointer: 'auto',
             threads: 4
         }, urlRunConfig)
     },
@@ -344,6 +345,9 @@
             if (test.useSVG) {
                 searches.push('__RENDERER__=svg');
             }
+            if (test.useCoarsePointer) {
+                searches.push('__COARSE__POINTER__=true');
+            }
             let src = test.fileUrl;
             if (searches.length) {
                 src = src + '?' + searches.join('&');
@@ -366,6 +370,7 @@
             this.runConfig.isExpectedNightly = runResult.expectedVersion.includes('-dev.');
             this.runConfig.isActualNightly = runResult.actualVersion.includes('-dev.');
             this.runConfig.renderer = runResult.renderer;
+            this.runConfig.useCoarsePointer = runResult.useCoarsePointer;
 
             this.showRunsDialog = false;
         },
@@ -418,6 +423,7 @@
         actualVersion: app.runConfig.actualVersion,
         threads: app.runConfig.threads,
         renderer: app.runConfig.renderer,
+        useCoarsePointer: app.runConfig.useCoarsePointer,
         noHeadless,
         replaySpeed: noHeadless ? 5 : 5
     });
diff --git a/test/runTest/client/index.html b/test/runTest/client/index.html
index 9d52c1a..e8978f8 100644
--- a/test/runTest/client/index.html
+++ b/test/runTest/client/index.html
@@ -101,83 +101,94 @@
             </el-aside>
             <el-main>
                 <div class="test-run-controls">
-                    <div class="run-config-item">
-                        <el-tooltip content="Show All Tests Runs">
-                            <div style="cursor: pointer;"  @click="showAllTestsRuns">
-                                <i style="font-size:20px;vertical-align:middle;display:inline-block;" class="el-icon-files"></i>
-                                <span style="vertical-align:middle;display:inline-block;">ALL RUNS</span>
-                            </div>
-                        </el-tooltip>
-                    </div>
-
-                    <div class="run-config-item">
-                        <el-dropdown v-if="!running" split-button size="mini" title="Run"
-                            @click="run('selected')"
-                            @command="run"
-                        >
-                            <i class="el-icon-caret-right"></i> RUN ({{selectedTests.length}})
-                            <el-dropdown-menu slot="dropdown" >
-                                <el-dropdown-item command="unfinished">Run unfinished ({{unfinishedTests.length}})</el-dropdown-item>
-                                <el-dropdown-item command="failed">Run failed ({{failedTests.length}})</el-dropdown-item>
-                                <el-dropdown-item command="all">Run all ({{fullTests.length}})</el-dropdown-item>
-                            </el-dropdown-menu>
-                        </el-dropdown>
-
-                        <el-button-group v-else>
-                            <el-button size="mini" :loading="true">Stop</el-button>
-                            <el-button title="Run" @click="stopTests" size="mini" icon="el-icon-close" style="padding-left: 3px;padding-right:3px;"></el-button>
-                        </el-button-group>
-
-                        <el-tooltip :content="'Finished ' + finishedPercentage + '%'">
-                            <el-progress
-                                type="circle"
-                                :percentage="finishedPercentage"
-                                :width="20"
-                                :stroke-width="4"
-                                :show-text="false"
-                            ></el-progress>
-                        </el-tooltip>
-                    </div>
-
-                    <div class="run-config-item">
-                        <span class="label">
-                            Expected
-                            <el-tooltip content="Use Nightly Build">
-                                <el-checkbox :disabled="running" v-model="runConfig.isExpectedNightly" size="mini"></el-checkbox>
+                    <div class="test-run-row">
+                        <div class="run-config-item">
+                            <el-tooltip content="Show Result of All Test Runnings">
+                                <div style="cursor: pointer;"  @click="showAllTestsRuns">
+                                    <i style="font-size:20px;vertical-align:middle;display:inline-block;" class="el-icon-files"></i>
+                                    <span style="vertical-align:middle;display:inline-block;">LIST OF RUNNING RESULTS</span>
+                                </div>
                             </el-tooltip>
-                        </span>
-                        <el-select :disabled="running" size="mini" v-model="runConfig.expectedVersion" placeholder="Select Version"
-                            :style="`width: ${runConfig.isExpectedNightly ? 160 : 80}px;`"
-                        >
-                            <el-option v-for="version in expectedVersionsList" :key="version" :label="version" :value="version"></el-option>
-                        </el-select>
-                        <!-- <i class="el-icon-link"></i> -->
-                        <span class="label">
-                            Actual
-                            <el-tooltip content="Use Nightly Build">
-                                <el-checkbox :disabled="running" v-model="runConfig.isActualNightly" size="mini"></el-checkbox>
-                            </el-tooltip>
-                        </span>
-                        <el-select :disabled="running" size="mini" v-model="runConfig.actualVersion" placeholder="Select Version"
-                            :style="`width: ${runConfig.isActualNightly ? 160 : 80}px;`"
-                        >
-                            <el-option v-for="version in actualVersionsList" :key="version" :label="version" :value="version"></el-option>
-                        </el-select>
-                    </div>
-                    <div class="run-config-item">
-                        <span class="label">Renderer</span>
-                        <el-select :disabled="running" size="mini" style="width: 100px;" v-model="runConfig.renderer" placeholder="Select Renderer">
-                            <el-option key="canvas" label="canvas" value="canvas"></el-option>
-                            <el-option key="svg" label="svg" value="svg"></el-option>
-                        </el-select>
-                    </div>
-                    <div class="run-config-item">
-                        <span class="label">Threads</span>
+                        </div>
 
-                        <el-select :disabled="running" size="mini" v-model="runConfig.threads" style="width: 58px">
-                            <el-option v-for="t in [1, 2, 4, 6, 8]" :key="t" :label="t" :value="t"></el-option>
-                        </el-select>
-                        <!-- <el-slider style="width: 100px;" v-model="runConfig.threads" :step="1" :min="1" :max="8" show-stops></el-slider> -->
+                        <div class="run-config-item">
+                            <el-dropdown v-if="!running" split-button size="mini" title="Run"
+                                @click="run('selected')"
+                                @command="run"
+                            >
+                                <i class="el-icon-caret-right"></i> RUN ({{selectedTests.length}})
+                                <el-dropdown-menu slot="dropdown" >
+                                    <el-dropdown-item command="unfinished">Run unfinished ({{unfinishedTests.length}})</el-dropdown-item>
+                                    <el-dropdown-item command="failed">Run failed ({{failedTests.length}})</el-dropdown-item>
+                                    <el-dropdown-item command="all">Run all ({{fullTests.length}})</el-dropdown-item>
+                                </el-dropdown-menu>
+                            </el-dropdown>
+
+                            <el-button-group v-else>
+                                <el-button size="mini" :loading="true">Stop</el-button>
+                                <el-button title="Run" @click="stopTests" size="mini" icon="el-icon-close" style="padding-left: 3px;padding-right:3px;"></el-button>
+                            </el-button-group>
+
+                            <el-tooltip :content="'Finished ' + finishedPercentage + '%'">
+                                <el-progress
+                                    type="circle"
+                                    :percentage="finishedPercentage"
+                                    :width="20"
+                                    :stroke-width="4"
+                                    :show-text="false"
+                                ></el-progress>
+                            </el-tooltip>
+                        </div>
+                    </div>
+                    <div class="test-run-row">
+                        <div class="run-config-item">
+                            <span class="label">
+                                Expected
+                                <el-tooltip content="Use Nightly Build">
+                                    <el-checkbox :disabled="running" v-model="runConfig.isExpectedNightly" size="mini"></el-checkbox>
+                                </el-tooltip>
+                            </span>
+                            <el-select :disabled="running" size="mini" v-model="runConfig.expectedVersion" placeholder="Select Version"
+                                :style="`width: ${runConfig.isExpectedNightly ? 160 : 80}px;`"
+                            >
+                                <el-option v-for="version in expectedVersionsList" :key="version" :label="version" :value="version"></el-option>
+                            </el-select>
+                            <!-- <i class="el-icon-link"></i> -->
+                            <span class="label">
+                                Actual
+                                <el-tooltip content="Use Nightly Build">
+                                    <el-checkbox :disabled="running" v-model="runConfig.isActualNightly" size="mini"></el-checkbox>
+                                </el-tooltip>
+                            </span>
+                            <el-select :disabled="running" size="mini" v-model="runConfig.actualVersion" placeholder="Select Version"
+                                :style="`width: ${runConfig.isActualNightly ? 160 : 80}px;`"
+                            >
+                                <el-option v-for="version in actualVersionsList" :key="version" :label="version" :value="version"></el-option>
+                            </el-select>
+                        </div>
+                        <div class="run-config-item">
+                            <span class="label">Renderer</span>
+                            <el-select :disabled="running" size="mini" style="width: 100px;" v-model="runConfig.renderer" placeholder="Select Renderer">
+                                <el-option key="canvas" label="canvas" value="canvas"></el-option>
+                                <el-option key="svg" label="svg" value="svg"></el-option>
+                            </el-select>
+                        </div>
+                        <div class="run-config-item">
+                            <span class="label">Coarse Pointer</span>
+                            <el-select :disabled="running" size="mini" style="width: 100px;" v-model="runConfig.useCoarsePointer" placeholder="auto">
+                                <el-option key="auto" label="auto" value="auto"></el-option>
+                                <el-option key="true" label="true" value="true"></el-option>
+                                <el-option key="false" label="false" value="false"></el-option>
+                            </el-select>
+                        </div>
+                        <div class="run-config-item">
+                            <span class="label">Threads</span>
+
+                            <el-select :disabled="running" size="mini" v-model="runConfig.threads" style="width: 58px">
+                                <el-option v-for="t in [1, 2, 4, 6, 8]" :key="t" :label="t" :value="t"></el-option>
+                            </el-select>
+                            <!-- <el-slider style="width: 100px;" v-model="runConfig.threads" :step="1" :min="1" :max="8" show-stops></el-slider> -->
+                        </div>
                     </div>
                 </div>
 
diff --git a/test/runTest/server.js b/test/runTest/server.js
index f74b001..f7b598f 100644
--- a/test/runTest/server.js
+++ b/test/runTest/server.js
@@ -131,6 +131,7 @@
     actualVersion,
     expectedVersion,
     renderer,
+    useCoarsePointer,
     noSave
 }) {
     console.log('Received: ', testsNameList.join(','));
@@ -190,6 +191,7 @@
                 '--actual', actualVersion,
                 '--expected', expectedVersion,
                 '--renderer', renderer || '',
+                '--use-coarse-pointer', useCoarsePointer,
                 '--threads', Math.min(threadsCount, CLI_FIXED_THREADS_COUNT),
                 '--dir', getResultBaseDir(),
                 ...(noHeadless ? ['--no-headless'] : []),
@@ -339,6 +341,7 @@
                         actualVersion: data.actualVersion,
                         expectedVersion: data.expectedVersion,
                         renderer: data.renderer,
+                        useCoarsePointer: data.useCoarsePointer,
                         noSave: false
                     }
                 );
@@ -399,6 +402,7 @@
                     actualVersion: data.actualVersion,
                     expectedVersion: data.expectedVersion,
                     renderer: data.renderer || '',
+                    useCoarsePointer: data.useCoarsePointer,
                     noSave: true
                 });
             }
diff --git a/test/runTest/store.js b/test/runTest/store.js
index 5eb3e1d..3430bd4 100644
--- a/test/runTest/store.js
+++ b/test/runTest/store.js
@@ -80,7 +80,8 @@
     return [
         params.expectedVersion,
         params.actualVersion,
-        params.renderer
+        params.renderer,
+        params.useCoarsePointer
     ].join(TEST_HASH_SPLITTER);
 }
 
@@ -92,7 +93,8 @@
     return {
         expectedVersion: parts[0],
         actualVersion: parts[1],
-        renderer: parts[2]
+        renderer: parts[2],
+        useCoarsePointer: parts[3]
     };
 }
 
@@ -111,7 +113,8 @@
     console.log('Store ', _runHash);
     return storeParams.expectedVersion === runParams.expectedVersion
         && storeParams.actualVersion === runParams.actualVersion
-        && storeParams.renderer === runParams.renderer;
+        && storeParams.renderer === runParams.renderer
+        && storeParams.useCoarsePointer === runParams.useCoarsePointer;
 }
 
 function getResultFilePath() {
diff --git a/test/timeline-case.html b/test/timeline-case.html
new file mode 100644
index 0000000..d6ba3cf
--- /dev/null
+++ b/test/timeline-case.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+
+
+
+
+
+
+
+
+        <script>
+        require(['echarts'], function (echarts) {
+            var option = {
+                timeline: {
+                    data: ['9月1日', '9月2日', '9月3日'],
+                    axisType: 'category',
+                    show: true,
+                    autoPlay: false,
+                    playInterval: 1000,
+                    lineStyle: {
+                        show: false
+                    }
+                },
+                options: [{
+                    tooltip: {
+                        trigger: 'axis'
+                    },
+                    calculable: true,
+                    xAxis: {
+                        type: 'category',
+                        axisLabel: {
+                            interval: 0
+                        },
+                        data: ['1', ' 2', '3', '4', '5', '6', '7', '8']
+                    },
+                    yAxis: [
+                        {},
+                        {
+                            type: 'value'
+                        }
+                    ],
+                    series: [{
+                        yAxisIndex: 1,
+                        type: 'bar',
+                        data: [5, 6, 8, 28, 8, 24, 11, 16]
+                    }]
+                }, {
+                    title: {
+                        text: '9月2日'
+                    },
+                    series: [{
+                        data: [45, 43, 64, 134, 188, 43, 109, 12]
+                    }]
+                },
+                {
+                    title: {
+                        text: '9月3日'
+                    },
+                    series: [{
+                        data: [110, 32, 111, 176, 73, 59, 181, 9]
+                    }]
+                }]
+            };
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    'Drag the timeline',
+                    'The chart should be rendered correctly without any error message in the console',
+                    'Case from https://github.com/apache/echarts/issues/17643'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+
+    </body>
+</html>
+
diff --git a/theme/macarons.js b/theme/macarons.js
index c771d5e..27c9f9a 100644
--- a/theme/macarons.js
+++ b/theme/macarons.js
@@ -87,7 +87,11 @@
         },
 
         tooltip: {
+            borderWidth: 0,
             backgroundColor: 'rgba(50,50,50,0.5)',
+            textStyle: {
+                color: '#FFF'
+            },
             axisPointer: {
                 type: 'line',
                 lineStyle: {